使用GridView的SearchView小部件。我键入搜索字段,但它不刷新GridView

时间:2017-06-12 16:25:21

标签: java android gridview widget searchview

我是编码的新手。我正在尝试实现一个应该更新GridView的SearchView Widget,但它不起作用。当我在搜索字段中输入内容时,没有任何反应。如果我也不点按搜索按钮,则没有任何反应。你能帮我吗?

这是MainActivity:

public class MainActivity extends AppCompatActivity  {

    private static Context mainContext;

    private FragmentDataSaver mDataSaver;
    private static final String DATA_SAVER_TAG = "DATA_SAVER";

    private View mDecorView;

    public ArrayList<Movies> mMovies;

    WallAdapter wallAdapter;

    GridView gridView;

    public static Context getContext(){
        return mainContext;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);


        mDecorView = getWindow().getDecorView();

        mainContext = getApplicationContext();

        setContentView(R.layout.activity_main);

        Toolbar myToolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(myToolbar);
        getSupportActionBar().setDisplayShowTitleEnabled(false);

        FragmentManager fm = getSupportFragmentManager();
        mDataSaver = (FragmentDataSaver)fm.findFragmentByTag(DATA_SAVER_TAG);

        if(mDataSaver == null){
            mDataSaver = new FragmentDataSaver();
            fm.beginTransaction().add(mDataSaver, DATA_SAVER_TAG).commit();

            mMovies = DatabaseProva.creaDatabaseProva();
            mDataSaver.setData(mMovies);
        } else {
            mMovies = mDataSaver.getData();
        }

        gridView = (GridView)findViewById(R.id.gridview_layout);

        /*if(savedInstanceState == null){
            mMovies = DatabaseProva.creaDatabaseProva();
        } else {
            mMovies = savedInstanceState.getParcelableArrayList("tempMovies");
        }*/

        wallAdapter = new WallAdapter(this, mMovies);
        gridView.setAdapter(wallAdapter);

        handleIntent(getIntent());

    }

    @Override
    protected void onNewIntent(Intent intent) {
        handleIntent(intent);
    }

    private void handleIntent(Intent intent) {

        if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
            String query = intent.getStringExtra(SearchManager.QUERY);
            //use the query to search your data somehow
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.toolbar_menu, menu);
        MenuItem searchMenu = menu.findItem(R.id.search_view);

        // Get the SearchView and set the searchable configuration
        SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);

        android.widget.SearchView searchView = (android.widget.SearchView) searchMenu.getActionView();
        searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
        searchView.setIconifiedByDefault(false); // Do not iconify the widget; expand it by default
        searchView.setOnQueryTextListener(new android.widget.SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextSubmit(String query) {
                return false;
            }

            @Override
            public boolean onQueryTextChange(String newText) {
                wallAdapter.getFilter().filter(newText);

                return false;
            }
        });

        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);

        if(hasFocus){
            mDecorView.setSystemUiVisibility(
                    View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                            | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                            | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                            | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                            | View.SYSTEM_UI_FLAG_FULLSCREEN
                            | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
        }
    }

    /*@Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putParcelableArrayList("tempMovies", wallAdapter.getItems());
    }*/

适配器(WallAdapter):

public class WallAdapter extends ArrayAdapter<Movies> implements Filterable{

    private ArrayList<Movies> tempMovies = new ArrayList<Movies>();


    public WallAdapter(Context context, ArrayList movies) {
        super(context, 0, movies);
        setItems(movies);
    }

    public ArrayList<Movies> getMovies() {
        return tempMovies;
    }

    public void setItems(ArrayList<Movies> movies) {
        this.tempMovies = movies;
    }

    public ArrayList<Movies> getItems() {
        return tempMovies;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        ViewHolder holder;

        if(convertView == null){
            convertView = LayoutInflater.from(getContext()).inflate(R.layout.item_layout, parent, false);
            holder = new ViewHolder();
            holder.mImage = (ImageView) convertView.findViewById(R.id.item_view);
            holder.mImage.setScaleType(ImageView.ScaleType.CENTER_CROP);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }

        final Movies currentMovie = getItem(position);

        holder.mImage.setImageBitmap(currentMovie.getImage());

        convertView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(getContext(), SchedaFilm.class);
                intent.putExtra("titolo", currentMovie.getTitolo());
                intent.putExtra("locandina", currentMovie.getIdLocandina());
                intent.putExtra("trama", currentMovie.getTrama());
                intent.putExtra("regia", currentMovie.getRegia());
                intent.putExtra("anno", currentMovie.getAnno());
                intent.putExtra("genere", currentMovie.getGenere());
                getContext().startActivity(intent);
            }
        });

        return convertView;
    }

    Filter filter = new Filter() {
        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            FilterResults filterResults = new FilterResults();
            ArrayList<Movies> tempList = new ArrayList<>();
            //constraint is the result from text you want to filter against.
            //objects is your data set you will filter from
            if(constraint != null || constraint.length() == 0) {
                // No filter implemented we return all the list
                filterResults.values = tempMovies;
                filterResults.count = tempMovies.size();
            } else {
                for(Movies m : tempMovies){
                    if(m.toString().toLowerCase().contains(constraint.toString().toLowerCase())){
                        tempList.add(m);
                    }
                }

                filterResults.values = tempList;
                filterResults.count = tempList.size();
            }


            return filterResults;
        }

        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {
            if(results.count == 0){
                notifyDataSetInvalidated();
            } else {
                tempMovies = (ArrayList<Movies>) results.values;
                notifyDataSetChanged();
            }
        }
    };

    @NonNull
    @Override
    public Filter getFilter() {
        return filter;
    }

    static class ViewHolder{

        private ImageView mImage;

        public Context getContext(){
            return mImage.getContext();
        }
    }

我的清单:

<?xml version="1.0" encoding="utf-8"?>
<manifest package="arca.mitty.com.arcagridview"
          xmlns:android="http://schemas.android.com/apk/res/android">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.AppCompat.Light.NoActionBar">
        <activity android:name=".MainActivity"
                  android:launchMode="singleTop">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <action android:name="android.intent.action.SEARCH" />
                <meta-data android:name="android.app.searchable"
                           android:resource="@xml/searchable"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
        <activity android:name=".SchedaFilm"
            android:parentActivityName=".MainActivity">
        </activity>
    </application>

</manifest>

可搜索的xml文件:

<?xml version="1.0" encoding="utf-8"?>
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
        android:label="@string/app_label"
        android:hint="@string/search_hint" >
</searchable>  

这是电影课:

public class Movies implements Parcelable{

    private String mTitolo;
    private String mGenere;
    private Bitmap mLocandina;
    private Bitmap mLocandinaBig;
    private int mAnno;
    private int mIdLocandina;

    private String mTrama = "Seduto sulla panchina ad un bus-stop di Savannah, " +
            "Forrest Gump ricorda la sua infanzia di bimbo con problemi mentali e fisici. " +
            "Solo la mamma lo accetta per quello che è, e solo la piccola Jenny Curran lo fa sedere accanto a sé sull'autobus della scuola. " +
            "Sarà lei a incitarlo, per fuggire a tre compagnetti violenti, a correre, liberando così le gambe dalla protesi. " +
            "Attraverso trent'anni di storia americana vista con gli occhi della semplicità e dell'innocenza, Forrest diventa un campione universitario di football, " +
            "mentre è sempre più innamorato di Jenny che però lo considera un fratello. Assiste ai disordini razziali in Alabama ed incontra Kennedy poco prima dell'assassinio. " +
            "Si arruola quindi nell'esercito, dove fa amicizia con il nero Bubba, un pescatore di gamberi che gli comunica la sua passione. " +
            "Dopo un fugace incontro con Jenny che canta a Memphis, Gump va a combattere in Vietnam.";

    private String mRegia = "Bino Cicogna";

    //Constructor
    public Movies (String titolo, String genere, int locandina, int anno){

        mTitolo = titolo;
        mGenere = genere;
        mIdLocandina = locandina;
        mLocandina = decodeSampledBitmapFromResource(MainActivity.getContext().getResources(), locandina, 90, 135);
        mAnno = anno;
    }


    protected Movies(Parcel in) {
        mTitolo = in.readString();
        mGenere = in.readString();
        mLocandina = in.readParcelable(Bitmap.class.getClassLoader());
        mAnno = in.readInt();
    }

    public static final Creator<Movies> CREATOR = new Creator<Movies>() {
        @Override
        public Movies createFromParcel(Parcel in) {
            return new Movies(in);
        }

        @Override
        public Movies[] newArray(int size) {
            return new Movies[size];
        }
    };

    public String getTitolo() {
        return mTitolo;
    }

    public String getGenere() {
        return mGenere;
    }

    public int getIdLocandina(){
        return mIdLocandina;
    }

    public Bitmap getImage() {
        return mLocandina;
    }

    public int getAnno() {
        return mAnno;
    }

    public String getTrama(){
        return mTrama;
    }

    public String getRegia(){
        return mRegia;
    }

    public String toString(){
        String s = "";
        s = getTitolo() + " " + getGenere() + " " + getRegia() + " " + getAnno();
        return s;
    }

    public static int calculateInSampleSize(
            BitmapFactory.Options options, int reqWidth, int reqHeight) {
        // Raw height and width of image
        final int height = options.outHeight;
        final int width = options.outWidth;
        int inSampleSize = 1;

        if (height > reqHeight || width > reqWidth) {

            final int halfHeight = height / 2;
            final int halfWidth = width / 2;

            // Calculate the largest inSampleSize value that is a power of 2 and keeps both
            // height and width larger than the requested height and width.
            while ((halfHeight / inSampleSize) >= reqHeight
                    && (halfWidth / inSampleSize) >= reqWidth) {
                inSampleSize *= 2;
            }
        }

        return inSampleSize;
    }


    public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
                                                         int reqWidth, int reqHeight) {

        // First decode with inJustDecodeBounds=true to check dimensions
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeResource(res, resId, options);

        // Calculate inSampleSize
        options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

        // Decode bitmap with inSampleSize set
        options.inJustDecodeBounds = false;
        return BitmapFactory.decodeResource(res, resId, options);
    }


    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(mTitolo);
        dest.writeString(mGenere);
        dest.writeParcelable(mLocandina, flags);
        dest.writeInt(mAnno);
    }
}

2 个答案:

答案 0 :(得分:0)

In your filter, you are doing this:

if (m.toString().toLowerCase().contains(constraint.toString().toLowerCase())) {
   tempList.add(m);
}

Make sure m.toString() returns value that actually contains movie's name, if it doesn't that condition will always be false and tempList empty, and next code will be executed:

if (results.count == 0) {
    notifyDataSetInvalidated();
}

答案 1 :(得分:0)

好的,经过多次尝试,我找到了解决方案。

显然,有一个逻辑错误:&#34;过滤器&#34;我正在更新错误的电影ArrayList。适配器用于在我的应用程序中构建GridView的那个是&#34; tempMovies&#34;数组列表。 在&#34;过滤器&#34;我正在使用&#34; tempList&#34;然后更新&#34; filterResults&#34;,但永远不会更新&#34; tempMovies&#34;。即使在&#34; getFilter&#34;方法

此外,我发现更容易理解并应用&#34;过滤&#34;方法。我使用它并且效果很好。

您在这里是代码:

public void filter(CharSequence text){
    String query = text.toString().toLowerCase();
    tempMovies.clear();
    if(text.length() == 0){
        tempMovies.addAll(originalMoviesList);
    } else{
        for(Movies m : originalMoviesList){
            if(m.toString().toLowerCase().contains(query)){
                tempMovies.add(m);
            }
        }
    }
    notifyDataSetChanged();
}

我在这个网站找到了它: http://www.androidbegin.com/tutorial/android-search-listview-using-filter/

最后,再次感谢所有试图提供帮助的人。我希望我的经验对其他人有用。