RecyclerView:筛选列表中的错误位置 [英] RecyclerView: wrong position in filtered List

查看:114
本文介绍了RecyclerView:筛选列表中的错误位置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个CardView项目的RecyclerView列表.然后,我使用带有SearchView小部件的简单过滤器方法来过滤列表.然后,当我单击已过滤的CardView来启动CardViewDetails活动时,UI将显示原始列表中的CardView,而不是已过滤列表中的CardView.例如,我在原始列表中有二十个项目的列表.当我输入搜索约束时,过滤后的列表会在RecyclerView中正确显示三个CardView.当我单击列表中的第三个CardView时,UI从原始列表中返回第三个CardView,而不是从过滤后的列表中返回第三个CardView.我在这里想念什么?

I have a RecyclerView list of CardView items. I then use a simple filter method with a SearchView widget to filter the list. When I then click on a filtered CardView to launch a CardViewDetails Activity, the UI is showing the CardView from the original List and not the filtered List. For example, I have a list of twenty items in the original List. When I enter a search constraint the filtered List correctly shows three CardViews in the RecyclerView. When I click on the third CardView in the List, the UI returns the third CardView from the original List and not the third CardView from the filtered List. What am I missing here?

Adapter:

public class MyRecylerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

private List<ListItem> mListItems, filteredList;
Context mContext;
private RecyclerItemClickListener recyclerItemClickListener;
private RecyclerView mRecyclerView;
/**********************************************************/
private String searchString = "";
/**********************************************************/

public MyRecylerAdapter(Context context, List<ListItem> listItems) {
    this.mContext = context;
    this.mListItems = listItems;
    this.filteredList = new ArrayList<>();
    this.filteredList.addAll(this.mListItems);
}

// RecyclerItemClickListener is the public interface file used to reach the MainActivity
public void setOnItemClickListener(RecyclerItemClickListener recyclerItemClickListener) {
    this.recyclerItemClickListener = recyclerItemClickListener;
}

// Get the Item's position.
public ListItem getItem(int position) {
    return filteredList.get(position);
}

@Override
public int getItemCount() {
    if (filteredList.size() >0) {
        return filteredList.size();
    }
    else {
        return mListItems.size();
    }
}

public void setFilter(List<ListItem> listItems, String searchString) {
    // Note: the String is to get s.toString() from the Main Activity SearchView.
    filteredList = new ArrayList<>();
    filteredList.addAll(listItems);
    this.searchString = searchString;
    notifyDataSetChanged();
}

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

    View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_contact_item, parent, false);
    final ItemHolder itemHolder = new ItemHolder(view);

        // Attach a Click listener to the items's (row) view.
        // itemView is from the ItemHolder() below.
        // onItemClick is the click method in MainActivity.
        itemHolder.itemView.setOnClickListener(new View.OnClickListener() {                
            @Override
            public void onClick(View view) {

                int adapterPos = itemHolder.getAdapterPosition(); // get the item position.                    
                if (adapterPos != RecyclerView.NO_POSITION) {
                    if (recyclerItemClickListener != null) {
                        // pass the item to the Main Activity
                        // through the RecyclerItemClickListener file and its
                        // public interface.
                        recyclerItemClickListener.onItemClick(itemHolder.itemView,adapterPos);
                    }
                }
            }
        });            
    return itemHolder;
}

private static class ItemHolder extends RecyclerView.ViewHolder {

    private TextView cardBlankText2; 

    private ItemHolder(View itemView) {
        super(itemView);

        cardBlankText2 = (TextView) itemView.findViewById(R.id.cardBlankText2);            
}

public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) {

    final ListItem listItem = filteredList.get(position);
    final ItemHolder itemHolder = (ItemHolder) holder;

    itemHolder.cardBlankText2.setText(listItem.getTodo());
}

Activity:

public class MainActivity extends AppCompatActivity implements
    RecyclerItemClickListener {

private List<ListItem> allList = new ArrayList<>();
private RecyclerView mRecyclerView;
private SQLiteDB sqLiteDB;
private MyRecylerAdapter adapter;    
private CardView cardview;

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    sqLiteDB = SQLiteDB.getInstance(this);        
    mRecyclerView = (RecyclerView)findViewById(R.id.list_recyclerview);        
    final LinearLayoutManager layoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);        
    mRecyclerView.setLayoutManager(layoutManager);
    allList = sqLiteDB.getAllDBItems();

    adapter = new MyRecylerAdapter(this, allList);
    adapter.setOnItemClickListener(this);
    mRecyclerView.setAdapter(adapter);
}

@Override
public void onItemClick(View view, int position) {
    cardview = (CardView) view;
    cardview.setEnabled(false);

    // Create a new intent to send data from this MainActivity to the CardViewDetails
    // Activity.
    Intent intent = new Intent(this,CardViewDetails.class);
    ListItem listItem = adapter.getItem(position);
    // Add the item object to the Intent.  The item object can be used because the
    // model class implements Parcelable so it holds all of the getters
    // that can be snagged in the next Activity with the
    // getParcelableExtra method.
    intent.putExtra("item",listItem);
    intent.putExtra("position",position);
    startActivity(intent);
    finish();
}

// SearchView
final EditText mSearchEditText = (EditText) mSearchView.findViewById(android.support.v7.appcompat.R.id.search_src_text);

    mSearchEditText.addTextChangedListener(new TextWatcher() {

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {

        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {

        }

        @Override
        public void afterTextChanged(Editable s) {

             final ArrayList<ListItem> filteredModelList = filter(allList, s.toString());

                if (!mSearchView.isIconified() && filteredModelList.size() == 0) {
                    Toast.makeText(MainActivity.this, "Not Found", Toast.LENGTH_SHORT).show();
                    // re-load the list so the Adapter refreshes the RecyclerView list View.
                    adapter.clear();
                    adapter.addAll(allList);
                } else if (!mSearchView.isIconified() && filteredModelList.size() > 0) {                            
                    adapter.setFilter(filteredModelList, s.toString());
                    mRecyclerView.scrollToPosition(0);
                }
            }
        }
    });

private ArrayList<ListItem> filter(List<ListItem> models, String query) {

    query = query.toLowerCase();

    final ArrayList<ListItem> filteredModelList = new ArrayList<>();
    for (ListItem listItem : models) {
        final String text = listItem.getTodo().toLowerCase();
        final String text2 = listItem.getNote1().toLowerCase();
        final String text3 = listItem.getNote2().toLowerCase();
        if (text.contains(query) || text2.contains(query) ||
            text3.contains(query)) {
            filteredModelList.add(listItem);
        }
    }
    return filteredModelList;
}

RecyclerItemClickListener:

public interface RecyclerItemClickListener {

    void onItemClick(View view, int position);
}

CardViewDetails:

public class CardViewDetails extends AppCompatActivity {

private int position;
private SQLiteDB helper;
List<ListItem> listItems;
private CardView cardview;

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_details);

    final CardView cardView = (CardView) findViewById(R.id.dets);

    // Create a variable for the skychill footer text.
    final TextView skychilltext5;

    // A db helper instance is needed for the removeItem() below
    // when the user Longclicks the skycard for deletion.
    helper = new SQLiteDB(this);

    // Get the position of the clicked on R. list CardView from
    // the MainActivity's intent bundle.
    Bundle extras = getIntent().getExtras();
    if (extras != null) {
        // get the CardView item using the int position from the
        // MainActivity's onItemClick() and the putExtra in the intent.
        position = extras.getInt("position",0); // 0 is default value
    }

    cb2 = (TextView) findViewById(R.id.cb2);

    helper = new SQLiteDB(this);
    listItems = new ArrayList<>();
    listItems = helper.getAllDBItems(); 

    cb2.setText(listItems.get(position).getTodo());

    ...

}   

推荐答案

应用过滤器后,sql DB( getAllDBItems )数据保持不变.您仅将position传递给 CardViewDetail .并且sql数据是原始列表.

After applying filter the sql DB (getAllDBItems ) data remain same. You are passing only position to CardViewDetail. And the sql data is of original list.

您应该将可打包的 ListItem 传递给CardViewDetails而不是位置.您的问题将得到解决.

You should pass your ListItem as parcelable to CardViewDetails instead of position. your problem will be solved.

这篇关于RecyclerView:筛选列表中的错误位置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆