开发者

Android ListFragment individually change row background color

I have a ListFragment where I want certain rows to be a certain color. I basically followed this: Creating a ListView and setting the background color of a view in each row

However, getView is never called. Does anyone know why?

    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开发者_JS百科("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>

I am updating the list like this from my activity:

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

My 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;
}
}

What am I doing wrong? Edit: added list_item.xml, where line is found. Edit2: added extended array adapter

Now my problem is that, every row is either all green or red, when I just want certain individual rows to be either red or green. Also, none of the text is showing up.


Your current getView implementation should be moved into a ListAdapter implementation instead of your TrackerFragment class. Since you're using ArrayAdapter, you can subclass that and put the code in there. ArrayAdapter already implements getView, but you'll override it to provide your specialized behavior.

The reason you're getting a NullPointerException is because you're calling getView and passing in the list view, which does not have a tag associated with it -- so holder = (ViewHolder) vi.getTag(); assigns null to holder. That said, you shouldn't be calling getView directly. The system will call that for you whenever it needs to display a list item. When the system calls the getView method, it initially passes in null to have the views created, and every call where convertView is not null is a view created by that method.


Looks like the same problem as the post you linked: the getView() method isn't nested inside the class.

Or your code doesn't show anything that would call it either.


The more I look over this, the more I wonder about the basic premise you are using. I think you're making it overly complicated. I would do it like this:

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;
}

I don't think you are using the holder in the way you think... the loop you have in there will just loop through setting the background resource to whatever the last trigger to set the backgroundResource is, no matter what.

If I have missed the point in this, let me know. But, my basic thought would be to remove as much complexity as you can until it works, and if you've had to remove something important, slowly add it back in.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜