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裏面。
點擊下載源碼
如果有疑問歡迎留言