Android ListFragment индивидуално променя цвета на фона на реда

Имам ListFragment, където искам определени редове да са с определен цвят. По принцип следвах това: Създаване на ListView и задаване на цвета на фона на изглед във всеки ред

GetView обаче никога не се извиква. Някой знае ли защо?

    public class TrackerFragment extends ListFragment
{   
    private String[] list;
    @Override
    public void onActivityCreated(Bundle myBundle)
    {
        super.onActivityCreated(myBundle);

        list = null;
        ListView lv = getListView();
        setListAdapter(null);
        setEmptyText("Touch a connection to view tracker information.");
        lv.setTextFilterEnabled(true);
    }

    public void updateList(String[] list)
    {
        this.list = list;
        setListAdapter(new ColoredArrayAdapter(getActivity(),R.layout.list_item,list));
    }
}

list_item.xml

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:padding="7dp"
    android:textSize="14sp" 
    android:id="@+id/line">
</TextView>

Актуализирам списъка по този начин от моята дейност:

TrackerFragment tf = (TrackerFragment) fragmentManager.findFragmentById(R.id.tracker1);
tf.updateList(result);

Моят ColoredArrayAdapter

public class ColoredArrayAdapter extends ArrayAdapter{

    private String[] list;

    public ColoredArrayAdapter(Context context, int textViewResourceId,
            Object[] objects) {
        super(context, textViewResourceId, objects);
        list = new String[objects.length];
        for (int i = 0; i < list.length; i++)
            list[i] = (String) objects[i];
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent)
{
    View vi = convertView;
    ViewHolder holder;

    if (convertView == null)
    {
        vi = LayoutInflater.from(getContext()).inflate(R.layout.list_item, null);
        holder = new ViewHolder();
        holder.line = (TextView) vi.findViewById(R.id.line);
        vi.setTag(holder);
    }
    else
        holder = (ViewHolder) vi.getTag();

    for (int i = 0; i < list.length; i++)
    {
        if (list[i].contains("OUT OF LOCK"))
        {
            System.out.println("OUT OF LOCK");
            holder.line.setText(list[i]);
            //holder.line.setTextColor(R.color.white);
            holder.line.setBackgroundResource(R.color.red);
        }
        else if(list[i].contains("IN LOCK"))
        {
            System.out.println("In LOCK");
            holder.line.setText(list[i]);
            //holder.line.setTextColor(R.color.white);
            holder.line.setBackgroundResource(R.color.green);
        }
        else
            holder.line.setText(list[i]);
    }

    return vi;
}
}

какво правя грешно Редактиране: добавен list_item.xml, където е намерен ред. Edit2: добавен адаптер за разширен масив

Сега проблемът ми е, че всеки ред е или изцяло зелен, или червен, когато просто искам определени отделни редове да са или червени, или зелени. Освен това нищо от текста не се показва.


person Raptrex    schedule 05.08.2011    source източник
comment
Можете ли да бъдете по-ясни относно това, което причинява NullReferenceException? Това може да помогне да се определи причината за срива. И: Това само на линия OUT OF LOCK ли се случва или също и на линия IN LOCK?   -  person gtcompscientist    schedule 08.08.2011
comment
Това се случва и на двата реда .setBackgroundResource().   -  person Raptrex    schedule 08.08.2011
comment
И holder ИЛИ holder.line преобразува ли се в нула?   -  person gtcompscientist    schedule 08.08.2011
comment
Добре, сега стигаме до някъде. Това означава, че holder.line е коренът на проблема. Сега откъде идва това: - Това става ли, когато се надуват? Ако е така, публикувайте кода, откъдето идва line. - Това случва ли се, когато се използва convertView?   -  person gtcompscientist    schedule 09.08.2011
comment
Добавих xml, където е намерен ред. Да, това се случва, когато се използва convertView.   -  person Raptrex    schedule 09.08.2011


Отговори (3)


Вашата текуща getView реализация трябва да бъде преместена в ListAdapter реализация вместо във вашия TrackerFragment клас. Тъй като използвате ArrayAdapter, можете да го подкласирате и да поставите кода там. ArrayAdapter вече прилага getView, но вие ще го замените, за да предоставите вашето специализирано поведение.

Причината да получавате NullPointerException е, че извиквате getView и предавате изгледа на списъка, който няма етикет, свързан с него -- така че holder = (ViewHolder) vi.getTag(); присвоява null на holder. Въпреки това не трябва да се обаждате директно на getView. Системата ще извика това вместо вас, когато трябва да покаже елемент от списъка. Когато системата извиква метода getView, тя първоначално предава null, за да създаде изгледите, и всяко извикване, при което convertView не е null, е изглед, създаден от този метод.

person blazeroni    schedule 10.08.2011
comment
Благодаря ви, виждам цветни редове, но сега всеки ред се оцветява в зелено или червено и не показва текст. Актуализирах публикацията си - person Raptrex; 10.08.2011
comment
Вместо да преминавате през масива, трябва просто да използвате предадената позиция, т.е. да използвате само list[position] и да зададете фона и текста въз основа на това. - person blazeroni; 10.08.2011

Изглежда същият проблем като публикацията, която сте свързали: методът getView() не е вложен в класа.

Или кодът ви не показва нищо, което да го извика.

person SQLiteNoob    schedule 05.08.2011
comment
Какво означава методът getView, който не е вложен в класа? и как да го оправя? - person Raptrex; 06.08.2011
comment
Вашият код не показва нищо, което извиква метода getView(). Не се вика, защото никъде не сте го викали. Опитайте да го поставите във вашия метод ActivityCreated. - person SQLiteNoob; 06.08.2011

Колкото повече разглеждам това, толкова повече се чудя за основната предпоставка, която използвате. Мисля, че го правите прекалено сложно. Бих го направил така:

public View getView(View convertView)
{
    View vi = convertView;
    TextView viText = null;

    if (vi == null)
        vi = LayoutInflater.from(getActivity()).inflate(R.layout.list_item, null);
    viText = (TextView)vi.findViewById(R.id.line);

    if (viText == null) return vi;
    String viString = viText.getText().toString();

    if (viString.contains("OUT OF LOCK"))
    {
        viText.setBackgroundResource(R.color.red);
    }
    else if (viString.contains("IN LOCK"))
    {
        viText.setBackgroundResource(R.color.green);
    }

    return vi;
}

Не мисля, че използвате holder по начина, по който мислите... цикълът, който имате там, просто ще премине през настройката на фоновия ресурс на какъвто и да е последният тригер за задаване на фоновия ресурс, без значение какво.

Ако съм пропуснал смисъла в това, уведомете ме. Но основната ми мисъл би била да премахнете колкото можете повече сложност, докато заработи, и ако трябва да премахнете нещо важно, бавно го добавете обратно.

person gtcompscientist    schedule 09.08.2011
comment
Е, имам цикъла за преминаване през списъка, който фрагментът има, за да намеря реда, който искам да има цвят на фона. - person Raptrex; 09.08.2011
comment
Но що се отнася до вашия примерен код, няма връзка между holder и list. Можете ли да обясните по-добре връзката? - person gtcompscientist; 09.08.2011