Reputation: 15
I have a listView
with a custom adapter which implements filterable. The filter function works finally perfectly fine, up until I try to open an item within the listView
. When I try to open my filtered result, it moves me to the wrong activity. I've gone through some different approaches from other posts, one of which (latest attempt) is marked as a comment in my code down below.
What's weird to me is why this problem occurs, since I'm using a simple "if-else" case...
Another post, which I can't find anymore, suggested to use set/get-tag, which I'm not very familiar with. I also suspect the issue might lie within the filter, since the filter doesnt give out the arrayList, but the filtered version of it. However, I couldn't figure that one out, either.
Any help is appreciated!
MainActivity down to its core:
public class MainActivity extends AppCompatActivity implements TextWatcher{
MyAdapter adapter;`
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView lw = findViewById(R.id.lw);
Button notiz = findViewById(R.id.btnNotiz);
Button merk = findViewById(R.id.btnMerk);
EditText suche = findViewById(R.id.suchen);
lw.setLongClickable(true);
final ArrayList<Objekt> arrayList = new ArrayList();
arrayList.add(new Objekt("AAA", "AAA-Street"));
arrayList.add(new Objekt( "BBB","BBB-Street")); // and so on
adapter = new MyAdapter(this,arrayList);
suche.addTextChangedListener(this);
Collections.sort(arrayList, new Comparator<Objekt>() {
@Override
public int compare(Objekt o1, Objekt o2) {
return o1.getKuerzel().compareToIgnoreCase(o2.getKuerzel());
}
});
lw.setAdapter(adapter);
lw.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
TextView textView = view.findViewById(R.id.textViewFullAdress);
ClipboardManager cm = (ClipboardManager)
getSystemService(Context.CLIPBOARD_SERVICE);
assert cm != null;
cm.setText(textView.getText().toString());
Toast.makeText(MainActivity.this, "Kopiert!", Toast.LENGTH_SHORT).show();
return false;
}
});
lw.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String selection = arrayList.get(position).getKuerzel();
//one of the things I've tried: Objekt selection = (Objekt)((MyAdapter)parent.getAdapter()).getItem(position);
if(selection.equals("AAA")){
Intent intent0 = new Intent(MainActivity.this, AAA.class);
startActivity(intent0);
} else if(selection.equals("BBB")){
Intent intent0 = new Intent(MainActivity.this, BBB.class);
startActivity(intent0);
} //and so on
}
});
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
adapter.getFilter().filter(s);
}
@Override
public void afterTextChanged(Editable s) {
}
MyAdapter:
public class MyAdapter extends BaseAdapter implements Filterable {
Context context;
ArrayList<Objekt> arr, tempArr;
CustomFilter cs;
public MyAdapter(Context context, ArrayList<Objekt> arr) {
this.context = context;
this.arr = arr;
this.tempArr = arr;
}
@Override
public int getCount() {
return arr.size();
}
@Override
public Object getItem(int position) {
return arr.get(position);
//return position;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
convertView = LayoutInflater.from(context).inflate(R.layout.adapter_view_layout,parent,false);
TextView kuerzel = convertView.findViewById(R.id.textViewKuerzel);
TextView fullAdress = convertView.findViewById(R.id.textViewFullAdress);
kuerzel.setText(arr.get(position).getKuerzel());
fullAdress.setText(arr.get(position).getFullAdress());
return convertView;
}
@Override
public Filter getFilter() {
if (cs == null){
cs = new CustomFilter();
}
return cs;
}
class CustomFilter extends Filter{
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
if (constraint != null && constraint.length()>0) {
constraint = constraint.toString().toUpperCase();
ArrayList<Objekt> filters = new ArrayList<Objekt>();
for (int i = 0; i < tempArr.size(); i++) {
if (tempArr.get(i).getKuerzel().toUpperCase().contains(constraint)) {
Objekt objekt = new Objekt(tempArr.get(i).getKuerzel(), tempArr.get(i).getFullAdress());
filters.add(objekt);
}
}
results.count = filters.size();
results.values = filters;
}
else
{
results.count = tempArr.size();
results.values = tempArr;
}
return results;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
arr = (ArrayList<Objekt>)results.values;
notifyDataSetChanged();
}
}
Objekt:
public class Objekt {
String kuerzel;
String fullAdress;
public Objekt(String kuerzel, String fullAdress) {
this.kuerzel = kuerzel;
this.fullAdress = fullAdress;
}
public String getKuerzel() {
return kuerzel;
}
public void setKuerzel(String kuerzel) {
this.kuerzel = kuerzel;
}
public String getFullAdress() {
return fullAdress;
}
public void setFullAdress(String fullAdress) {
this.fullAdress = fullAdress;
}
}
I haven't quite figured out formatting here, sorry...
Upvotes: 0
Views: 395
Reputation: 4508
After applying the filter in MyAdapter class, the elements in the arr in MyAdapter and arrayList in the MainActivity will be different. for example, if initially your list contains ['AAA','BBB','AAC','CCC','DDD'] then both the list will have same elements:
arrayList = ['AAA','BBB','AAC','CCC','DDD'] // in MainActivity
arr = ['AAA','BBB','AAC','CCC','DDD'] // in MyAdapter
Now if you apply the filter by typing 'AA', the elements of the arr will be updated but arraylist will remain same.
arrayList = ['AAA','BBB','AAC','CCC','DDD'] // in MainActivity
arr = ['AAA','AAC'] // in MyAdapter
Now if the user has selected the second element from the list i.e. at index 1.
In your MainActivity, you have used String selection = arrayList.get(position).getKuerzel();
It will return 'BBB' as you are selecting index 1 from the arrayList.
The solution to the problem is to filter arrayList as well in onTextChanged method.
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
adapter.getFilter().filter(s);
//filter arrayList
}
Upvotes: 1