5

私が持っているもの:テキストビューとチェックボックスを備えたカスタムリストビュー。
問題:画面に表示されている最初の項目を確認してからリストをスクロールすると、リストの一番上に戻る (上にスクロールする) ときに値が正しく保存されます。しかし、リストをスクロールして、たとえばリストの最後のツリーのチェックボックスをオンにしたい場合、上下にスクロールするとチェックが外れます....なぜですか?**
他のフォーラムで同じ問題のさまざまな解決策を見てきましたここでもstackoverflowにありますが、問題は解決しません。
私が大丈夫だと思う私のgetView関数の下:

    @Override
      public View getView(final int position, View convertView, ViewGroup parent) {
    final ViewHolder viewHolder;
    if (convertView == null) {
        convertView = mInflater.inflate(R.layout.item_select_friends, null);
        viewHolder=new ViewHolder();
        viewHolder.nameText=(TextView) convertView.findViewById(R.id.personName);
        viewHolder.surnameText=(TextView) convertView.findViewById(R.id.personSurname);
        viewHolder.contactImage=(ImageView) convertView.findViewById(R.id.personImage);
        viewHolder.checkBox=(CheckBox)convertView.findViewById(R.id.checkBox);

        convertView.setTag(viewHolder);

        viewHolder.nameText.setTag(viewHolder.nameText);
        viewHolder.nameText.setTag(viewHolder.surnameText);
        viewHolder.contactImage.setTag(data[position]);
        viewHolder.checkBox.setChecked(data[position].isCheck());  
        viewHolder.checkBox.setOnClickListener(new OnClickListener() {  

            public void onClick(View arg0) {  

                if(viewHolder.checkBox.isChecked()==true)   
                    data[position].setCheck(true);  
                else  
                    data[position].setCheck(false);  
            }  
        });
    }
    else{
        viewHolder = (ViewHolder) convertView.getTag();
    }

    viewHolder.nameText.setText(data[position].getName());
    viewHolder.surnameText.setText(data[position].getSurname());
    viewHolder.contactImage.setImageResource(data[position].getPhotoRes());
    viewHolder.contactImage.setScaleType(ScaleType.FIT_XY);
    viewHolder.checkBox.setChecked(data[position].isCheck());
    return convertView;
}

解決済み:私はこのコードで getView の問題を解決しました:

    public class NewQAAdapterSelectFriends extends BaseAdapter {
private LayoutInflater mInflater;
private Person[] data;
boolean[] checkBoxState;
ViewHolder viewHolder;

public NewQAAdapterSelectFriends(Context context) { 
    mInflater = LayoutInflater.from(context);
}


public void setData(Person[] data) {
    this.data = data;
    checkBoxState=new boolean[data.length];
}

@Override
public int getCount() {
    return data.length;
}

@Override
public Object getItem(int item) {
    return data[item];
}

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



@Override
public View getView(final int position, View convertView, ViewGroup parent) {
    if (convertView == null) {
        convertView = mInflater.inflate(R.layout.item_select_friends, null);
        viewHolder=new ViewHolder();

        viewHolder.nameText=(TextView) convertView.findViewById(R.id.personName);
        viewHolder.surnameText=(TextView) convertView.findViewById(R.id.personSurname);
        viewHolder.contactImage=(ImageView) convertView.findViewById(R.id.personImage);
        viewHolder.checkBox=(CheckBox)convertView.findViewById(R.id.checkBox);

        convertView.setTag(viewHolder);

    }
    else{
        viewHolder = (ViewHolder) convertView.getTag();
    }

    viewHolder.nameText.setText(data[position].getName());
    viewHolder.surnameText.setText(data[position].getSurname());
    viewHolder.contactImage.setImageResource(data[position].getPhotoRes());
    viewHolder.contactImage.setScaleType(ScaleType.FIT_XY);
    viewHolder.checkBox.setChecked(checkBoxState[position]);
    viewHolder.checkBox.setOnClickListener(new View.OnClickListener() {

           public void onClick(View v) {
               if(((CheckBox)v).isChecked()){
                   checkBoxState[position]=true;
                   data[position].setCheck(true);
               }else{
                   checkBoxState[position]=false;
                   data[position].setCheck(false);
               }
            }
        });
    return convertView;
}


static class ViewHolder {
    TextView nameText;
    TextView surnameText;
    ImageView contactImage;
    CheckBox checkBox;
}

}

getView を実行するためのこのチュートリアルを見ました: http://androidcocktail.blogspot.it/2012/04/adding-checkboxes-to-custom-listview-in.html

4

3 に答える 3

2

newメソッド内でもクラスを作成するために使用すると、変数に対して別のスコープが作成されます。言い換えると:

// Creating a new scope here -->       vvv
viewHolder.checkBox.setOnClickListener(new OnClickListener() {
    // Any variables not visible to the entire class, won't work properly in here! 
    //  (variables like: viewHolder, position, possibly data) 
    public void onClick(View arg0) {  
        if(viewHolder.checkBox.isChecked()==true)   
            data[position].setCheck(true);  
        else  
            data[position].setCheck(false);  
    }  
}); // Exited "new class'" scope

positionpositionあなたが思っているのと同じではありません。position再度参照できる場所の値を保存してみてください。

viewHolder.checkBox = (CheckBox) convertView.findViewById(R.id.checkBox);
viewHolder.position = position;
convertView.setTag(viewHolder);
...

viewHolder.checkBox.setOnClickListener(new OnClickListener() {  
    public void onClick(View view) {
        ViewHolder viewHolder = (ViewHolder) view.getTag();
        data[viewHolder.position].setCheck(viewHolder.checkBox.isChecked());   
    }  
}); 

あなたは CheckBox を扱っているので、OnCheckedChangeListenerを使用することをお勧めします。

ただし、 ChoiceModeを変更すると、 ListView 行のリスナーを定義する必要がない場合があります。

listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
于 2012-07-05T20:39:55.223 に答える
0

またはのviewHolder.checkBox.setChecked(checkBoxState[position]);後にも追加します。viewHolder.checkBox.setOnCheckedChangedListenerviewHolder.checkBox.setOnClickListener

スクロール後、リストビューがそのビューをリサイクルするsetCheckedと、古いリスナーに基づいて使用されるため、場合によっては値が失われる可能性があります。

ここに流れがあります -

getView()
---
---
---
viewHolder.checkBox.setOnCheckedChangedListener()
---
---
---
viewHolder.checkBox.setChecked()
于 2015-01-20T09:10:41.687 に答える