Android ListView Item含有RadioButton、CheckBox、RatingBar、EditText

ListView在项目里面会经常遇到,但是有时候在使用的过程中会遇到一些让我们意想不到的问题,ListView的复用问题在前面的博客中已经介绍过了点击浏览ListView的复用问题。这边博客主要是关于什么的呢?先来看看效果图
这里写图片描述
这一篇可以说是关于ListView的复用的经常用到的事例。单选,多选,星星的滑动和修改保存EditText的内容
单选的不单单是复用的问题,之所以可以实现单选就是我们大家所常用的,先设置所有的状态为未选中的状态,然后记录点击的item的索引位置,再根据索引设置相应的条目是否选中。
先看看单选的示例代码

package com.lyxrobert.listviewmore.adapter;

import android.content.Context;
import android.view.View;
import android.widget.RadioButton;
import com.lyxrobert.listviewmore.R;

import java.util.HashMap;
import java.util.List;

/**
 * Created by ytx on 2016/11/11.
 */
public class RadioAdp extends BaseAdp<String>{
    private Context mContext;
    private List<String> data;
    private HashMap<String, Boolean> rabMap;
    HashMap<String, Boolean> selectState = new HashMap<String, Boolean>();
    public RadioAdp(List<String> data) {
        super(data);
    }
    public RadioAdp(Context context,List<String> data) {
        this(data);
        this.data = data;
        this.mContext = context;
        this.rabMap = new HashMap<String, Boolean>();
    }
    @Override
    public View getConvertView(View convertView, final int position) {
        final ViewHolder viewHolder;
        if(convertView !=null){
            viewHolder = (ViewHolder) convertView.getTag();
        }else {
            viewHolder = new ViewHolder();
            convertView = View.inflate(mContext, R.layout.item_radio,null);
            viewHolder.rab_select=(RadioButton) convertView
                    .findViewById(R.id.rab_select);

        }
        viewHolder.rab_select.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {                for (String key : selectState.keySet()) {
                    selectState.put(key, false);
                }
                selectState.put(String.valueOf(position), viewHolder.rab_select.isChecked());
                RadioAdp.this.notifyDataSetChanged();
            }
        });
        boolean isSelect = false;
        if (selectState.get(String.valueOf(position)) == null
                || selectState.get(String.valueOf(position)) == false) {
            isSelect = false;
            selectState.put(String.valueOf(position), false);
        } else{
            isSelect = true;
        }
        viewHolder.rab_select.setChecked(isSelect);
        viewHolder.rab_select.setText(data.get(position));
        convertView.setTag(viewHolder);
        return convertView;
    }
    public class  ViewHolder{
        RadioButton rab_select;
    }
}

再点击事件触发的代码里面我们可以看到

for (String key : selectState.keySet()) {
     selectState.put(key, false);
 }
selectState.put(String.valueOf(position), viewHolder.rab_select.isChecked());
RadioAdp.this.notifyDataSetChanged();

for循环里面的代码的作用就是把所有的选中状态置为未选中的状态,selectState.put(String.valueOf(position), viewHolder.rab_select.isChecked());isChecked()就是判断当前是否选中,如果选中返回值为true否则为false,而这段代码的作用就是以索引作为key值然后再以选中的状态设置为value值,方便以后判断使用。

boolean isSelect = false;
 if (selectState.get(String.valueOf(position)) == null
  || selectState.get(String.valueOf(position)) == false) {
        isSelect = false;
        selectState.put(String.valueOf(position), false);
     } else{
           isSelect = true;
       }

if (selectState.get(String.valueOf(position)) == null
|| selectState.get(String.valueOf(position)) == false)这行代码就是判断获取的value是否为空,如果为空证明当前未发生点击选择的事件,那么对应的选中状态也就是false,仅仅判断为空也是不行的,如果有点击事件发生但是不是发生在自身上面那么对应的状态当然也就是false状态了。
多选和星星的滑动的主要是解决一下ListVIew的复用问题即可。
关于ListView item里面的EditText编辑内容的修改和保存先看看代码最后我们再来分析一下。

package com.lyxrobert.listviewmore.adapter;

import android.content.Context;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.MotionEvent;
import android.view.View;
import android.widget.EditText;
import android.widget.RadioButton;

import com.lyxrobert.listviewmore.R;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by ytx on 2016/11/11.
 */
public class EditAdp extends BaseAdp<String>{
    private Context mContext;
    private List<String> data;
    HashMap<Integer, View> editMap;
    private List<Map<String, String>> mData;
    public Map<String, String> editorValue = new HashMap<String, String>();
    public EditAdp(List<String> data) {
        super(data);
    }
    public EditAdp(Context context, List<String> data) {
        this(data);
        this.data = data;
        this.mContext = context;
        this.editMap = new HashMap<Integer, View>();
        editorValue.clear();
        mData = new ArrayList<Map<String, String>>();
        for(int i = 0; i < 20; i++) {
            Map<String, String> valueMap = new HashMap<String, String>();
            valueMap.put("value", "我是测试编辑数据的第"+(i+1)+"条数据");
            mData.add(valueMap);
        }

    }
    @Override
    public View getConvertView(View convertView, final int position) {
        final ViewHolder viewHolder;
        if (convertView == null) {
            viewHolder = new ViewHolder();
            convertView = View.inflate(mContext, R.layout.item_edit,null);
            viewHolder.et_test = (EditText) convertView
                    .findViewById(R.id.et_test);
            viewHolder.et_test.setTag(position);
            class MyTextWatcher implements TextWatcher {
                ViewHolder mViewHolder;
                public MyTextWatcher(ViewHolder holder) {
                    mViewHolder = holder;
                }

                @Override
                public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

                }

                @Override
                public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {

                }

                @Override
                public void afterTextChanged(Editable editable) {
                    if (!TextUtils.isEmpty(editable)) {
                        int position = (Integer) mViewHolder.et_test.getTag();
                        mData.get(position).put("value",
                                editable.toString());
                }
            }
            }

            viewHolder.et_test.addTextChangedListener(new MyTextWatcher(viewHolder));
            convertView.setTag(viewHolder);
        } else {
            viewHolder = (ViewHolder) convertView.getTag();
            viewHolder.et_test.setTag(position);
        }
        if (mData.get(position).get("value")!=null){
            Object value = mData.get(position).get("value");
            if (value != null && !"".equals(value)) {
                viewHolder.et_test.setText(value.toString());
            }
        }
        viewHolder.et_test.clearFocus();
        int textLenth = viewHolder.et_test.getText().toString().trim().length();
        if (textLenth>0){
            viewHolder.et_test.setSelection(textLenth);
        }
        return convertView;
    }
    public class  ViewHolder{
        EditText et_test;
    }
}

如果我们要想知道EditText中的内容是否发生了变化,我们就需要使用TextWatcher来对EditText实行监听。TextWatcher对我们来说也许并不陌生,不如说限制EditText输入的字数,我们经常使用的登录根据输入的长度判断登录按钮是否可以点击,也是通过TextWatcher来实现的。
在TextWatcher里面有一个afterTextChanged方法,此方法只有在输入框内容发生变化的时候才会触发此方法。

if (!TextUtils.isEmpty(editable)) {
        int position = (Integer) mHolder.et_test.getTag();
        mData.get(position).put("value", editable.toString());
    }

editable其实就是输入之后的内容,如果editable为空则说明内容并没有发生变化,否则发生了变化。如果发生变化我们就要将变化的那部分内容添加到对应的Map集合里面。后面会有获取的代码获取并添加到EditText里面。

点击下载源码

这里写图片描述
如果有疑问欢迎留言

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章