2012-07-05 44 views
3


我有什么:用Textviews和复选框的自定义列表视图。
问题:如果我检查屏幕上显示的初始项目,然后查找列表,当我返回列表顶部(向上滚动)时,它们的值将被正确保存。但是,如果我滚动列表,例如我想检查我的列表中的最后一棵树复选框,然后如果我上下滚动,他们变得没有检查....为什么?????? **
我见过各种解决方案在其他论坛同样的问题,也在这里在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

回答

1

当您使用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 

position是不一样的position,你认为它是。请尝试保存的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()); 
    } 
}); 

既然你正在处理一个复选框,虽然我会建议使用OnCheckedChangeListener

但是,如果你改变了ChoiceMode你可能不需要定义任何听众为ListView行:

listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); 
+0

嗨,感谢的答案。我改变了我的代码,如你所建议的,但现在当我点击一个复选框,我有一个NullPointerException行数据[viewHolder.position] .setCheck(viewHolder.checkBox.isChecked());为什么??? – 2012-07-05 21:33:11

+0

使用你的调试器或logcat语句来确认'viewHolder'不是null,有'position',有CheckBox和data [viewHolder.position]也是有效的。但我认为我看到我疯了,试试这个:'ViewHolder viewHolder =(ViewHolder)((View)view.getParent())。getTag();;' – Sam 2012-07-05 23:01:47

+0

Sam,我改变我的代码, Log.i(String,String)我已经看到,当我点击复选框时,viewHolder.position是正确的(我的dislapy可以显示8个项目,所以viewHolder.position有一个范围在0,1,2,3。 .7和下一个元素重新启动为0,1,..(用于回收)。使用日志我检查数据[viewHolder.position] .getNamePerson()也适用于每个元素。firts 8个元素(0,1 ,2..7)在列表顶部起作用(当我滚动时,它们的复选框状态被保存)。在第一个8之后的下一个元素仍然存在问题,他们从不保持它们的值 – 2012-07-06 08:08:14

0

而且viewHolder.checkBox.setOnCheckedChangedListenerviewHolder.checkBox.setOnClickListener之后添加viewHolder.checkBox.setChecked(checkBoxState[position]);

因为滚动后,当listview回收它的视图时,它将使用setChecked基于旧的侦听器,这可能在某些情况下松散值。

所以这里是流 -

getView() 
--- 
--- 
--- 
viewHolder.checkBox.setOnCheckedChangedListener() 
--- 
--- 
--- 
viewHolder.checkBox.setChecked() 
0
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> 
{ 
    boolean[] checkBoxState; 


    public MyAdapter(Context context, ArrayList<String> list) { 
     checkBoxState = new boolean[list.size()]; 
    } 

    @Override 
    public void onBindViewHolder(final ViewHolder holder, final int position) { 
     holder.checkBox.setTag(position); 

      holder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener(){ 
       @Override 
       public void onCheckedChanged(CompoundButton compoundButton, boolean b) { 
        if(compoundButton.isPressed()) // check whether user pressed the checkbox. 
        { 
         int getPosition = (Integer) compoundButton.getTag(); // Here we get the position that we have set for the checkbox using setTag. 
         checkBoxState[getPosition] = compoundButton.isChecked(); // Set the value of checkbox to maintain its state. 
        } 
       } 
      }); 

      holder.checkBox.setChecked(checkBoxState[position]); 
    } 

    public class ViewHolder extends RecyclerView.ViewHolder { 
     public CheckBox checkBox; 
     public ViewHolder(View v,MainActivity mainActivity) { 
      super(v); 
      checkBox= (CheckBox) v.findViewById(R.id.checkBox); 
     } 
    } 

    @Override 
    public int getItemCount() { 
     return list.size(); 
    } 
} 

滚动时,onCheckedChanged()方法可以被自动调用。因此,您可能需要使用isPressed()方法来检查用户是否按下了复选框。我的适配器类如上所示。请注意,当你添加新的元素到列表中,那么当您一个元素添加到列表中,你应该调用下面的更新您的布尔数组checkBoxState,例如:

checkBoxState = new boolean[list.size()+1]; 

或使用ArrayList举行布尔变量并添加元素到这个数组列表中,无论你想要什么。

我也为此解决方案实施了一个项目。你可以从这里下载: https://www.dropbox.com/s/ssm58w62gw32i29/recyclerView_checkbox_highlight.zip?dl=0

截图低于:

screen1 screen2 screen3 screen4

+0

问题是关于'ListView'类,而不是'RecyclerView' – crgarridos 2017-10-10 22:57:54

+0

同样的问题也在recyclerView中发生。通过为listView实现一个自定义适配器类,可以为listView执行相同的解决方案。 – oiyio 2017-10-11 07:36:32