2015-09-18 3 views
-2

Я хотел сделать общий ListAdapter, где вместо вставки предопределенных структур вида вы можете добавлять разные представления в каждый элемент списка.ListAdapter неправильно работает на прокрутке Android

У меня есть мой ListAdapter:

public class ListAdapter extends BaseAdapter {  
    private HashMap<Integer, Integer> listDataTypes; //For each element of the list, defines if its an ítem or a separator 
    private List<View> listData; 
    private static final int TYPE_ITEM = 0; 
    private static final int TYPE_SEPARATOR = 1; 

    public ListAdapter() { 
     listDataTypes = new HashMap<Integer, Integer>(); 
     listData = new ArrayList<>(); 
    } 

    public void addItem(final View item) { 
     listDataTypes.put(listData.size(), TYPE_ITEM); 
     listData.add(item); 
     notifyDataSetChanged(); 
    } 

    public void addSeparator(final View item) { 
     listDataTypes.put(listData.size(), TYPE_SEPARATOR); 
     listData.add(item); 
     notifyDataSetChanged(); 
    } 

    @Override 
    public int getViewTypeCount() { 
     return 2; 
    } 

    @Override 
    public int getCount() { 
     return listData.size(); 
    } 

    @Override 
    public int getItemViewType(int position) { 
     return listDataTypes.get(position); 
    } 

    @Override 
    public View getItem(int position) { 
     return listData.get(position); 
    } 

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

    public View getView(int position, View convertView, ViewGroup parent) { 
     if (convertView == null) { 
      View itemView = listData.get(position); 
      convertView = itemView; 
     } 

     return convertView; 
    } 
} 

Вот пример list_item.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content"> 

    <RelativeLayout 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:layout_margin="8dp"> 

    <TextView 
     android:layout_width="0dp" 
     android:layout_height="wrap_content" 
     android:id="@+id/tvInfo1" 
     android:layout_alignParentLeft="true" 
     android:layout_alignParentStart="true" 
     android:layout_centerVertical="true"/> 

    <TextView 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:id="@+id/tvInfo2" 
     android:layout_toLeftOf="@+id/tvInfo3" 
     android:layout_toStartOf="@+id/tvInfo3" 
     android:layout_toEndOf="@id/tvInfo1" 
     android:layout_toRightOf="@id/tvInfo1" 
     android:layout_centerVertical="true"/> 

    <TextView 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_alignParentRight="true" 
     android:layout_alignParentEnd="true" 
     android:layout_marginLeft="8dp" 
     android:layout_marginStart="8dp" 
     android:id="@+id/tvInfo3" 
     android:layout_centerVertical="true"/> 
</RelativeLayout> 
</LinearLayout> 

И как я использую адаптер список:

protected void onCreate(Bundle savedInstanceState) { 
    ... 
    ListAdapter listAdapter = new ListAdapter(); 

    TextView tvHeader = new TextView(this); 
    tvHeader.setText("I am a header"); 

    listAdapter.addSeparator(tvHeader); 

    for(int i=0; i<50; i++){ 
     View itemView = layoutInflater.inflate(R.layout.layout_two_items_list_item, null); 
     TextView tvInfo1= (TextView) itemView .findViewById(R.id.tvInfo1); 
     TextView tvInfo2= (TextView) itemView .findViewById(R.id.tvInfo2); 
     TextView tvInfo3= (TextView) itemView .findViewById(R.id.tvInfo3); 
     tvInfo1.setText("Id " + i); 
     tvInfo2.setText("Info " + i); 
     tvInfo3.setText("Hour " + i); 
     listAdapter.addItem(itemView); 
    } 

    ListView listView = (ListView)findViewById(R.id.listview); 
    listView.setAdapter(listAdapter); 
    listView.setSelector(android.R.color.transparent); 
} 

Но по какой-то причине, когда я просматриваю список, некоторые элементы начинают плавать, другие не отображаются, другие - rep другие места изменений и т. д. Что я делаю неправильно?

Это как показано на рисунке (неверно) enter image description here

ответ

1

Это очень плохая практика, что вы делаете. Сохранение массива представлений в памяти. Вся цель списка, чтобы минимизировать это. Для того, чтобы избежать повторения заменить

if (convertView == null) { 
      View itemView = listData.get(position); 
      convertView = itemView; 
     } 

return convertView; 

с

return listData.get(position); 

Но если вы были, я бы серьезно рассмотреть вопрос о перезаписи, как вы делаете ваш ListView.

+0

Я вижу. Я хотел создать общий список, поэтому у меня нет одного класса для каждого типа элемента списка, который я хочу использовать внутри своего приложения. Что делать, если я сохраню массив представлений в базе данных телефона вместо сохранения их в памяти? Или это приведет к замедлению загрузки списка? –

+1

Я думаю, что чтение и запись в базу данных - огромная потеря производительности. Лучший способ - использовать шаблон ViewHolder, а также не раздувать все взгляды за один раз. Надеюсь, это поможет. Для сравнения я бы предложил вам сделать большой список изображений и попробовать оба метода и сравнить результаты :) – hoomi

0

Изменить getView на что-то вроде:

public View getView(int position, View convertView, ViewGroup parent) { 
    View itemView = listData.get(position); 
    return itemView; 
} 

Я подозреваю, что вы повторно использовать старые взгляды, когда вы действительно не хотите быть.