android - OnClick 事件重复 ListView 项目

标签 android listview baseadapter android-viewholder

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

 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;
    }

}

最佳答案

ListView 项目是可重用的。当您滚动列表时,一些项目会变得“不可见”, View 项目将被重新用于将变得可见的项目。

您不会保留哪些项已展开和哪些未展开的数据,因此您无法根据 getView 方法中其先前的“展开”状态将“展开”部分的可见性设置为 GONE 或 VISIBLE。简单的解决方法是制作 Map<Integer,Boolean>并在扩展时保持状态在这里 put(position,true)并隐藏put(position,false) .在获取 View 中

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

第零步(为展开状态添加 map )

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);
            }
        });

关于android - OnClick 事件重复 ListView 项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35538353/

相关文章:

android - 如何在 YouTube API v3 上获得 "music channels within a channel”

android - Facebook SDK - Ant clean 发布失败

java - MediaMetadata.getString java.lang.RuntimeException : Could not read bitmap from parcel blob

c# - ListView 作为日志文件

java - ListView 页脚导致 ArrayIndexOutOfBoundsException

android - 在 BaseAdapter android 中停止媒体播放器

android - 如何在 Cordova/Phonegap - Eclipse for Android 上安装 barcodescanner-plugin?

android - 如何在 ListView 中添加 EditText 并在所有行中动态获取其值?

android - ListView 中的独特项目 View

java - Android ListView 与数组数据库