2

В настоящее время я добавляю TextViews внутри LinearLayout внутри элемента ListView, используя цикл for, потому что количество текстовых элементов, которые я должен добавить, есть переменная. Я добавляю элементы в список, как обычно. Проблема в том, что когда я прокручиваю элементы, становлюсь все больше и больше, и когда я прокручиваю резервные копии, я получаю сотни предметов. Я думаю, это потому, что ListView перезагружается и циклически перемещается по циклу for еще раз и поэтому добавляет каждый TextView несколько раз. Могу ли я остановить это?Android ListView добавляет слишком много элементов

Мой код:

public class ListViewAdapter extends ArrayAdapter<RowItem> { 

    private final Context context; 

    public ListViewAdapter(Context context, List<RowItem> items) { 
     super(context, R.layout.list, items); 
     this.context = context; 
    } 

    private class ViewHolder { 
     TextView title; 
     LinearLayout linearLayout; 
    } 

    public View getView(int position, View convertView, ViewGroup parent) { 
     ViewHolder holder; 
     RowItem rowItem = getItem(position); 

     LayoutInflater mInflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE); 

     if (convertView == null) { 
      convertView = mInflater.inflate(R.layout.list_list, null); 
      holder = new ViewHolder(); 
      holder.title = (TextView) convertView.findViewById(R.id.list_line); 
      holder.linearLayout = (LinearLayout) convertView.findViewById(R.id.list_linear); 
      convertView.setTag(holder); 
     } else { 
      holder = (ViewHolder) convertView.getTag(); 
     } 

     holder.title.setText(rowItem.getTitle()); 

      String data = rowItem.getData(); 
      String[] split0 = data.split("="); 

      Log.e("DATA", data); 
      Log.e("LINE", rowItem.getTitle()); 

      for (int j = 0; j < split0.length; j++) { 
       String[] split1 = split0[j].split(":"); 

       LinearLayout parentLayout = new LinearLayout(MainActivity.context); 
       parentLayout.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)); 
       parentLayout.setOrientation(LinearLayout.HORIZONTAL); 

       for (int k = 0; k < split1.length; k++) { 
        TextView textView = new TextView(MainActivity.context); 
        textView.setText(split1[k]); 
        textView.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT, 1.0f)); 
        textView.setGravity(Gravity.CENTER_HORIZONTAL | Gravity.CENTER_VERTICAL); 
        textView.setTextSize(18); 

        parentLayout.addView(textView); 
       } 
       holder.linearLayout.addView(parentLayout); 
     } 

     return convertView; 
    } 
} 

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

text1:text2=text3:text4 

Как это будет выглядеть в списке:

text1 text2 
text3 text4 
+1

использование стан dard viewHolder и удалите allViews LinearLayout, прежде чем запускать код добавления ur view, используя viewGroup.removeAllViews() –

+0

Можете ли вы дать мне какой-нибудь пример кода, как бы я это сделал? – Broadwell

+0

напишите свой код. Было бы более полезно дать предложение. – dora

ответ

3

Проблема в том, что ArrayAdapter будет вызывать getView() каждый раз, когда строка становится видимой. Если строка была настроена ранее, она будет проходить в ранее установленном представлении в параметре convertView.

Для получения более подробной информации см. here. От the documentation за convertView:

Старый вид повторного использования, если возможно. Примечание. Вы должны проверить, что это вид не имеет значения null и соответствующего типа перед использованием. Если это не , возможно преобразовать это представление, чтобы отобразить правильные данные, этот метод может создать новый вид. Гетерогенные списки могут указывать их количество типов видений , поэтому этот вид всегда имеет нужный тип (см. getViewTypeCount() и getItemViewType (int)).

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

Вы могли бы быть в состоянии сделать что-то, что немного оптимизирована, где вы не должны называть inflate() на каждом getView() вызова, но все-таки вновь создать ViewHolder каждый раз getView() называется, для того, чтобы заполнить правильные данные при прокрутке:

public View getView(int position, View convertView, ViewGroup parent) { 
    ViewHolder holder; 
    RowItem rowItem = getItem(position); 

    LayoutInflater mInflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE); 

    if (convertView == null) { 
     convertView = mInflater.inflate(R.layout.list_list, null); 

    } 

    holder = new ViewHolder(); 
    holder.title = (TextView) convertView.findViewById(R.id.list_line); 
    holder.linearLayout = (LinearLayout) convertView.findViewById(R.id.list_linear); 
    convertView.setTag(holder); 


    holder.title.setText(rowItem.getTitle()); 

     String data = rowItem.getData(); 
     String[] split0 = data.split("="); 

     Log.e("DATA", data); 
     Log.e("LINE", rowItem.getTitle()); 

     for (int j = 0; j < split0.length; j++) { 
      String[] split1 = split0[j].split(":"); 

      LinearLayout parentLayout = new LinearLayout(MainActivity.context); 
      parentLayout.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)); 
      parentLayout.setOrientation(LinearLayout.HORIZONTAL); 

      for (int k = 0; k < split1.length; k++) { 
       TextView textView = new TextView(MainActivity.context); 
       textView.setText(split1[k]); 
       textView.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT, 1.0f)); 
       textView.setGravity(Gravity.CENTER_HORIZONTAL | Gravity.CENTER_VERTICAL); 
       textView.setTextSize(18); 

       parentLayout.addView(textView); 
      } 
      holder.linearLayout.addView(parentLayout); 
     } 


    return convertView; 
} 

Если это не работает, вы можете просто вернуться к основам, а просто полностью воссоздать вид на каждом вызове getView():

public View getView(int position, View convertView, ViewGroup parent) { 
     ViewHolder holder; 
     RowItem rowItem = getItem(position); 

     LayoutInflater mInflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE); 

     //if (convertView == null) { 
      convertView = mInflater.inflate(R.layout.list_list, null); 
      holder = new ViewHolder(); 
      holder.title = (TextView) convertView.findViewById(R.id.list_line); 
      holder.linearLayout = (LinearLayout) convertView.findViewById(R.id.list_linear); 
      convertView.setTag(holder); 

      holder.title.setText(rowItem.getTitle()); 

      String data = rowItem.getData(); 
      String[] split0 = data.split("="); 

      Log.e("DATA", data); 
      Log.e("LINE", rowItem.getTitle()); 

      for (int j = 0; j < split0.length; j++) { 
       String[] split1 = split0[j].split(":"); 

       LinearLayout parentLayout = new LinearLayout(MainActivity.context); 
       parentLayout.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)); 
       parentLayout.setOrientation(LinearLayout.HORIZONTAL); 

       for (int k = 0; k < split1.length; k++) { 
        TextView textView = new TextView(MainActivity.context); 
        textView.setText(split1[k]); 
        textView.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT, 1.0f)); 
        textView.setGravity(Gravity.CENTER_HORIZONTAL | Gravity.CENTER_VERTICAL); 
        textView.setTextSize(18); 

        parentLayout.addView(textView); 
       } 
       holder.linearLayout.addView(parentLayout); 
      }  

     //} 

     return convertView; 
    } 
+0

@Broadwell Конечно, никаких проблем! –

+0

Итак, теперь у меня есть проблема, что он не отображает все мои данные. Предположим, что у меня есть 10 записей для отображения в списке, он берет только данные первых 4 и отображает их снова и снова, пока не отобразится все 10 записей. Однако заголовки отображаются нормально.В основном он отображает первые 4 записи снова и снова, вместо одного из каждого из 10 – Broadwell

+0

@Broadwell. Это странно. Похоже, что это может быть проблемой с вашим источником данных, независимо от того, что вы передадите в «Список элементов» этого адаптера. Попробуйте проверить, что список содержит то, что вы ожидаете. Если вы не можете разобраться, задайте новый вопрос, и я посмотрю! –

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