2016-08-10 5 views
0

Я пытаюсь изменить фон определенного элемента в представлении списка под названием «Разный элемент». Когда я просматриваю список, все фоны элементов верны. Когда я дойду до конца списка (где «Разный элемент» есть) и прокрутите резервную копию, есть некоторые случайные элементы, которые получают тот же фон, что и «Разный элемент». Я считаю, что это связано с тем, что я использую шаблон держателя представления, и тот факт, что андроид перерабатывает каждую точку зрения, чтобы использовать ее снова, но я не совсем понимаю эту проблему и как ее решить. Вот мой MainActivity.javaФон списка ListView перемещается при прокрутке спискаView

import android.support.v7.app.AppCompatActivity; 
import android.os.Bundle; 
import android.widget.ListView; 

public class MainActivity extends AppCompatActivity { 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     final ListView listView = (ListView)findViewById(R.id.list_view); 
     listView.setAdapter(new CustomAdapter(this)); 
    } 
} 

Вот мой CustomAdapter.java класс

import android.content.Context; 
import android.graphics.Color; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.BaseAdapter; 
import android.widget.TextView; 

import java.util.ArrayList; 
import java.util.List; 

public class CustomAdapter extends BaseAdapter { 

    private Context mContext; 
    private List<String> mItems; 

    public CustomAdapter(Context context) { 
     mContext = context; 
     mItems = new ArrayList<>(); 
     for (int i = 0; i < 20; i++) { 
      mItems.add("Item " + i); 
     } 
     mItems.add("Different Item"); 
    } 

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

    @Override 
    public Object getItem(int i) { 
     return mItems.get(i); 
    } 

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

    @Override 
    public View getView(int position, View convertView, ViewGroup viewGroup) { 
     View view; 
     ViewHolder viewHolder; 
     TextView textView; 

     if (convertView == null) { 
      LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(
        Context.LAYOUT_INFLATER_SERVICE); 
      view = inflater.inflate(R.layout.list_item_template, viewGroup, false); 
     } else { 
      view = convertView; 
     } 

     if (view.getTag() == null) { 
      textView = (TextView)view.findViewById(R.id.items_text_view); 
      viewHolder = new ViewHolder(textView); 
      view.setTag(viewHolder); 
     } 
     else { 
      viewHolder = (ViewHolder)view.getTag(); 
      textView = viewHolder.getTextView(); 
     } 

     textView.setText(mItems.get(position)); 

     if (mItems.get(position).equals("Different Item")) { 
      textView.setBackgroundColor(Color.parseColor("#DDDDDD")); 
     } 

     return view; 
    } 

    private class ViewHolder { 
     private TextView mTextView; 

     public ViewHolder(TextView textView) { 
      this.mTextView = textView; 
     } 

     public TextView getTextView() { 
      return this.mTextView; 
     } 
    } 
} 

Вот мой activity_main.xml

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:padding="16dp"> 

    <ListView 
     android:id="@+id/list_view" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent"></ListView> 
</RelativeLayout> 

и мой литий st_item_template.xml

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
       xmlns:tools="http://schemas.android.com/tools" 
       android:orientation="vertical" 
       android:layout_width="match_parent" 
       android:layout_height="match_parent"> 
    <TextView 
     android:id="@+id/items_text_view" 
     android:textSize="20sp" 
     android:padding="20dp" 
     tools:text="test text" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content"/> 

</LinearLayout> 

и скриншоты проблемы: Сначала, когда я пролистать список, все выглядит отлично:

at first, it looks good

После прокрутки списка просмотра вверх и вниз, просмотров перепутать:

after scrolling it gets mixed up

+1

Просто попробуйте использовать [RecyclerView] (https://developer.android.com/training/material/lists-cards.html). Это более эффективно, чем 'ListView' –

+0

@GaryJohnson True, но мне интересно узнать об этой проблеме, можете ли вы объяснить это мне? –

ответ

3

после т его раздел:

if (mItems.get(position).equals("Different Item")) { 
      textView.setBackgroundColor(Color.parseColor("#DDDDDD")); 
     } 

вы должны иметь еще так:

else 
    textView.setBackgroundColor(Color.parseColor("#FFFFFF")); 

это решит вашу проблему.

+0

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

1

Ваша интуиция верна.

Когда вы устанавливаете фон в режиме «Разный элемент», в какой-то момент этот вид получает рециркуляцию и повторное использование на ListView, когда он отключается от экрана, и он необходим снова адаптером.

Он используется повторно для других предметов, которые не являются «Разным элементом», и если вы не сбросили лишний цвет фона по умолчанию для этих элементов «Item [x]», вы столкнетесь с этой проблемой с несогласованные фоны.

Кроме того, заявление else в этом контексте имеет ноль Влияние на производительность.

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