2015-02-12 2 views
0

У меня есть listview с пользовательским адаптером с кнопкой переключения, прядильщиком и некоторыми другими видами в нем.Пользовательский адаптер Android Listview 1 вызывает несколько выборов

В этом списке показано больше предметов, чем обычно может быть на 1 экране, и это вызывает странную проблему, которую я не понимаю.

Например: Когда я нажимаю кнопку переключения первого элемента в списке, фон меняет цвет. Если я затем прокручу вниз до «второго экрана» (пункты 10-18), я заметил, что 11-й элемент также был «переключен», поскольку фон также изменился. Если я затем прокручу вниз еще дальше вниз до 20-го пункта, также был выбран.

Мой адаптер выглядит следующим образом:

public class ArticlesListAdapter extends ArrayAdapter<Line> { 

private List<Line> lineList; 
private Context context; 

public ArticlesListAdapter(Context context, int textViewResourceId, 
     List<Line> objects) { 
    super(context, textViewResourceId, objects); 
    this.lineList = objects; 
    this.context = context; 
} 

public int getCount() { 
    return lineList.size(); 
} 

public Line getItem(int position) { 
    return lineList.get(position); 
} 

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

public List<Line> GetAllLines() { 
    return lineList; 

} 

@SuppressLint("InflateParams") 
public View getView(int position, View convertView, ViewGroup parent) { 

    Viewholder viewholder; 

    if (convertView == null) { 
     viewholder = new Viewholder(); 
     convertView = LayoutInflater.from(context).inflate(
       R.layout.articles_list_row, null); 

     viewholder.articleName = (TextView) convertView 
       .findViewById(R.id.textArticleName); 
     viewholder.articleAmount = (EditText) convertView 
       .findViewById(R.id.textArticleAmount); 
     viewholder.articleButton = (ToggleButton) convertView 
       .findViewById(R.id.toggleArticleReturn); 
     viewholder.articleStock = (Spinner) convertView 
       .findViewById(R.id.spinStockWarehouse); 

     convertView.setTag(viewholder); 
    } else { 
     viewholder = (Viewholder) convertView.getTag(); 
    } 

    viewholder.articleButton.setTag(position); 

    if (lineList.get(position).getLineCode().length() > 0) { 
     viewholder.articleButton.setOnClickListener(RetourArticleListener); 
     viewholder.articleButton.setOnLongClickListener(RetourCertainAmountArticleListener); 
    } else { 
     viewholder.articleButton.setText("Delete"); 
     viewholder.articleButton.setOnClickListener(DeleteArticleListener); 
    } 

    String articleNameString = lineList.get(position) 
      .getLineArticleDescription(); 
    if (articleNameString.length() > 30) { 
     articleNameString.substring(0, 30); 
    } 
    viewholder.articleName.setText(articleNameString); 
    viewholder.articleName.setTextSize(12); 

    viewholder.articleAmount.setTag(position); 
    viewholder.articleAmount.setTextSize(12); 
    viewholder.articleAmount.setText(lineList.get(position) 
      .getLineArticleAmount().toString()); 

    if (lineList.get(position).isLineArticleIsOriginal()) { 
     viewholder.articleStock.setEnabled(false); 
    } 
    viewholder.articleStock.setSelection(Integer.parseInt(lineList 
      .get(position).getLineArticleStock().toString()) - 1); 
    viewholder.articleStock.setTag(position); 
    viewholder.articleStock 
      .setOnItemSelectedListener(new OnItemSelectedListener() { 

       @Override 
       public void onItemSelected(AdapterView<?> adapterView, 
         View view, int position, long id) { 
        final int listPosition = (Integer) adapterView.getTag(); 
        lineList.get(listPosition).setLineArticleStock(
          String.valueOf(position + 1)); 
       } 

       @Override 
       public void onNothingSelected(AdapterView<?> adapter) { 
       } 
      }); 

    // we need to update adapter once we finish with editing 
    viewholder.articleAmount 
      .setOnFocusChangeListener(new OnFocusChangeListener() { 
       public void onFocusChange(View v, boolean hasFocus) { 
        if (!hasFocus) { 
         final int position = (Integer) v.getTag(); 
         final EditText articleAmount = (EditText) v; 
         lineList.get(position).setLineArticleAmount(
           Double.parseDouble(articleAmount.getText() 
             .toString().replace(",", "."))); 
        } 
       } 
      }); 

    return convertView; 
} 

private OnClickListener RetourArticleListener = new OnClickListener() { 

    @Override 
    public void onClick(View v) { 
     boolean on = ((ToggleButton) v).isChecked(); 
     int position = (Integer) v.getTag(); 
     RelativeLayout rl = (RelativeLayout) v.getParent(); 
     if (on) { 
      // Article returned 
      rl.setBackgroundColor(Color.RED); 
      lineList.get(position).setLineArticleReturned(true); 
     } else { 
      // Article used 
      rl.setBackgroundColor(Color.WHITE); 
      lineList.get(position).setLineArticleReturned(false); 
     } 

    } 
}; 
} 
+0

Как вы перечисляете в вашем ListView, взгляды, которые выходят из поля зрения повторно используются, следовательно, ваш 11-й вид имеет тот же цвет фона, как первый –

+0

@FrankD. Есть ли способ противостоять этому? – Hetiwos

+0

Вы можете создать список (Array), содержащий логические значения (например, «differentColor = true»), которые соответствуют состоянию элементов в вашем линкевисте. Таким образом, для каждой позиции в линейте, вы можете проверить, должен ли элемент иметь другой цвет фона. В вашем методе getView используйте позицию, чтобы проверить свой список логических элементов и задайте цвет фона для этого элемента соответственно. –

ответ

2

Проблема, как указывает Alex.F, - это поведение в режиме рециркуляции ListView. Решение довольно просто:

У вас в позиции Line уже есть логическое значение, соответствующее состоянию цвета, которое мы будем использовать.

В вашем RetourArticleListener измените если-то еще заявление:

if (on) { 
    // Article returned 
    lineList.get(position).setLineArticleReturned(true); 
    notifyDatasetChanged(); 
} else { 
    // Article used 
    lineList.get(position).setLineArticleReturned(false); 
    notifyDatasetChanged(); 
} 

Метод notifyDatasetChanged сделает метод, что ваш GetView() называется.

В вашем методе getView() проверьте значение «LineArticleReturned» и соответствующим образом измените цвет фона. Добавьте это где-нибудь в конце вашего метода getView, чтобы вы были уверены, что все необходимые переменные будут инициализированы к тому моменту. Я предполагаю, что у вас есть метод, называемый getLineArticleReturned(), который возвращает логическое значение LineArticleReturned в вашем классе Line.

if(lineList.get(position).getLineArticleReturned()==true){ 
    RelativeLayout rl = (RelativeLayout)   
    convertView.findViewById(R.id.name_of_your_relative_layout_here); 
    rl.setBackgroundColor(Color.RED); 

}else{ 
    rl.setBackgroundColor(Color.WHITE); 
} 
1

Это явный случай выпуска с механизмом рециркуляции ListView в. Вы должны прочитать об этом, например, в this SO Q&A

+0

И когда я говорю о проблеме, я не имею в виду, что с ней что-то не так, а вам нужно написать свой код соответственно :) –

Смежные вопросы