【问题标题】:Checkbox in Listview get check with wrong position itemListview 中的复选框获取错误位置项的检查
【发布时间】:2023-03-10 17:40:01
【问题描述】:

我创建了在每一行中提供唯一视图的列表视图,但我添加了复选框。我遇到了一个问题,它将检查第一项并滚动列表。奇怪的匿名项目被检查。你能为此提供解决方案吗?谢谢

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    int type = getItemViewType(position);
    final ItemDto dto = listStoreItemDto.get(position);
    if (convertView == null) {
        holder = new ViewHolder();
        switch (type) {
            case TYPE_IMAGE:
                convertView = mInflater.inflate(R.layout.listview_video, null);
                holder.vidImgAdapter = (ImageView)convertView.findViewById(R.id.vidImgAdapter);
                holder.vidImgPlayAdapter = (ImageView)convertView.findViewById(R.id.vidImgPlayAdapter);
                holder.vidNameAdapter = (TextViewVerbStyle)convertView.findViewById(R.id.vidNameAdapter);
                holder.vidDetailAdapter = (TextViewVerbStyle)convertView.findViewById(R.id.vidDetailAdapter);
                holder.linearAdpVideo = (LinearLayout)convertView.findViewById(R.id.linearAdpVideo);
                holder.tbAdpVideo = (ToggleButton)convertView.findViewById(R.id.tbAdpVideo);
                break;
            case TYPE_VIDEO:
                convertView = mInflater.inflate(R.layout.listview_video, null);
                holder.vidImgAdapter = (ImageView)convertView.findViewById(R.id.vidImgAdapter);
                holder.vidImgPlayAdapter = (ImageView)convertView.findViewById(R.id.vidImgPlayAdapter);
                holder.vidNameAdapter = (TextViewVerbStyle)convertView.findViewById(R.id.vidNameAdapter);
                holder.vidDetailAdapter = (TextViewVerbStyle)convertView.findViewById(R.id.vidDetailAdapter);
                holder.linearAdpVideo = (LinearLayout)convertView.findViewById(R.id.linearAdpVideo);
                holder.tbAdpVideo = (ToggleButton)convertView.findViewById(R.id.tbAdpVideo);
                break;
            case TYPE_MUSIC:
                convertView = mInflater.inflate(R.layout.listview_music, null);
                holder.musicImgAdapter = (ImageView)convertView.findViewById(R.id.musicImgAdapter);
                holder.musicNameAdapter = (TextViewVerbStyle)convertView.findViewById(R.id.musicNameAdapter);
                holder.musicDetailAdapter = (TextViewVerbStyle)convertView.findViewById(R.id.musicDetailAdapter);
                holder.tbAdpMusic = (ToggleButton)convertView.findViewById(R.id.tbAdpMusic);
                holder.linearAdpMusic = (LinearLayout)convertView.findViewById(R.id.linearAdpMusic);
                break;
            case TYPE_STORAGE:
                convertView = mInflater.inflate(R.layout.listview_storage, null);
                holder.storageImgAdapter = (ImageView)convertView.findViewById(R.id.storageImgAdapter);
                holder.imgAdpStorageChevronRight = (ImageView)convertView.findViewById(R.id.imgAdpStorageChevronRight);
                holder.storageNameAdapter = (TextViewVerbStyle)convertView.findViewById(R.id.storageNameAdapter);
                holder.storageDetailAdapter = (TextViewVerbStyle)convertView.findViewById(R.id.storageDetailAdapter);
                holder.linearAdpStorage = (LinearLayout)convertView.findViewById(R.id.linearAdpStorage);
                holder.tbAdpStorage = (ToggleButton)convertView.findViewById(R.id.tbAdpStorage);
                break;
        }
        convertView.setTag(holder);
    } else {
        holder = (ViewHolder)convertView.getTag();
    }
    Log.e("will","holder : "+holder.tbAdpStorage +" | "+holder.tbAdpVideo + " | "+holder.tbAdpMusic);
    switch (type){
        case TYPE_IMAGE:
            MainActivityV3.getImgLoader().init(config);
            MainActivityV3.getImgLoader().displayImage("file://" + Uri.parse(dto.getItemPath()), holder.vidImgAdapter, MainActivityV3.getOptions());
            holder.vidImgPlayAdapter.setVisibility(View.GONE);
            holder.vidNameAdapter.setText(dto.getItemName());
            holder.vidDetailAdapter.setText(mContext.getResources().getString(R.string.detail_item,
                    StringUtils.showSizeByte(FileManageUtil.getKbSize(dto.getItemSize()),
                            FileManageUtil.getMbSize(dto.getItemSize())), StringUtils.getDateVideo(dto.getLastModified())));
            if(isCheckable) {
                holder.linearAdpVideo.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        if (dto.isSelected()) {
                            dto.setIsSelected(false);
                            holder.tbAdpVideo.setChecked(dto.isSelected());
                        } else {
                            dto.setIsSelected(true);
                            holder.tbAdpVideo.setChecked(dto.isSelected());
                        }
                        ((MainActivityV3) mContext).updateSelected(getTotalItemSelected());
                    }
                });
                holder.tbAdpVideo.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        if (dto.isSelected()) {
                            dto.setIsSelected(false);
                        } else {
                            dto.setIsSelected(true);
                        }
                        ((MainActivityV3) mContext).updateSelected(getTotalItemSelected());
                    }
                });
                holder.tbAdpVideo.setVisibility(View.VISIBLE);
            }
            else {
                holder.tbAdpVideo.setVisibility(View.GONE);
            }
            break;
        case TYPE_VIDEO:
            MainActivityV3.getImgLoader().init(config);
            MainActivityV3.getImgLoader().displayImage("file://" + Uri.parse(dto.getItemPath()), holder.vidImgAdapter, MainActivityV3.getOptions());
            holder.vidNameAdapter.setText(dto.getItemName());
            holder.vidDetailAdapter.setText(mContext.getResources().getString(R.string.detail_item,
                    StringUtils.showSizeByte(FileManageUtil.getKbSize(dto.getItemSize()),
                            FileManageUtil.getMbSize(dto.getItemSize())), StringUtils.getDateVideo(dto.getLastModified())));
            if(isCheckable){
                holder.linearAdpVideo.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        if (dto.isSelected()) {
                            dto.setIsSelected(false);
                            holder.tbAdpVideo.setChecked(dto.isSelected());
                        } else {
                            dto.setIsSelected(true);
                            holder.tbAdpVideo.setChecked(dto.isSelected());
                        }
                        ((MainActivityV3) mContext).updateSelected(getTotalItemSelected());
                    }
                });
                holder.tbAdpVideo.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        if (dto.isSelected()) {
                            dto.setIsSelected(false);
                        } else {
                            dto.setIsSelected(true);
                        }
                        ((MainActivityV3) mContext).updateSelected(getTotalItemSelected());
                    }
                });
                holder.tbAdpVideo.setVisibility(View.VISIBLE);
            }
            else {
                holder.tbAdpVideo.setVisibility(View.GONE);
            }
            break;
        case TYPE_MUSIC:
            if(dto.getItemName().toString().toLowerCase().contains(".mp3"))
                holder.musicImgAdapter.setImageResource(R.drawable.ic_mp3);
            else if(dto.getItemName().toString().toLowerCase().contains(".ogg"))
                holder.musicImgAdapter.setImageResource(R.drawable.ic_ogg);
            else if(dto.getItemName().toString().toLowerCase().contains(".mp4"))
                holder.musicImgAdapter.setImageResource(R.drawable.ic_mp4);
            else if(dto.getItemName().toString().toLowerCase().contains(".wav"))
                holder.musicImgAdapter.setImageResource(R.drawable.ic_wav);
            holder.musicNameAdapter.setText(dto.getItemName());
            holder.musicDetailAdapter.setText(mContext.getResources().getString(R.string.detail_item, StringUtils.showSizeByte(FileManageUtil.getKbSize(dto.getItemSize()),
                    FileManageUtil.getMbSize(dto.getItemSize())), StringUtils.getDateVideo(dto.getLastModified())));
            if(isCheckable) {
                holder.linearAdpMusic.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        if (dto.isSelected()) {
                            dto.setIsSelected(false);
                            holder.tbAdpMusic.setChecked(dto.isSelected());
                        } else {
                            dto.setIsSelected(true);
                            holder.tbAdpMusic.setChecked(dto.isSelected());
                        }
                        ((MainActivityV3) mContext).updateSelected(getTotalItemSelected());
                    }
                });
                holder.tbAdpMusic.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        if (dto.isSelected()) {
                            dto.setIsSelected(false);
                        } else {
                            dto.setIsSelected(true);
                        }
                        ((MainActivityV3) mContext).updateSelected(getTotalItemSelected());
                    }
                });
                holder.tbAdpMusic.setVisibility(View.VISIBLE);
            }
            else {
                holder.tbAdpMusic.setVisibility(View.GONE);
            }
            break;
        case TYPE_STORAGE:
            File file = new File(dto.getItemPath());
            if(dto.isDirectory()){
                holder.storageDetailAdapter.setText(mContext.getResources().getString(R.string.detail_item,
                        file.listFiles().length>=1?file.listFiles().length+" items":file.listFiles().length+" item",
                        StringUtils.getDateVideo(dto.getLastModified())));
                holder.storageImgAdapter.setImageResource(R.drawable.ic_folder);
                holder.imgAdpStorageChevronRight.setVisibility(View.VISIBLE);
            }else{
                if(StringUtils.isArchivesExtension(mContext,dto.getItemName())){//file archive
                    holder.storageImgAdapter.setImageResource(R.drawable.ic_archives);
                }else if(StringUtils.isDocsExtension(mContext,dto.getItemName())){//file doc
                    holder.storageImgAdapter.setImageResource(R.drawable.ic_text_doc);
                }else if(StringUtils.isApkExtension(mContext,dto.getItemName())){
                    holder.storageImgAdapter.setImageResource(R.drawable.ic_apk);
                }
                else{//broken image
                    holder.storageImgAdapter.setImageResource(R.drawable.ic_broken_image);
                }
                holder.storageDetailAdapter.setText(mContext.getResources().getString(R.string.detail_item,
                        StringUtils.showSizeByte(dto.getItemSize()),
                        StringUtils.getDateVideo(dto.getLastModified())));
                holder.imgAdpStorageChevronRight.setVisibility(View.GONE);
            }
            holder.storageNameAdapter.setText(dto.getItemName());
            if(isCheckable) {
                holder.linearAdpStorage.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        if (dto.isSelected()) {
                            dto.setIsSelected(false);
                            holder.tbAdpStorage.setChecked(dto.isSelected());
                        } else {
                            dto.setIsSelected(true);
                            holder.tbAdpStorage.setChecked(dto.isSelected());
                        }
                        ((MainActivityV3) mContext).updateSelected(getTotalItemSelected());
                    }
                });
                holder.tbAdpStorage.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        if (dto.isSelected()) {
                            dto.setIsSelected(false);
                        } else {
                            dto.setIsSelected(true);
                        }
                        ((MainActivityV3) mContext).updateSelected(getTotalItemSelected());
                    }
                });
                if(dto.isDirectory())
                    holder.imgAdpStorageChevronRight.setVisibility(View.GONE);
                holder.tbAdpStorage.setVisibility(View.VISIBLE);
            }
            else {
                holder.tbAdpStorage.setVisibility(View.GONE);
            }
            break;
    }
    return convertView;
}

【问题讨论】:

  • 这背后的原因是,listview一旦离开屏幕就会回收视图。
  • 改用回收视图。有 VIewHolder 适配器和绑定模式的实现你的视图总是如你所愿
  • 你能发布你的 getview() 代码吗?
  • 感谢您的回复.. 这是我的 getview @Exigente05
  • 一小时前有人问了同样的问题。你不读stackoverflow吗?你不会谷歌一下吗? stackoverflow.com/questions/39912827/…

标签: android listview baseadapter


【解决方案1】:

您必须创建一个包含所有要在列表视图行中显示的组件(EX:ComponentClass)的类。在这个类中创建布尔值和所有 setter/getter 和 ...。 在adapter Java class extent arrayAdapter中,你必须创建名为ViewHolder的内部类,并使用这个内部类来展示adapter的组件。

static class ViewHolder {
    TextView text;
    CheckBox checkbox;
}

在 getView 方法中,使用自爆代码:

viewHolder.checkbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {

            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                int getPosition = (Integer) buttonView.getTag();  // Here we get the position that we have set for the checkbox using setTag.
                ComponentClass.get(getPosition).setSelected(buttonView.isChecked()); // Set the value of checkbox to maintain its state.
            }
        });

感谢Lalit Poptani

【讨论】:

    【解决方案2】:

    我遇到了同样的问题。我通过在适配器类中覆盖这两个方法来解决它。

    @Override
    public int getViewTypeCount() {
              return getCount();
    }
    
    @Override
    public int getItemViewType(int position) {
    
     return position;
    }
    

    希望这会有所帮助!

    【讨论】:

    • 不,这不会有帮助。您在一小时前也发布了此代码作为另一个帖子的答案。但它不被认为是正确的。你的代码根本不能用来解决回收问题。
    • 嘿,这还不够完整。我现在已经更新了该代码。它现在可以工作了。尝试一次。
    【解决方案3】:

    Great example shown here

    Example 2

    您正在选择一个,而 View holder 将其保持选中状态。您可以将布尔变量添加到您的 ObjectIncome 对象中并保持您的项目的选择状态。

    public class AdapterTrashIncome extends RecyclerView.Adapter<AdapterTrashIncome.ViewHolder> {
    
        private ArrayList<ObjectIncome> myItems = new ArrayList<>();
    
        public AdapterTrashIncome(ArrayList<ObjectIncome> getItems, Context context){
            try {
                mContext = context;
                myItems = getItems;
                }catch (Exception e){
                Log.e(FILE_NAME, "51: " + e.toString());
                e.printStackTrace();
            }
        }
    
        public class ViewHolder extends RecyclerView.ViewHolder {
            public TextView tvContent;
            public CheckBox cbSelect;
    
            public ViewHolder(View v) {
                super(v);
                tvContent = (TextView) v.findViewById(R.id.tvContent);
                cbSelect = (CheckBox) v.findViewById(R.id.cbSelect);
            }
        }
    
        @Override
        public void onBindViewHolder(ViewHolder holder, final int position) {
            final ObjectIncome objIncome = myItems.get(position);
            String content = "<b>lalalla</b>";
            holder.tvContent.setText(Html.fromHtml(content));
    
            //in some cases, it will prevent unwanted situations
            holder.cbSelect.setOnCheckedChangeListener(null);
    
            //if true, your checkbox will be selected, else unselected
            holder.cbSelect.setChecked(objIncome.isSelected());
    
            holder.cbSelect.setOnCheckedChangeListener(new OnCheckedChangeListener() {
                    @Override
                    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                        //set your object's last status
                        objIncome.setSelected(isChecked);
                }
            });
    
        }
    }
    

    在 Activity 的 onCreate 方法中。

    recyclerView = (RecyclerView) findViewById(R.id.recyclerview1);
    
            recylerViewLayoutManager = new LinearLayoutManager(context);
    
            recyclerView.setLayoutManager(recylerViewLayoutManager);
    
            recyclerViewAdapter = new RecyclerViewAdapter(context, subjects);
    
            recyclerView.setAdapter(recyclerViewAdapter);
    

    你的Activiy xml 喜欢

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context="com.android_examples.recyclerview_android_examplescom.MainActivity"
        android:id="@+id/relativelayout1">
    
        <android.support.v7.widget.RecyclerView
            android:id="@+id/recyclerview1"
            android:scrollbars="vertical"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            />
    
    </RelativeLayout>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-01-15
      • 1970-01-01
      • 2012-06-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-08
      • 1970-01-01
      相关资源
      最近更新 更多