Reputation: 59
I am new to Android programming and I have a ListView when filtered always return me the first item in the list, so how do I fix this?
For instance, my list contains A.A, A.B, A.C, B.C, B.D. When I want to search the list for things starting with B, I will get B.C, B.D but when I click B.C, it returns me A.A and B.D, it returns me A.B
I am weeks I'm looking for a solution! please help me !!
public class MainActivity extends Activity implements
SearchView.OnQueryTextListener, AdapterView.OnItemClickListener {
ListView lv;
SearchView search_view;
String[] country_names , iso_codes ;
TypedArray country_flags ;
ArrayList<Country> countrylist ;
CustomAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lv = (ListView) findViewById(R.id.list_view);
search_view = (SearchView) findViewById(R.id.search_view);
country_names = getResources().getStringArray(R.array.country_names);
iso_codes = getResources().getStringArray(R.array.iso_Code);
country_flags = getResources().obtainTypedArray(R.array.country_flags);
countrylist = new ArrayList<Country>();
for (int i = 0; i < country_names.length; i++) {
Country country = new Country(country_names[i] , iso_codes[i] ,
country_flags.getResourceId(i, -1) );
countrylist.add(country);
}
adapter = new CustomAdapter(getApplicationContext(), countrylist );
lv.setAdapter(adapter);
search_view.setOnQueryTextListener(this);
lv.setOnItemClickListener(this);
}
@Override
public boolean onQueryTextChange(String newText) {
adapter.getFilter().filter(newText);
return false;
}
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
public void onItemClick(AdapterView<?> l, View v, int position, long id) {
Log.i("HelloListView", "You clicked Item: " + id + " at position:" + position);
// Then you start a new Activity via Intent
Intent intent = new Intent();
intent.setClass(this, ListItemDetail.class);
intent.putExtra("position", position);
// Or / And
intent.putExtra("id", id);
startActivity(intent);
}
list item detail
public class ListItemDetail extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list_item_detail);
Intent intent = getIntent();
int position = intent.getIntExtra("position", 0);
// Here we turn your string.xml in an array
String[] myKeys = getResources().getStringArray(R.array.sections);
String[] myKeys2 = getResources().getStringArray(R.array.testo2);
String[] myKeys3 = getResources().getStringArray(R.array.testo3);
String[] myKeys4 = getResources().getStringArray(R.array.testo4);
TextView myTextView = (TextView) findViewById(R.id.my_textview);
myTextView.setText(myKeys[position]);
TextView myTextView2 = (TextView) findViewById(R.id.testo2);
myTextView2.setText(myKeys2[position]);
TextView myTextView3 = (TextView) findViewById(R.id.testo3);
myTextView3.setText(myKeys3[position]);
TextView myTextView4 = (TextView) findViewById(R.id.testo4);
myTextView4.setText(myKeys4[position]);
customlistAdapter
public class CustomAdapter extends BaseAdapter implements Filterable {
Context context;
ArrayList<Country> countrylist;
ArrayList<Country> mStringFilterList;
ValueFilter valueFilter;
CustomAdapter(Context context , ArrayList<Country> countrylist) {
this.context = context;
this.countrylist = countrylist;
mStringFilterList = countrylist;
}
@Override
public int getCount() {
return countrylist.size();
}
@Override
public Object getItem(int position) {
return countrylist.get(position);
}
@Override
public long getItemId(int position) {
return countrylist.indexOf(getItem(position));
}
@Override
public View getView(int position , View convertView , ViewGroup parent ) {
LayoutInflater mInflater = (LayoutInflater) context
.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
convertView = null;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.list_item, null);
TextView name_tv = (TextView) convertView.findViewById(R.id.name);
TextView iso_tv = (TextView) convertView.findViewById(R.id.code);
ImageView iv = (ImageView) convertView.findViewById(R.id.flag);
Country country = countrylist.get(position);
name_tv.setText(country.getName());
iso_tv.setText(country.getIso_code());
Picasso
.with(context)
.load(url[position])
.fit() // will explain later
.centerCrop()
.into(iv);
}
return convertView;
}
@Override
public Filter getFilter() {
if (valueFilter == null) {
valueFilter = new ValueFilter();
}
return valueFilter;
}
private class ValueFilter extends Filter {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
if (constraint != null && constraint.length() > 0) {
ArrayList<Country> filterList = new ArrayList<Country>();
for (int i = 0; i < mStringFilterList.size(); i++) {
if ( (mStringFilterList.get(i).getName().toUpperCase() )
.contains(constraint.toString().toUpperCase())) {
Country country = new Country(mStringFilterList.get(i)
.getName() , mStringFilterList.get(i)
.getIso_code() , mStringFilterList.get(i)
.getFlag());
filterList.add(country);
}
}
results.count = filterList.size();
results.values = filterList;
} else {
results.count = mStringFilterList.size();
results.values = mStringFilterList;
}
return results;
}
@Override
protected void publishResults(CharSequence constraint,
FilterResults results) {
countrylist = (ArrayList<Country>) results.values;
notifyDataSetChanged();
}
}
contry
public class Country {
String name;
String iso_code;
int flag;
Country(String name, String iso_code, int flag) {
this.name = name;
this.iso_code = iso_code;
this.flag = flag;
}
public String getIso_code() {
return iso_code;
}
public void setIso_code(String iso_code) {
this.iso_code = iso_code;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getFlag() {
return flag;
}
public void setFlag(int flag) {
this.flag = flag;
}
Upvotes: 2
Views: 1248
Reputation: 30985
I notice you're using the position as input to the ListItemDetail
activity. This will cause you problems as the position for a given item will change as the list is filtered.
You should just put the item values into the Intent
then use those values and not look anything up in ListItemDetail
public void onItemClick(AdapterView<?> l, View v, int position, long id) {
Country country = (Country) ((CustomAdapter ) l.getAdapter()).getItem(position);
Intent intent = new Intent(this, ListItemDetail.class);
intent.putExtra("name", country.getName());
intent.putExtra("iso_code", country.getIso_code());
intent.putExtra("flag", country.getFlag());
startActivity(intent);
}
Now change your ListDetailActivity
to use these values:
public class ListItemDetail extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list_item_detail);
Intent intent = getIntent();
String name = intent.getStringExtra("name");
String iso_code = intent.getStringExtra("iso_code");
int flagResId = intent.getIntExtra("flag");
// make a TextView in activity_list_item_detail.xml called "name"
TextView nameTextView = (TextView) findViewById(R.id.name);
nameTextView .setText(name);
// make a TextView in activity_list_item_detail.xml called "iso_code"
TextView isoCodeTextView = (TextView) findViewById(R.id.iso_code);
isoCodeTextView .setText(iso_code);
// make an ImageView in activity_list_item_detail.xml called "flag"
ImageView flagImageView = (ImageView) findViewById(R.id.flag);
flagImageView.setImageResource(flagResId);
}
}
Note this activity won't work until you update your activity_list_item_detail.xml as suggested in the comments
Upvotes: 3