问题
When I opened the searched item, it is opening the first item of ListView not the searched one. Even if search and find the items successfuly.
Let me give examples:
- If I search for
Arrow
, I can get theArrow
but when clickedArrow
it is going toAlmost Human
,Almost Human
is my first item of ListView - If I search for
American
I'm gettingThe Americans (first)
andAmerican Horror Story (second)
( two results ) search proccess is successful but if clickThe Americans (second one)
it goes to second item of ListView.
What am I missing?
My search code :
search.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) {
// When user changed the Text
MainActivity.this.adapter.getFilter().filter(cs);
}
@Override
public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,
int arg3) {
// TODO Auto-generated method stub
}
@Override
public void afterTextChanged(Editable arg0) {
// TODO Auto-generated method stub
}
});
}
And here is the CustomListViewAdapter.java
public class CustomListViewAdapter extends ArrayAdapter<RowItem> {
Context context;
public CustomListViewAdapter(Context context, int resourceId,
List<RowItem> items) {
super(context, resourceId, items);
this.context = context;
}
/* private view holder class */
private class ViewHolder {
ImageView imageView;
TextView txtTitle;
TextView txtDesc;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
RowItem rowItem = getItem(position);
LayoutInflater mInflater = (LayoutInflater) context
.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
convertView = mInflater.inflate(R.layout.list_item, null);
holder = new ViewHolder();
holder.txtDesc = (TextView) convertView.findViewById(R.id.desc);
holder.txtTitle = (TextView) convertView.findViewById(R.id.title);
holder.imageView = (ImageView) convertView.findViewById(R.id.icon);
convertView.setTag(holder);
} else
holder = (ViewHolder) convertView.getTag();
holder.txtDesc.setText(rowItem.getDesc());
holder.txtTitle.setText(rowItem.getTitle());
// holder.imageView.setImageBitmap(rowItem.getImageId());
ImageView img = (ImageView) convertView.findViewById(R.id.icon);
ImageView gif = (ImageView) convertView.findViewById(R.id.icon);
// UrlImageViewHelper.loadUrlDrawable(context, rowItem.getImageId());
Ion.with(gif).load("http://www.example.com/wp-content/uploads/2014/03/android-icon/loading.gif");
Drawable drawable=gif.getDrawable();
UrlImageViewHelper.setUrlDrawable(img, rowItem.getImageId(),drawable,
600000);
return convertView;
}
}
RowItem.java
public class RowItem<T> {
private String imageId;
private String title;
private String desc;
public RowItem(String imageId, String title, String desc) {
this.imageId = imageId;
this.title = title;
this.desc = desc;
}
public String getImageId() {
return imageId;
}
public void setImageId(String imageId) {
this.imageId = imageId;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
@Override
public String toString() {
return title + "\n" + desc;
}
}
MainActiviy.java
protected void onCreate(Bundle onSaveInstanceState ) {
super.onCreate(onSaveInstanceState );
setContentView(R.layout.activity_main);
listView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// When clicked, Open the Next Screen
Intent r = new Intent(MainActivity.this, KategoriActivity.class);
r.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
r.putExtra("cat_img", asd[2][position]);
r.putExtra("cat_id", asd[1][position]);
r.putExtra("cat_id2", asd[1][position]);
r.putExtra("cat_name",asd[0][position]);
// r.putExtra("cat_img", bit[1][position]);
startActivityForResult(r, position);
}
});
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
try {
JSONArray jsonResponse = new JSONArray(result);
asd = new String[3][jsonResponse.length()];
rowItems = new ArrayList<RowItem>();
for (int i = 0; i < jsonResponse.length(); i++) {
JSONObject js = jsonResponse.getJSONObject(i);
asd[0][i] = js.getString("Category_Name");
asd[2][i] = js.getString("Image");
asd[1][i] = js.getString("Term_ID");
RowItem item = new RowItem(asd[2][i], asd[0][i], "");
rowItems.add(item);
}
adapter = new CustomListViewAdapter(MainActivity.this,
R.layout.list_item, rowItems);
listView.setAdapter(adapter);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Hope you can help me..
回答1:
Normally if you have an ArrayAdapter of of a custom type like RowItem
it won't automatically handle filtering for you. After all, how can it know which property of RowItem
to filter? You should override the getFilter
method, and store the filtered list separately from the overall list in your adapter. Something like this:
public class CustomListViewAdapter extends ArrayAdapter<RowItem>
{
private final ArrayList<RowItem> mItems;
private ArrayList<RowItem> mFilteredItems;
private final Comparator<Object> mComparator;
public CustomListViewAdapter(Context context, int textViewResourceId, List<RowItem> items)
{
super(context, textViewResourceId);
mItems = new ArrayList<RowItem>(items);
mFilteredItems = new ArrayList<RowItem>(items);
mComparator = new Comparator<Object>()
{
@Override
public int compare(Object o1, Object o2)
{
String s1 = ((RowItem)o1).getTitle();
String s2 = ((RowItem)o2).getTitle();
return s1.toLowerCase(Locale.getDefault()).compareTo(s2.toLowerCase());
}
};
Collections.sort(mItems, mComparator);
Collections.sort(mFilteredItems, mComparator);
}
@Override
public int getCount()
{
return mFilteredItems.size();
}
@Override
public RowItem getItem(int position)
{
return mFilteredItems.get(position);
}
@Override
public int getPosition(RowItem item)
{
return mFilteredItems.indexOf(item);
}
@Override
public Filter getFilter()
{
return new Filter()
{
@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence constraint, FilterResults results)
{
mFilteredItems = (ArrayList<RowItem>)results.values;
if (results.count > 0)
{
notifyDataSetChanged();
}
else
{
notifyDataSetInvalidated();
}
}
@Override
protected FilterResults performFiltering(CharSequence constraint)
{
List<RowItem> filteredResults = new ArrayList<RowItem>();
for (RowItem item : mItems)
{
if (item.getTitle().toLowerCase(Locale.getDefault()).contains(constraint.toString().toLowerCase(Locale.getDefault())))
{
filteredResults.add(item);
}
}
Collections.sort(filteredResults, mComparator);
FilterResults results = new FilterResults();
results.values = filteredResults;
results.count = filteredResults.size();
return results;
}
};
}
}
and in MainActivity:
RowItem item = adapter.getItem(position)
r.putExtra("cat_img", item.getImageId());
r.putExtra("cat_id", item.getTermId());
r.putExtra("cat_id2", item.getTermId());
r.putExtra("cat_name", item.getTitle());
You Also have to add a termid field to RowItem, since it's in your JSON response...
回答2:
Inside ArrayAdapter are two lists: the original list with all the items, and the list of current items that the adapter will create views for. In the beginning, these two lists have the same items. When you filter on the adapter, the original list will continue to hold all the items, but the list being used for display will change because of the filter. When you remove the filter, the current list of items will change again to reflect the original list.
Suppose you have five items. After filtering, the list only shows the last item. The state of these lists then is
currentItems: { item5 }
originalItems: { item1 , item2 , item3 , item4 , item5 }
When you click this item, the ListView reports that position 0
is clicked. This is because the list being shown only has one item. If you then looked for the item at position 0 in the current list, you would get item5
. But if you looked for the item at position 0 of the original list, you would get item1
, which is not the data for the item that was clicked.
I suspect you have a reference to the original list and are using that to get the item data, even when the list is filtered. Instead use adapter.getItem(position)
, it should give you the proper item.
回答3:
Im using something like this and its working fine for me. Im using string value in my list onsitemclick for search and display of desired activity
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
String itemValue = (String) list.getItemAtPosition(position);
if (itemValue == "INDIA") {
Intent intent = new Intent(MainActivity.this, india.class);
startActivity(intent);}
else if (itemValue == "CHINA") {
Intent intent = new Intent(MainActivity.this, china.class);
startActivity(intent);}
else if (itemValue == "IRAQ") {
Intent intent = new Intent(MainActivity.this, usa.class);
startActivity(intent);
}
}
回答4:
get the listView item id from the list you are passing in //your adapter class.
here
for example if your adapter class is ##
class CustomAdapetr(Context context,ArrayList<RowItem>list_item){}
//mainactivity
myListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// HERE IS YOUR ITEM ID:):)
int clickedItem=list_item.indexOf(parent.getAdapter().getItem(position));
}
});
cheers !!!! happy coding
来源:https://stackoverflow.com/questions/23566855/after-searching-for-listview-items-in-android-always-open-first-item-of-listvie