OnClick 事件与列表视图项目重复

Posted

技术标签:

【中文标题】OnClick 事件与列表视图项目重复【英文标题】:OnClick event repeats with listview items 【发布时间】:2016-06-02 23:26:48 【问题描述】:

我的应用中有一个列表视图。每个列表视图行都在点击时展开,隐藏视图变得可见,但问题是隐藏视图对于列表中的许多其他项目也变得可见。我知道这种行为的原因,但我不知道如何解决它。这是我的适配器类

 public class ScheduleTaskAdapter extends BaseAdapter 
    Context context;
    LayoutInflater layoutInflater;
    // List<InterestAndLanguageBean> interestAndLanguageBeans=new ArrayList<>();
    List<BirdsDataBean> imageList = new ArrayList<>();

    public ScheduleTaskAdapter(Context context, List<BirdsDataBean> imagesList) 
        this.context = context;
        this.imageList = imagesList;
        layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    

    @Override
    public int getCount() 
        return imageList.size();
    

    @Override
    public Object getItem(int position) 
        return null;
    

    @Override
    public long getItemId(int position) 
        return 0;
    

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) 
        ViewHolder holder = null;
        if (convertView == null) 
            holder = new ViewHolder();
            convertView = layoutInflater.inflate(R.layout.birds_row, parent, false);
            holder.iv_birds = (ImageView) convertView.findViewById(R.id.iv_bird);
            holder.frameLayout = (FrameLayout) convertView.findViewById(R.id.frame_birds);
            holder.linearLayout = (LinearLayout) convertView.findViewById(R.id.detail_view);
            holder.imageView = (ImageView) convertView.findViewById(R.id.up);
            holder.iv_video = (ImageView) convertView.findViewById(R.id.iv_video);
            holder.iv_sound = (ImageView) convertView.findViewById(R.id.iv_sound);
            holder.tv_short_descript = (TextView) convertView.findViewById(R.id.tv_short_descript);
            holder.tv_category = (TextView) convertView.findViewById(R.id.tv_category);
            holder.tv_long_description = (TextView) convertView.findViewById(R.id.tv_long_description);
            convertView.setTag(holder);
         else 
            holder = (ViewHolder) convertView.getTag();
        
        Uri myUri = Uri.parse(birdsUrlList.get(position).getUrl());
        Glide.with(getActivity()).load(myUri).placeholder(R.drawable.birds).into(holder.iv_birds);
        holder.tv_short_descript.setText(birdsUrlList.get(position).getDescrip());
        holder.tv_long_description.setText(birdsUrlList.get(position).getDescrip_larga());
        holder.tv_category.setText(birdsUrlList.get(position).getNombre_cientifico());
        final ViewHolder finalHolder = holder;
        holder.frameLayout.setOnClickListener(new View.OnClickListener() 
            @Override
            public void onClick(View v) 
                finalHolder.linearLayout.setVisibility(View.VISIBLE);
                finalHolder.iv_sound.setOnClickListener(new View.OnClickListener() 
                    @Override
                    public void onClick(View v) 
                        try 
                            MediaPlayer mp = new MediaPlayer();
                                mp.setDataSource(birdsUrlList.get(position).getUrl_audio());
                                mp.prepare();
                            mp.setOnPreparedListener(new MediaPlayer.OnPreparedListener() 
                                @Override
                                public void onPrepared(MediaPlayer mp) 
                                    mp.start();
                                
                            );
                            mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() 
                                @Override
                                public void onCompletion(MediaPlayer mp) 
                                    mp.release();
                                
                            );
                            //startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(birdsUrlList.get(position).getUrl_video())));
                         catch (Exception e) 
                            e.printStackTrace();
                        
                    
                );
                finalHolder.iv_video.setOnClickListener(new View.OnClickListener() 
                    @Override
                    public void onClick(View v) 
                        hitBirdSeenService(birdsUrlList.get(position).getIdave());
                        finalHolder.iv_video.setImageResource(R.drawable.eye_selected);
                    
                );
            
        );
        holder.imageView.setOnClickListener(new View.OnClickListener() 
            @Override
            public void onClick(View v) 
                finalHolder.linearLayout.setVisibility(View.GONE);
            
        );
        if (birdsUrlList.get(position).getFlag()==1)
        
            holder.iv_video.setImageResource(R.drawable.eye_selected);
        else 
            holder.iv_video.setImageResource(R.drawable.eye110);
        
        //Picasso.with(context).load(myUri).placeholder(R.drawable.image).into(holder.pic);
        //malevich.load(helperTaskBeanList.get(position).getImage()).into(holder.pic);
        return convertView;
    


【问题讨论】:

有什么理由不使用 ExpandableListView 吗? 查看 getview 方法,它为隐藏视图内的两个按钮提供了单击侦听器方法。我没有找到任何显示展开按钮的可展开列表视图教程 将 convertView 和 parent 设置为 final 那会怎样? 【参考方案1】:

ListView 项目是可重复使用的。当您滚动列表时,某些项目将变为“不可见”,而视图项目将被重用于将变为可见的项目。

您不保留哪些项目已展开和哪些未展开的数据,因此您不能将“展开”部分的可见性设置为 GONE 或 VISIBLE,具体取决于其在 getView 方法中之前的“展开”状态。简单的解决方法是创建一个Map&lt;Integer,Boolean&gt; 并在扩展put(position,true) 和隐藏put(position,false) 时将状态保留在这里。在getView

boolean state = expandedStateMap.get(position);
finalHolder.linearLayout.setVisibility((state) ? View.VISIBLE : View.GONE);

步骤零(为展开状态添加地图)

public class ScheduleTaskAdapter extends BaseAdapter 
    Context context;
    LayoutInflater layoutInflater;
    // List<InterestAndLanguageBean> interestAndLanguageBeans=new ArrayList<>();
    List<BirdsDataBean> imageList = new ArrayList<>();
    Map<Integer,Boolean> expandedStateMap = new HashMap<>();

第一步:

    //determine if we already expanded the item
    Boolean state = expandedStateMap.get(position);
    if (state == null) 
      state = false;
    
    finalHolder.linearLayout.setVisibility((state) ? View.VISIBLE :      View.GONE);

    holder.frameLayout.setOnClickListener(new View.OnClickListener() 
            @Override
            public void onClick(View v) 
                //save expanded state 
                expandedStateMap.put(position,true);
                finalHolder.linearLayout.setVisibility(View.VISIBLE);

第二步:

 holder.imageView.setOnClickListener(new View.OnClickListener() 
            @Override
            public void onClick(View v) 
                 expandedStateMap.put(position,false);
                finalHolder.linearLayout.setVisibility(View.GONE);
            
        );

【讨论】:

以上是关于OnClick 事件与列表视图项目重复的主要内容,如果未能解决你的问题,请参考以下文章

在引导模式 ONCLICK 事件中显示动态内容

在swipable列表视图中具有onClickListener的视图不能再刷卡,但仅响应onClick事件

Android Studio:如何将列表视图中的项目添加到列表视图 onClick

onclick 按钮在列表视图中不起作用

刷新按钮onClick Listview数据必须在android中更新[重复]

将复选框列表传递到视图中并拉出 IEnumerable [重复]