Android中ListView中包含CheckBox或Switch时滑动丢失选中状态的解决方法

 

1.主函数:

/**
 * Created by sgf on 2018/8/10.
 * 添加TOKNEN
 */

public class AddTokenActivity extends BaseActivity implements View.OnClickListener{

    private ListView lv_addTokenDetails;
    private List<String> list = new ArrayList<>();
    private List<CheckBean> mDatas;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_addtoken);
        TextView tv_title_bar = findViewById(R.id.tv_title_order);
        tv_title_bar.setText("Add TOKEN");

        lv_addTokenDetails = findViewById(R.id.lv_addTokenDetails);

        findViewById(R.id.iv_title_back).setOnClickListener(this);

        init();
    }

    private void init() {

        mDatas = new ArrayList<>();
        CheckBean checkBean;
//        for (int i = 0; i <50 ; i++) {
//            list.add("R"+i);
//        }
        for (int i = 0; i <50 ; i++) {
            checkBean =new CheckBean("ETH"+i,false);
            mDatas.add(checkBean);
//            if (mDatas.get(i).isChecked()) {//默认选中第一个
//                mDatas.add(new CheckBean(list.get(i), true));
//                continue;
//            }else {
//
//                mDatas.add(new CheckBean(list.get(i), false));
//            }
        }
        final AddTokenAdapter addTokenAdapter = new AddTokenAdapter(this);
        addTokenAdapter.setContext(this);
        addTokenAdapter.setData(mDatas);
        lv_addTokenDetails.setAdapter(addTokenAdapter);

//        lv_addTokenDetails.setOnItemClickListener(new AdapterView.OnItemClickListener() {
//            @Override
//            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//                AddTokenAdapter.ViewHolder holder = (AddTokenAdapter.ViewHolder) view.getTag();
//                holder.switch_addToken.toggle();// 在每次获取点击的item时改变checkbox的状态
//                AddTokenAdapter.isSelected.put(position, true); // 同时修改map的值保存状态
//                addTokenAdapter.notifyDataSetChanged();//注意这一句必须加上,否则checkbox无法正常更新状态
//            }
//        });
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.iv_title_back:
                finish();
                break;
            default:
                break;
        }
    }
}

2.主要的代码在适配器中:

a.解决方法一:使用List集合

/**
 * 添加Token
 * Created by sgf on 2018/8/10.
 */

public class AddTokenAdapter extends BaseAdapter {
    private List<CheckBean> list;
    private LayoutInflater inflater;
    private Context context;


    public AddTokenAdapter(Context context) {
        inflater = LayoutInflater.from(context);
    }


    public Context getContext() {
        return context;
    }

    public void setContext(Context context) {
        this.context = context;
    }
    public void setData(List<CheckBean> lists) {
        list = lists;
        notifyDataSetChanged();
    }

    @Override
    public int getCount() {
        if (list == null) {
            return 0;
        }
        return list.size();
    }

    @Override
    public Object getItem(int position) {
        return list.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {

        AddTokenAdapter.ViewHolder viewHolder = null;
        if (convertView == null) {
            convertView = inflater.inflate(R.layout.add_token_item, null);
            viewHolder = new ViewHolder();
            viewHolder.iv_addTokenIcon = convertView.findViewById(R.id.iv_addTokenIcon);
            viewHolder.tv_addTokenName = convertView.findViewById(R.id.tv_addTokenName);
            viewHolder.tv_addTokenContent = convertView.findViewById(R.id.tv_addTokenContent);
            viewHolder.tv_addTokenAddress = convertView.findViewById(R.id.tv_addTokenAddress);
            viewHolder.switch_addToken = convertView.findViewById(R.id.switch_addToken);
            convertView.setTag(viewHolder);

        } else {
            viewHolder = (AddTokenAdapter.ViewHolder) convertView.getTag();
        }
        if(position == 0){
            viewHolder.switch_addToken.setVisibility(View.GONE);
        }else {
            viewHolder.switch_addToken.setVisibility(View.VISIBLE);
        }
        viewHolder.tv_addTokenName.setText(list.get(position).getStr());
//        viewHolder.tv_addTokenContent.setText(list.get(position));
//        viewHolder.tv_addTokenAddress.setText(list.get(position));
//        viewHolder.switch_addToken.setChecked(isSelected.get(position));
//        final int pos  = position; //pos必须声明为final
        viewHolder.switch_addToken.setTag(position);

        viewHolder.switch_addToken.setOnCheckedChangeListener(null);
        viewHolder.switch_addToken.setChecked(list.get(position).isChecked());
        viewHolder.switch_addToken.setOnCheckedChangeListener(onCheckedChangeListener);

        return convertView;
    }


    CompoundButton.OnCheckedChangeListener onCheckedChangeListener = new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            list.get((int)buttonView.getTag()).setChecked(isChecked);
                if(isChecked) {
                    //选中时 do some thing
//                    list.get(position).setChecked(isSelected.get(position));
//                    isSelected.put(pos,true);
                    ToastUtil.showShort(context,"开启了" + (int)buttonView.getTag());
                } else {
                    //非选中时 do some thing
//                    list.get(position).setChecked(isSelected.get(position));
//                    isSelected.put(pos,false);
                    ToastUtil.showShort(context,"关闭了" + (int)buttonView.getTag());
                }
        }
    };

    public static class ViewHolder {
        public ImageView iv_addTokenIcon;//icon
        public TextView tv_addTokenName;//token名称
        public TextView tv_addTokenContent;//token内容
        public TextView tv_addTokenAddress;//token地址
        public Switch switch_addToken;//token开关
    }
}

b.a.解决方法二:使用HashMap

/**
 * 添加Token
 * Created by sgf on 2018/8/10.
 */

public class AddTokenAdapter extends BaseAdapter {
    private List<String> list;
    public static HashMap<Integer, Boolean> isSelected= new HashMap<Integer, Boolean>();
    private LayoutInflater inflater;
    private Context context;
    private List<CheckBean> mDatas;
    private boolean[] checks; //用于保存选择状态


    public AddTokenAdapter(Context context) {
        inflater = LayoutInflater.from(context);
    }

    public AddTokenAdapter() {
    }
    public Context getContext() {
        return context;
    }

    public void setContext(Context context) {
        this.context = context;
    }
    public void setData(List<String> lists) {
        list = lists;
        notifyDataSetChanged();
    }

    @Override
    public int getCount() {
        if (list == null) {
            return 0;
        }
        return list.size();
    }

    @Override
    public Object getItem(int position) {
        return list.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {

        AddTokenAdapter.ViewHolder viewHolder = null;
        if (convertView == null) {
            convertView = inflater.inflate(R.layout.add_token_item, null);
            viewHolder = new ViewHolder();
            viewHolder.iv_addTokenIcon = convertView.findViewById(R.id.iv_addTokenIcon);
            viewHolder.tv_addTokenName = convertView.findViewById(R.id.tv_addTokenName);
            viewHolder.tv_addTokenContent = convertView.findViewById(R.id.tv_addTokenContent);
            viewHolder.tv_addTokenAddress = convertView.findViewById(R.id.tv_addTokenAddress);
            viewHolder.switch_addToken = convertView.findViewById(R.id.switch_addToken);
            convertView.setTag(viewHolder);

        } else {
            viewHolder = (AddTokenAdapter.ViewHolder) convertView.getTag();
        }
        if(position == 0){
            viewHolder.switch_addToken.setVisibility(View.GONE);
        }else {
            viewHolder.switch_addToken.setVisibility(View.VISIBLE);
        }
        viewHolder.tv_addTokenName.setText(list.get(position));
        viewHolder.tv_addTokenContent.setText(list.get(position));
        viewHolder.tv_addTokenAddress.setText(list.get(position));
//        viewHolder.switch_addToken.setChecked(isSelected.get(position));
//        final int pos  = position; //pos必须声明为final
        viewHolder.switch_addToken.setTag(position);

        viewHolder.switch_addToken.setOnCheckedChangeListener(null);
        viewHolder.switch_addToken.setChecked(isSelected.get(position)==null?false:true);
        viewHolder.switch_addToken.setOnCheckedChangeListener(onCheckedChangeListener);

        return convertView;
    }


    CompoundButton.OnCheckedChangeListener onCheckedChangeListener = new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
//            checks[pos] = isChecked;
            isSelected.put((int)buttonView.getTag(),isChecked);
//                if(checks[pos]) {
//                    //选中时 do some thing
                    list.get(position).setChecked(isSelected.get(position));
//                    isSelected.put(pos,true);
//                    ToastUtil.showShort(context,"开启了" + position);
//                } else {
//                    //非选中时 do some thing
                    list.get(position).setChecked(isSelected.get(position));
//                    isSelected.put(pos,false);
//                    ToastUtil.showShort(context,"关闭了" + position);
//                }
        }
    };

    public static class ViewHolder {
        public ImageView iv_addTokenIcon;//icon
        public TextView tv_addTokenName;//token名称
        public TextView tv_addTokenContent;//token内容
        public TextView tv_addTokenAddress;//token地址
        public Switch switch_addToken;//token开关
    }
}

在这里List要比HashMap集合效率高一点,但是HashMap标记状态后点击返回再次进入这个界面会保存上次选中的状态(杀进程除外),而List则是没有选中的状态,需要你进一步做保存数据的处理,比如:使用序列化。

3.布局:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="91dp">

    <RelativeLayout
        android:id="@+id/rl_addtoken"
        android:layout_width="match_parent"
        android:layout_height="90dp"
        android:background="@drawable/rb_white_two_shape">

        <ImageView
            android:id="@+id/iv_addTokenIcon"
            android:layout_width="32dp"
            android:layout_height="30dp"
            android:layout_centerVertical="true"
            android:layout_marginLeft="20dp"
            android:src="@drawable/zc_tf" />

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:layout_marginLeft="15dp"
            android:layout_marginRight="20dp"
            android:layout_toRightOf="@+id/iv_addTokenIcon"
            android:orientation="vertical">

            <TextView
                android:id="@+id/tv_addTokenName"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="ETH"
                android:textColor="@color/black_one"
                android:textSize="16sp"
                android:textStyle="bold" />

            <TextView
                android:id="@+id/tv_addTokenContent"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="Eth Foundation"
                android:textColor="@color/gray_one"
                android:textSize="13sp" />

            <TextView
                android:id="@+id/tv_addTokenAddress"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="0x925122...3hhfrhf"
                android:textColor="@color/gray_one"
                android:textSize="13sp" />

        </LinearLayout>

        <Switch
            android:id="@+id/switch_addToken"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:layout_marginRight="15dp"
            android:layout_toRightOf="@+id/iv_addTokenIcon"
            android:gravity="right"
            android:textOff=""
            android:textOn=""
            android:switchMinWidth="30dp"
            android:thumb="@drawable/switch_custom_thumb_selector"
            android:track="@drawable/switch_custom_track_selector" />
        <!--<Switch-->
            <!--android:id="@+id/switch_addToken2"-->
            <!--android:layout_width="wrap_content"-->
            <!--android:layout_height="wrap_content"-->
            <!--android:layout_alignParentRight="true"-->
            <!--android:layout_centerVertical="true"-->
            <!--android:layout_marginRight="90dp"-->
            <!--android:layout_toRightOf="@+id/iv_addTokenIcon"-->
            <!--android:gravity="right"-->
            <!--android:textOff=""-->
            <!--android:textOn=""-->
            <!--android:switchMinWidth="40dp"-->
            <!--android:thumb="@drawable/selector_thumb"-->
            <!--android:track="@drawable/selector_track" />-->
    </RelativeLayout>
    <View
        android:layout_width="match_parent"
        android:layout_marginLeft="25dp"
        android:layout_alignParentBottom="true"
        android:background="@color/gray_six"
        android:layout_height="0.5dp"></View>
</RelativeLayout>

4.自定义Switch开关按钮的样式:

a.样式一:

switch_custom_thumb_selector.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/switch_custom_thumb_on" android:state_checked="true" />
    <item android:drawable="@drawable/switch_custom_thumb_off" android:state_checked="false" />
</selector>

switch_custom_thumb_on.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval">
    <solid android:color="#94C5FF" />
    <size
        android:width="20dp"
        android:height="20dp" />
</shape>

switch_custom_thumb_off.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval">
    <solid android:color="#AAA" />
    <size
        android:width="20dp"
        android:height="20dp" />
</shape>

switch_custom_track_selector.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/switch_custom_track_on" android:state_checked="true" />
    <item android:drawable="@drawable/switch_custom_track_off" android:state_checked="false" />
</selector>

switch_custom_track_on.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <solid android:color="#B6D6FE" />
    <stroke
        android:width="5dp"
        android:color="#00000000" />
    <corners android:radius="20dp" />
    <size
        android:width="50dp"
        android:height="20dp"/>
</shape>

switch_custom_track_off.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <solid android:color="#E3E3E3" />
    <stroke
        android:width="5dp"
        android:color="#00000000" />
    <corners android:radius="20dp" />
    <size
        android:width="50dp"
        android:height="20dp"/>
</shape>

b.样式二:

selector_thumb.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
    <item android:drawable="@drawable/thumb_blue" android:state_checked="true"/>
    <item android:drawable="@drawable/thumb_grey"/>

</selector>

thumb_blue.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval" >

    <size
        android:height="30dp"
        android:width="30dp" />

    <stroke
        android:width="2dp"
        android:color="#BEBEBE" />

    <solid android:color="#6AB5FB" />

</shape>

thumb_grey.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle" >

    <corners android:radius="15dp"/>
    <size
        android:height="30dp"
        android:width="30dp" />

    <stroke
        android:width="2dp"
        android:color="#BEBEBE" />

    <solid android:color="#D5D5D5" />

</shape>

selector_track.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:drawable="@drawable/track_bg" android:state_checked="true"/>
    <item android:drawable="@drawable/track_bg"/>

</selector>

track_bg.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <size
        android:width="64dp"
        android:height="30dp"/>
    <corners android:radius="15dp"/>
    <stroke
        android:width="2dp"
        android:color="#BEBEBE"/>
</shape>

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值