2013-07-22 2 views
2

У меня есть список с флажком. Я нажимаю на конкретный элемент, соответствующий флажок выбирается, но он также выбирает флажки повторно после каждых 8-10 строк в списке. Я понимаю, что это происходит, потому что в андроиде для оптимизации памяти хранятся представления только для видимого экрана. Но я не смог преодолеть эту ситуацию. Pls предлагает.Выбор определенного флажка в длинном списке показывает несколько флажков

public class FBFriendsListAdaptor extends ArrayAdapter<FBFriendItem>{ 
    private final Context context; 
    private static List<FBFriendItem> items; 
    private SparseArray<FBFriendItem> checkedItems = new SparseArray<FBFriendItem>(); 
    ViewHolder holder; 

    public FBFriendsListAdaptor(Context context, List<FBFriendItem> items) { 
     super(context, R.layout.fb_friend_list, items); 
     this.items = items; 
     this.context = context; 
    } 

    @Override 
    public FBFriendItem getItem(int position) { 
     // TODO Auto-generated method stub 
     return items.get(position); 
    } 

    public View getView(final int position, View convertView, ViewGroup parent) { 

     View v = convertView; 

     if (v == null) { 
      LayoutInflater vi = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
      v = vi.inflate(R.layout.fb_friend_list, parent, false); 
     } 

     holder = new ViewHolder(); 
     holder.selectFriendCB = (CheckBox)v.findViewById(R.id.selectFriendCB); 
     v.setTag(holder); 

     v.setOnClickListener(new View.OnClickListener(){ 
      public void onClick(View v) { 
       if (checkedItems.get(position) != null){ 
        checkedItems.remove(position); 
        holder.selectFriendCB.setChecked(false); 
       } 
       else { 
        checkedItems.put(position, items.get(position)); 
        holder.selectFriendCB.setChecked(true); 
       } 
      } 
     }); 

     FBFriendItem item = items.get(position); 
     TextView firstNameTV = (TextView) v.findViewById(R.id.firstNameTV); 
     TextView lastNameTV = (TextView) v.findViewById(R.id.lastNameTV); 
     ImageView picIV = (ImageView) v.findViewById(R.id.picIV); 
     if (!item.getFbId().isEmpty()) { 
      firstNameTV.setText(" " + item.getFirstName()); 
      lastNameTV.setText(" " + item.getLastName()); 
      Bitmap image = item.getImage(); 
      if(image != null) { 
       picIV.setImageBitmap(image); 
      } 
     } 

     return v; 
    } 

    public SparseArray<FBFriendItem> getCheckedItems(){ 
     return checkedItems; 
    } 

    static class ViewHolder { 
     CheckBox selectFriendCB;   
    } 
} 

ответ

1

Первое, что я заметил, это

 if (!item.getFbId().isEmpty()) { 
     firstNameTV.setText(" " + item.getFirstName()); 
     lastNameTV.setText(" " + item.getLastName()); 
     Bitmap image = item.getImage(); 
     if(image != null) { 
      picIV.setImageBitmap(image); 
     } 
    } 

Установка этих значений только в некоторых случаях не является большой нет-нет. Помните, что ваши представления повторно используются, поэтому, если вы когда-либо устанавливаете какие-либо из этих свойств, вы не можете рассчитывать на то, что они когда-либо имеют значение по умолчанию. Они могут быть установлены из последнего элемента. Попробуйте логику, которая выглядит примерно так:

 if (!item.getFbId().isEmpty()) { 
     firstNameTV.setText(" " + item.getFirstName()); 
     lastNameTV.setText(" " + item.getLastName()); 
     Bitmap image = item.getImage(); 
     if(image == null) { 
      // reset the default because this view might have last displayed an 
      // item with a non-default value 
      picIV.setImageBitmap(myDefaultImage); 
     } else { 
      picIV.setImageBitmap(image); 
     } 
    } else { 
     // reset the defaults because this view might have last displayed an 
     // item with a non-default value 
     firstNameTV.setText(null); 
     lastNameTV.setText(null); 
     picIV.setImageBitmap(myDefaultImage); 
    } 

Следующее, что я заметил, это то, что ваше управление проверенными предметами является совершенно неправильным. Независимо от того, проверен элемент или нет, это состояние, которое должно управляться ListView, а не вашим адаптером. Я не знаю, какого взгляда вы пытаетесь достичь, поэтому я не буду точно указывать, как выложить ваши предметы, но вы хотите, вероятно, начать с удаления элементов CheckBox и посмотреть на ListView.setChoiceMode(). http://developer.android.com/reference/android/widget/AbsListView.html#setChoiceMode%28int%29

+0

Спасибо за ваш ответ. Но главный вопрос заключается в том, когда я выбираю флажок в listview, его выбирает несколько записей, даже если я удалю код для установки имени и фамилии выше. например в списке есть 100 элементов, и я проверяю второй элемент, делая это автоматически, проверяя все 13, 24, 35 пунктов соответственно. Я хочу избежать этого сценария. Даже если я добавлю onItemClickListener в listview, сценарий все еще существует. Прокомментируйте это. – funambulist

+0

Как я уже упоминал, все ваше управление проверкой неверно. Это никогда не будет работать так, как вы пытаетесь это сделать. Вам нужно удалить виджеты 'CheckBox' и использовать' ListView.setChoiceMode() '. –

0

Так оно и было. Я добавил «boolean selected = false» в класс FBFriendItem. Ниже представлен код внутри массива getView():

public View getView(final int position, View convertView, ViewGroup parent) { 

    ViewHolder holder = null; 

    View v = convertView; 
    if (v == null) { 
     LayoutInflater vi = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     v = vi.inflate(R.layout.fb_friend_list, null); 
     holder = new ViewHolder(); 
     holder.picIV = (ImageView)v.findViewById(R.id.picIV); 
     holder.firstNameTV = (TextView)v.findViewById(R.id.firstNameTV); 
     holder.lastNameTV = (TextView)v.findViewById(R.id.lastNameTV); 
     holder.selectFriendCB = (CheckBox)v.findViewById(R.id.selectFriendCB); 
     v.setTag(holder); 
     holder.selectFriendCB.setOnClickListener(new View.OnClickListener(){ 
      public void onClick(View v) { 
       CheckBox cb = (CheckBox)v; 
       FBFriendItem item = (FBFriendItem)cb.getTag(); 
       item.setSelected(cb.isChecked()); 
      } 
     }); 
    } 
    else { 
     holder = (ViewHolder)v.getTag(); 
    } 

    FBFriendItem item = items.get(position); 
    holder.picIV.setImageBitmap(item.getImageBitmap()); 
    holder.firstNameTV.setText(item.getFirstName()); 
    holder.lastNameTV.setText(item.getLastName()); 
    holder.selectFriendCB.setChecked(item.isSelected()); 
    holder.selectFriendCB.setTag(item); 

    return v; 
} 

private class ViewHolder { 
    ImageView picIV; 
    TextView firstNameTV; 
    TextView lastNameTV; 
    CheckBox selectFriendCB;   
} 
Смежные вопросы