OnItemClick 侦听器和单击的 View 项的可见性
Posted
技术标签:
【中文标题】OnItemClick 侦听器和单击的 View 项的可见性【英文标题】:OnItemClick Listener and the visibility of the clicked View item 【发布时间】:2014-08-23 19:46:52 【问题描述】:我有一个 ListView,其中每个项目包含一个 Textview
和 ImageView
,其中 imageView
是 invisible
,通过单击每个列表视图项目,它将是 visible
我的代码是:
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
ImageView acceptImageView= (ImageView) view.findViewById(R.id.iAccept);
if (acceptImageView.getVisibility()==ImageView.INVISIBLE)
acceptImageView.setVisibility(ImageView.VISIBLE);
else
acceptImageView.setVisibility(ImageView.INVISIBLE);
List View adapter :
public class ContentViewrAdaptor extends BaseAdapter implements Filterable
private List<String> originalData = null;
private List<String> filteredData = null;
private LayoutInflater mInflater;
private Typeface regular;
private ItemFilter mFilter = new ItemFilter();
public ContentViewrAdaptor(Context context, List<String> data, Typeface regular)
this.filteredData = data;
this.originalData = data;
this.regular = regular;
mInflater = LayoutInflater.from(context);
public int getCount()
return filteredData.size();
public Object getItem(int position)
return filteredData.get(position);
public long getItemId(int position)
return position;
public View getView(int position, View convertView, ViewGroup parent)
ViewHolder holder;
if (convertView == null)
convertView = mInflater.inflate(R.layout.text_view, null);
holder = new ViewHolder();
holder.text = (TextView) convertView.findViewById(R.id.contentText);
holder.text.setTypeface(regular);
convertView.setTag(holder);
else
holder = (ViewHolder) convertView.getTag();
if (filteredData.get(position).contains("font"))
holder.text.setText(html.fromHtml(filteredData.get(position)));
else
holder.text.setText(filteredData.get(position));
return convertView;
static class ViewHolder
TextView text;
public Filter getFilter()
return mFilter;
private class ItemFilter extends Filter
@Override
protected FilterResults performFiltering(CharSequence constraint)
String filterString = constraint.toString().toLowerCase();
FilterResults results = new FilterResults();
final List<String> list = originalData;
int count = list.size();
final ArrayList<String> nlist = new ArrayList<String>(count);
String filterableString;
for (int i = 0; i < count; i++)
filterableString = list.get(i);
if (filterableString.toLowerCase().contains(filterString))
filterableString = filterableString.replaceAll(filterString, "<font color='red'>" + filterString + "</font>");
nlist.add(filterableString);
results.values = nlist;
results.count = nlist.size();
return results;
@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence constraint, FilterResults results)
filteredData = (ArrayList<String>) results.values;
notifyDataSetChanged();
但问题是当我接受第一项时,第三项也会被接受,因为向下滚动时它是第一项
我该如何解决这个问题?
更新(getView)
但还是同样的问题
public View getView(final int position, View convertView, ViewGroup parent)
ViewHolder holder;
if (convertView == null)
convertView = mInflater.inflate(R.layout.text_view, null);
holder = new ViewHolder();
holder.image = (ImageView) convertView.findViewById(R.id.iAccept);
convertView.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
Toast.makeText(context,position,Toast.LENGTH_SHORT).show();
if (v.findViewById(R.id.iAccept).getVisibility() == ImageView.VISIBLE)
v.findViewById(R.id.iAccept).setVisibility(ImageView.INVISIBLE);
else
v.findViewById(R.id.iAccept).setVisibility(ImageView.VISIBLE);
);
holder.text = (TextView) convertView.findViewById(R.id.contentText);
holder.text.setTypeface(regular);
convertView.setTag(holder);
else
holder = (ViewHolder) convertView.getTag();
if (filteredData.get(position).contains("font"))
holder.text.setText(Html.fromHtml(filteredData.get(position)));
else
holder.text.setText(filteredData.get(position));
return convertView;
最终更新
终于在DIVA的帮助下解决了,
我把适配器改成了这个:
public class ContentViewrAdaptor extends BaseAdapter implements Filterable
private List<String> originalData = null;
private List<String> filteredData = null;
private ArrayList<Integer> visiblePositions;
private LayoutInflater mInflater;
private Typeface regular;
private Context context;
private ItemFilter mFilter = new ItemFilter();
public ContentViewrAdaptor(Context context, List<String> data, Typeface regular)
this.filteredData = data;
this.originalData = data;
visiblePositions = new ArrayList<Integer>();
this.regular = regular;
this.context = context;
mInflater = LayoutInflater.from(context);
public int getCount()
return filteredData.size();
public Object getItem(int position)
return filteredData.get(position);
public long getItemId(int position)
return position;
public View getView(final int position, View convertView, ViewGroup parent)
final ViewHolder holder;
if (convertView == null)
convertView = mInflater.inflate(R.layout.text_view, null);
holder = new ViewHolder();
holder.image = (ImageView) convertView.findViewById(R.id.iAccept);
holder.image.setTag(position);
holder.text = (TextView) convertView.findViewById(R.id.contentText);
holder.text.setTypeface(regular);
convertView.setTag(holder);
else holder = (ViewHolder) convertView.getTag();
adjustImageVisibility(holder.image, visiblePositions.contains(position));
convertView.setOnClickListener(new View.OnClickListener()
public void onClick(View v)
onViewClicked(holder, position);
);
if (filteredData.get(position).contains("font")) holder.text.setText(Html.fromHtml(filteredData.get(position)));
else holder.text.setText(filteredData.get(position));
return convertView;
public void onViewClicked(ViewHolder viewHolder, Integer position)
if (visiblePositions.contains(position))
adjustImageVisibility(viewHolder.image, false);
visiblePositions.remove(position);
else
adjustImageVisibility(viewHolder.image, true);
visiblePositions.add(position);
public void adjustImageVisibility(ImageView imageView, boolean visible)
if (visible) imageView.setVisibility(View.VISIBLE);
else imageView.setVisibility(View.INVISIBLE);
static class ViewHolder
ImageView image;
TextView text;
public Filter getFilter()
return mFilter;
private class ItemFilter extends Filter
@Override
protected FilterResults performFiltering(CharSequence constraint)
String filterString = constraint.toString().toLowerCase();
FilterResults results = new FilterResults();
final List<String> list = originalData;
int count = list.size();
final ArrayList<String> nlist = new ArrayList<String>(count);
String filterableString;
for (int i = 0; i < count; i++)
filterableString = list.get(i);
if (filterableString.toLowerCase().contains(filterString))
filterableString = filterableString.replaceAll(filterString, "<font color='red'>" + filterString + "</font>");
nlist.add(filterableString);
results.values = nlist;
results.count = nlist.size();
return results;
@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence constraint, FilterResults results)
filteredData = (ArrayList<String>) results.values;
notifyDataSetChanged();
【问题讨论】:
视图可见性和其他属性必须在您的适配器getView()
中设置,因为视图回收
@SimonMarquis 你的意思是我应该在每次点击项目时更新我的适配器?
您应该更新您的适配器正在显示的数据,然后通知您的适配器数据已更改
ViewHolder 中的 imageview 在哪里?
我现在不知道如何在适配器上处理这个问题,是否可以告诉我应该在我的适配器上做什么?
【参考方案1】:
您需要确保的几件事:
请使用arraylist而不是静态字符串[] 使用 View.Visible 或 invisible 代替 Imagview.Visible 和 在这里比较可见性时不可见的是有效的代码:适配器
public class ListAdapter extends BaseAdapter implements Filterable
private ArrayList<String> originalData = null;
private ArrayList<String> filteredData = null;
private LayoutInflater mInflater;
private Context context;
private ItemFilter mFilter = new ItemFilter();
public ListAdapter(Context context, ArrayList<String> data)
this.filteredData = new ArrayList<>(data);
this.originalData = new ArrayList<>(data);
this.context = context;
mInflater = LayoutInflater.from(context);
public int getCount()
return filteredData.size();
public Object getItem(int position)
return filteredData.get(position);
public long getItemId(int position)
return position;
public View getView(final int position, View convertView, ViewGroup parent)
ViewHolder holder = new ViewHolder();
if (convertView == null)
convertView = mInflater.inflate(R.layout.list_item, null);
holder = new ViewHolder();
holder.image = (ImageView) convertView.findViewById(R.id.image);
// holder.image.setVisibility(View.INVISIBLE);
holder.text = (TextView) convertView.findViewById(R.id.text);
convertView.setTag(holder);
else
holder = (ViewHolder) convertView.getTag();
// holder.image.setTag(position);
convertView.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
if (v.findViewById(R.id.image).getVisibility() == View.VISIBLE)
v.findViewById(R.id.image).setVisibility(View.INVISIBLE);
else
v.findViewById(R.id.image).setVisibility(View.VISIBLE);
);
if (filteredData.get(position).contains("font"))
holder.text.setText(Html.fromHtml(filteredData.get(position)));
else
holder.text.setText(filteredData.get(position));
return convertView;
static class ViewHolder
ImageView image;
TextView text;
@Override
public Filter getFilter()
return mFilter;
private class ItemFilter extends Filter
@Override
protected FilterResults performFiltering(CharSequence constraint)
String filterString = constraint.toString().toLowerCase();
FilterResults results = new FilterResults();
final ArrayList<String> list = originalData;
int count = list.size();
final ArrayList<String> nlist = new ArrayList<String>(count);
String filterableString;
for (int i = 0; i < count; i++)
filterableString = list.get(i);
if (filterableString.toLowerCase().contains(filterString))
filterableString = filterableString.replaceAll(
filterString, "<font color='red'>" + filterString
+ "</font>");
nlist.add(filterableString);
results.values = nlist;
results.count = nlist.size();
return results;
@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence constraint,
FilterResults results)
filteredData = (ArrayList<String>) results.values;
notifyDataSetChanged();
活动
public class MyActivity extends Activity
private ListView listView;
private ListAdapter adapter;
@Override
public void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
listView = (ListView) findViewById(R.id.listView);
ArrayList<String> LIST_ITEM = new ArrayList<String>();
LIST_ITEM.add("Item 1");
LIST_ITEM.add("Item 2");
LIST_ITEM.add("Item 3");
LIST_ITEM.add("Item 4");
LIST_ITEM.add("Item 5");
LIST_ITEM.add("Item 6");
LIST_ITEM.add("Item 7");
LIST_ITEM.add("Item 8");
LIST_ITEM.add("Item 9");
LIST_ITEM.add("Item 10");
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
adapter = new ListAdapter(MyActivity.this, LIST_ITEM);
listView.setAdapter(adapter);
COMPLETE SOURCE CODE
编辑 ALTERNATIVE CODE.
【讨论】:
我现在测试它,不幸的是它不起作用 chk 替代代码你需要这样做,如果有任何问题,请通过评论告诉我 在这个例子中,我们在 convertview 上有一个复选框,在这个问题上,我们想让它在点击侦听器上为 convertview 工作 正确,但这是你需要对 convertview 做的想法......如果这没有帮助?那么你需要在你的演示中进行解释......【参考方案2】:您需要为每个列表项创建一个boolean
参数isVisible
。并在单击列表项时将其设置为 true/false。在getView()
方法中检查每个可见项的isVisible
值:
if(isVisible)
make the image visible;
else
hide the image;
【讨论】:
以上是关于OnItemClick 侦听器和单击的 View 项的可见性的主要内容,如果未能解决你的问题,请参考以下文章
按钮 onClick 和 ListView onItemClick
在 LinearLayout 中获取 onItemClick 实现的位置
如何为 RecyclerView 列表元素设置单击侦听器以显示 AlertDialog?