2014-02-24 2 views
2

Android 및 Java 프로그래밍에 익숙하지 않은데 최근에 문제가 생겼습니다. 나는 몇 시간 동안 해답을 찾고 있었지만 성공하지 못했습니다. CheckBox 및 EditText가 포함 된 행이있는 사용자 지정 ListView 및 사용자 지정 어댑터가 있습니다. 처음으로 표시 될 때마다 OK이지만, 아래로 스크롤하면 CheckBox 및 EditText의 값이 변경되기 시작합니다.Android : ViewHolder, OnCheckedChangedListener 및 TextChangedListener가 포함 된 맞춤형 어댑터

<?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; 
    } 
} 

, 내가 스크롤되었고, 그 때 내가하기로 결정 이유를

다음

내 row_edit.xml입니다 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; 
    } 
} 

로그 캣과 디버깅 후 나는 생성 단지 8 홀더 (내 화면에 맞게 (0-7) 항목이 있기 때문에)이 있다는 것을 알고있다. 이들은 아래로 스크롤 할 때 재사용되고 있습니다. 위치가 7보다 큰 항목에 대해 생성 된 OnCheckedChangeListeners 및 TextChangedListeners가 없습니다.

나는 무엇을 해야할지 잘 모릅니다. 누군가 나를 도울 수 있습니까?

답변

4

나는 결국 대답을 얻었다.

기존의 TextWatcher를 제거하고 새 TextWatcher를 추가하는 것을 의미하는 setOnTextChangedListener 메소드를 사용할 수있는 자체 클래스 UpgEditText를 만드는 EditText를 확장했습니다.

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가 재활용 될 때마다, 나는 청취자 만 변경하고 잘 작동합니다.

관련 문제