Reputation: 3
I am relatively new to Android programming. I have a RecycleView
with CardView
in it settled in rows. On click of any row opens a new Activity associated to that row. Everything was working great until I added the filter functionality to this list. When I search the list and then click on one Item, it doesn't open the activity associated with the filtered results. It opens up an Activity related to the Item at that position in Original list.
Example - Original List : AA, BA, CC, DA, ED, FF
Search : 'A' Filtered results: AA, BA, DA
But when I click on item DA it opens up the Activity for CC. I have called notifyDataSetChanged()
on the adapter.
I searched and found similar problems but couldn't implement in my code.
Here is the code:
public class MainActivity extends AppCompatActivity implements ExampleAdapter.OnItemClickListener{
public static final String EXTRA_IMG = "imageresource";
public static final String EXTRA_TXT1 = "text1";
public static final String EXTRA_TXT2 = "text2";
public static final String EXTRA_TXT3 = "text3";
private ArrayList<ExampleItem> mExampleList;
private RecyclerView mRecyclerView;
private ExampleAdapter mAdapter;
private RecyclerView.LayoutManager mLayoutManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
createExampleList();
buildRecyclerView();
EditText editText = findViewById(R.id.editText);
editText.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) {
filter(s.toString());
}
});
}
private void filter(String text) {
ArrayList<ExampleItem> filteredList = new ArrayList<>();
for (ExampleItem item : mExampleList) {
if (item.getText1().toLowerCase().contains(text.toLowerCase())) {
filteredList.add(item);
}
}
mAdapter.filterList(filteredList);
}
private void createExampleList() {
//just creating list
}
private void buildRecyclerView() {
mRecyclerView = findViewById(R.id.recyclerView);
mRecyclerView.setHasFixedSize(true);
mLayoutManager = new LinearLayoutManager(this);
mAdapter = new ExampleAdapter(mExampleList);
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerView.setAdapter(mAdapter);
mAdapter.setOnItemClickListener(MainActivity.this);
}
@Override
public void onItemClick(int position) {
Intent detailintent = new Intent(this,DetailActivity.class);
ExampleItem clickedItem = mExampleList.get(position);
detailintent.putExtra(EXTRA_IMG,clickedItem.getImageResource());
detailintent.putExtra(EXTRA_TXT1,clickedItem.getText1());
detailintent.putExtra(EXTRA_TXT2,clickedItem.getText2());
detailintent.putExtra(EXTRA_TXT3,clickedItem.getText3());
startActivity(detailintent);
}
}
public class ExampleAdapter extends RecyclerView.Adapter<ExampleAdapter.ExampleViewHolder> {
private ArrayList<ExampleItem> mExampleList;
private OnItemClickListener mListener;
public interface OnItemClickListener{
void onItemClick(int position);
}
public void setOnItemClickListener(OnItemClickListener listener){
mListener=listener;
}
public class ExampleViewHolder extends RecyclerView.ViewHolder {
public ImageView mImageView;
public TextView mTextView1;
public TextView mTextView2;
public TextView mTextView3;
public ExampleViewHolder(View itemView) {
super(itemView);
mImageView = itemView.findViewById(R.id.imageView);
mTextView1 = itemView.findViewById(R.id.textView);
mTextView2 = itemView.findViewById(R.id.textView7);
mTextView3 = itemView.findViewById(R.id.textView2);
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(mListener != null ){
int position = getAdapterPosition();
if(position != RecyclerView.NO_POSITION){
mListener.onItemClick(position);
}
}
}
});
}
}
public ExampleAdapter(ArrayList<ExampleItem> exampleList) {
mExampleList = exampleList;
}
@Override
public ExampleViewHolder onCreateViewHolder(ViewGroup parent, int viewType){
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.example_item,
parent, false);
ExampleViewHolder evh = new ExampleViewHolder(v);
return evh;
}
@Override
public void onBindViewHolder(ExampleViewHolder holder, int position) {
ExampleItem currentItem = mExampleList.get(position);
holder.mImageView.setImageResource(currentItem.getImageResource());
holder.mTextView1.setText(currentItem.getText1());
holder.mTextView2.setText(currentItem.getText2());
holder.mTextView3.setText(currentItem.getText3());
}
@Override
public int getItemCount() {
return mExampleList.size();
}
public void filterList(ArrayList<ExampleItem> filteredList) {
mExampleList = filteredList;
notifyDataSetChanged();
}
}
Upvotes: 0
Views: 789
Reputation: 445
You have two lists, one in your activity and one in your adapter.
After filtering your list, you only notify the adapter and only set the adapters mExampleList
to the new, filtered list. The Activity's list remains the same.
When you click on an item, you let the activity handle the click event. But the activity still have the old, unfiltered list so it will send the wrong data to your new activity.
Solution: simply add mExampleList = filteredList
next to the line mAdapter.filterList(filteredList);
in your filtering method
Upvotes: 2