带有 GridView 的搜索视图小部件。我在搜索字段中输入,但它不会刷新 GridView



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

这是主要活动:

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());
    }*/
适配器

(墙上适配器(:

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);
    }
}

在过滤器中,您正在执行以下操作:

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

确保返回m.toString()实际包含电影名称的值,如果没有,该条件将始终falsetempList为空,并将执行下一个代码:

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

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

显然,存在逻辑错误:在"过滤器"中,我更新了错误的电影 ArrayList。适配器用于在我的应用程序中构建 GridView 的适配器是"tempMovies"ArrayList。在"过滤器"中,我使用"tempList",然后更新"filterResults",但从未更新"tempMovies"。即使在"getFilter"方法中。

此外,我发现了一种更容易理解和应用的"过滤器"方法。我正在使用它,它工作得很好。

这是代码:

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/

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

相关内容

  • 没有找到相关文章

最新更新