![](/img/trans.png)
[英]making ViewHolder final in Custom Listview Adapter android
[英]Android: Custom Adapter with ViewHolder, OnCheckedChangedListener and TextChangedListener
我是Android和Java編程的新手,我最近遇到了一個問題。 幾個小時我一直在尋找答案,但我沒有成功。 我有一個自定義ListView和一個自定義適配器,其中一行包含CheckBox和EditText。 每當它第一次顯示時都沒問題,但是當我向下滾動時,它開始改變CheckBox和EditText的值。
這是我的row_edit.xml:
<?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="wrap_content" >
<EditText
android:id="@+id/bonus"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:inputType="numberSigned"
android:gravity="right"
android:selectAllOnFocus="true"
android:textSize="16sp" />
<CheckBox
android:id="@+id/checkBox_person"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_toLeftOf="@id/bonus"
android:textSize="16sp" />
</RelativeLayout>
Item_edit(適配器項):
public class Item_edit {
private String meno;
private boolean ucast;
private int bonus;
public Item_edit(String meno, boolean ucast, int bonus) {
super();
this.meno = meno;
this.ucast = ucast;
this.bonus = bonus;
}
public String getMeno() {
return meno;
}
public boolean getUcast() {
return ucast;
}
public int getBonus() {
return bonus;
}
public void setMeno(String meno) {
this.meno = meno;
}
public void setUcast(boolean ucast) {
this.ucast = ucast;
}
public void setBonus(int bonus) {
this.bonus = bonus;
}
}
當我滾動時ListView不順暢,這就是我決定使用ViewHolder的原因。 Adapter_edit:
public class Adapter_edit extends ArrayAdapter<Item_edit> {
private final Context context;
private final ArrayList<Item_edit> itemsArrayList;
private final Edit edit;
public Adapter_edit(Context context, ArrayList<Item_edit> itemsArrayList, Edit edit) {
super(context, R.layout.row_edit, itemsArrayList);
this.edit = edit;
this.context = context;
this.itemsArrayList = itemsArrayList;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.row_edit, parent, false);
holder = new ViewHolder();
//Log.e("NewHolder", "position = " + position);
holder.checkBox = (CheckBox) convertView
.findViewById(R.id.checkBox_person);
holder.bonus = (EditText) convertView.findViewById(R.id.bonus);
convertView.setTag(holder);
holder.checkBox.setText(itemsArrayList.get(position).getMeno());
holder.checkBox.setChecked(itemsArrayList.get(position).getUcast());
holder.bonus.setText(Integer.toString(itemsArrayList.get(position)
.getBonus()));
holder.checkBox
.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
itemsArrayList.get(position).setUcast(isChecked);
}
});
holder.bonus.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
try {
if (itemsArrayList.get(position).getBonus() != Integer
.parseInt(s.toString()) && !edit
.getUcast(position)) {
itemsArrayList.get(position).setBonus(
Integer.parseInt(s.toString()));
itemsArrayList.get(position).setUcast(true);
}
}
catch (NumberFormatException e) {
itemsArrayList.get(position).setBonus(0);
}
}
@Override
public void afterTextChanged(Editable s) {
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
});
}
else {
holder = (ViewHolder) convertView.getTag();
}
holder.checkBox.setText(itemsArrayList.get(position).getMeno());
holder.checkBox.setChecked(itemsArrayList.get(position).getUcast());
holder.bonus.setText(Integer.toString(itemsArrayList.get(position)
.getBonus()));
return convertView;
}
static class ViewHolder {
CheckBox checkBox;
EditText bonus;
}
}
使用LogCat調試后,我知道只生成了8個持有者(因為有(0-7)個項目適合我的屏幕)。 當我向下滾動時,這些正被重用。 沒有為位置大於7的項創建OnCheckedChangeListeners和TextChangedListeners。
我不知道該怎么做。 有人能幫我嗎?
我終於得到了答案。
我擴展了EditText,創建了我自己的類UpgEditText,它具有方法setOnTextChangedListener,這意味着刪除現有的TextWatcher並添加一個新的TextWatcher。
UpgEditText
public class UpgEditText extends EditText {
public UpgEditText(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public UpgEditText(Context context, AttributeSet attrs) {
super(context, attrs);
}
public UpgEditText(Context context) {
super(context);
}
TextWatcher watcher = null;
public void setOnTextChangedListener(final int position, final Adapter_edit adapter) {
if (watcher != null) {
this.removeTextChangedListener(watcher);
}
watcher = new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void afterTextChanged(Editable s) {
try {
adapter.itemsArrayList.get(position).setBonus(
Integer.parseInt(s.toString()));
}
catch (Exception e) {
}
}
};
this.addTextChangedListener(watcher);
}
}
我通常也使用ViewHolder:
public class ViewHolder {
CheckBox chBoxUcast;
UpgEditText edTBonus;
}
CustomAdapter getView()方法:
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.row_edit, parent, false);
holder = new ViewHolder();
holder.chBoxUcast = (CheckBox) convertView
.findViewById(R.id.checkBox_person);
holder.edTBonus = (UpgEditText) convertView
.findViewById(R.id.bonus);
convertView.setTag(holder);
}
else {
holder = (ViewHolder) convertView.getTag();
}
holder.edTBonus.setOnTextChangedListener(position, this);
holder.chBoxUcast
.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
// TODO Auto-generated method stub
itemsArrayList.get(position).setUcast(isChecked);
}
});
holder.chBoxUcast.setText(itemsArrayList.get(position).getMeno());
holder.chBoxUcast.setChecked(itemsArrayList.get(position).getUcast());
holder.edTBonus.setText(Integer.toString(itemsArrayList.get(position)
.getBonus()));
return convertView;
}
現在一切都很好。 每次轉換convertView時,我只會更改監聽器並且運行良好。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.