OnItemClick 侦听器和单击的 View 项的可见性

Posted

技术标签:

【中文标题】OnItemClick 侦听器和单击的 View 项的可见性【英文标题】:OnItemClick Listener and the visibility of the clicked View item 【发布时间】:2014-08-23 19:46:52 【问题描述】:

我有一个 ListView,其中每个项目包含一个 TextviewImageView,其中 imageViewinvisible,通过单击每个列表视图项目,它将是 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?

Android里的AdapterView中OnItemClickListener监听器四个参数的含义

Listview 中未触发 Onitemclick 侦听器

listview OnItemClick 侦听器在片段中不起作用