简体   繁体   中英

Android Custom SimpleAdapter Background Color

I have been trying to implement getting the ListView Item Background Color to change based on its State using a Custom SimpleAdapter. I was following code references found here and on other sites. I have it partially working, but not completely.

First, my code:
The XML for the Over-all GUI containing ListView:

<?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout
      android:id="@+id/widget37"
      android:layout_width="fill_parent"
      android:layout_height="fill_parent"
      android:background="#ffffffff"
      xmlns:android="http://schemas.android.com/apk/res/android" 
   >

<ProgressBar
    android:id="@+id/progressBar"
    style="?android:attr/progressBarStyleLarge"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerHorizontal="true"
    android:layout_centerVertical="true" />

<TextView
    android:id="@+id/textViewMessage"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentLeft="true"
    android:layout_alignParentTop="true"
    android:layout_marginLeft="10dp"
    android:layout_marginTop="10dp"
    android:text="Building List..."
    android:textAppearance="?android:attr/textAppearanceMedium"
    android:textColor="#ff000000"
    android:textSize="22sp" />

<RelativeLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignBaseline="@+id/textViewMessage"
    android:layout_alignParentLeft="true"
    android:layout_marginTop="20dp">

    <ListView
        android:id="@id/listLocations"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:layout_marginLeft="10dp"
        android:cacheColorHint="#00000000"
        android:choiceMode="singleChoice"
        android:clickable="true"
        android:scrollingCache="false"
        android:background="@color/transparent"
        android:listSelector="@drawable/listitem_selector">
    </ListView>
</RelativeLayout>

<Button
    android:id="@+id/buttonTryAgain"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentRight="true"
    android:layout_alignParentTop="true"
    android:text="Try Again" />

Based on other postings, notice that I am using a listitem_selector as the background for the ListView so that individual Items can reflect the State in different colors.

Next the XML for the listitem_selector:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
  <item android:state_selected="true" android:drawable="@color/itemSelected" />
  <item android:state_pressed="true" android:drawable="@color/itemPressed" />

<item android:drawable="@color/text_white" />

Here is a 'wrinkle' due to the fact that each Item is comprised of 4 Textboxes - the Adapter is built to utilize the layout list_parkers_tmp

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="60dp"
android:background="@drawable/listitem_selector">

<ImageView
    android:id="@+id/logo"
    android:layout_width="40dp"
    android:layout_height="50dp"
    android:layout_alignParentLeft="true"
    android:layout_alignParentTop="true"
    android:src="@drawable/hangtag" />

<TextView
    android:id="@+id/textViewPermit"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentTop="true"
    android:layout_toRightOf="@+id/logo"
    android:text="Permit Number"
    android:textStyle="bold"
    android:textColor="#FF00AA00"
    android:textSize="22dp" />

<TextView
    android:id="@+id/textViewCategory"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentTop="true"
    android:layout_toRightOf="@+id/textViewPermit"
    android:paddingLeft="10dp"
    android:text="Category"
    android:textColor="#FF555555"
    android:textSize="16dp" />

<TextView
    android:id="@+id/textViewCars"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignBottom="@+id/logo"
    android:layout_alignParentRight="true"
    android:layout_toRightOf="@+id/logo"
    android:text="TextView"
    android:textColor="#FF000000"
    android:textSize="18dp" />

<TextView
    android:id="@+id/textStatus"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentRight="true"
    android:layout_alignParentTop="true"
    android:paddingLeft="10dp"
    android:text="Status"
    android:textStyle="bold"        
    android:textColor="#FF0000"
    android:textSize="16dp" />

Code within the Activity:

// create our SelectedAdapter
selectedAdapter = new SelectedAdapter(getBaseContext(), itemList, R.layout.list_parkers_tmp,
     new String[]{"permit", "status", "category", "cars"},
     new int[]{R.id.textViewPermit, R.id.textStatus, R.id.textViewCategory, R.id.textViewCars});
selectedAdapter.notifyDataSetChanged();
listLocations.setAdapter(selectedAdapter);

And finally the Custom SimpleAdapter:

public class SelectedAdapter extends SimpleAdapter {
private int[] mTo;
private String[] mFrom;
private ViewBinder mViewBinder;
private List<? extends Map<String, ?>> mData;
private int mResource;
private int mDropDownResource;
private LayoutInflater mInflater;

public SelectedAdapter(Context context,
                       List<? extends Map<String, String>> data, int resource, String[] from,
                       int[] to) {
    super(context, data, resource, from, to);
    mData = data;
    mResource = mDropDownResource = resource;
    mFrom = from;
    mTo = to;
    mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}

/**
 * @see android.widget.Adapter#getView(int, View, ViewGroup)
 */

// used to keep selected position in ListView
private int selectedPos = -1;    // init value for not-selected

public void setSelectedPosition(int pos) {
    selectedPos = pos;
    // inform the view of this change
    notifyDataSetChanged();
}

public int getSelectedPosition() {
    return selectedPos;
}

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

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    //View v = convertView;
    View v = super.getView(position, convertView, parent);

    // only inflate the view if it's null
    if (v == null) {
        LayoutInflater vi = (LayoutInflater) Config.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        //LayoutInflater vi
        //        = (LayoutInflater) this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        v = vi.inflate(R.layout.list_parkers_tmp, null);
    }

    // get text view
    String TextViewStr = "";
    String CategoryText = "";
    TextViewStr = this.getItem(position).toString();   // Get ALL of ListView Item's Text Values

    TextView viewPermit = (TextView) v.findViewById(R.id.textViewPermit);
    CategoryText = parseItemStr(TextViewStr,"permit=","");
    viewPermit.setText(CategoryText);

    TextView status = (TextView) v.findViewById(R.id.textStatus);
    CategoryText = parseItemStr(TextViewStr,"status=","cars=");
    status.setText(CategoryText);

    TextView viewCategory = (TextView) v.findViewById(R.id.textViewCategory);
    CategoryText = parseItemStr(TextViewStr,"category=","permit=");
    viewCategory.setText(CategoryText);

    TextView viewCars = (TextView) v.findViewById(R.id.textViewCars);
    CategoryText = parseItemStr(TextViewStr,"cars=","category=");
    viewCars.setText(CategoryText);

    // change the row color based on selected state
    if (selectedPos == position) {
        v.setSelected(true);
        v.setPressed(true);
        v.setBackgroundColor(R.color.amber_800);
    } else {
        v.setSelected(false);
        v.setPressed(false);
        v.setBackgroundColor(R.color.text_white);
    }

    /*
    // to use something other than .toString()
    MyClass myobj = (MyClass)this.getItem(position);
    label.setText(myobj.myReturnsString());
    */
    return (v);
}

public String parseItemStr (String ItemStr, String Category1, String Category2) {
    ItemStr = ItemStr.replace("}","");
    ItemStr = ItemStr.replace("{","");
    int loc1 = ItemStr.indexOf((Category1));
    int loc2 = 0;
    if (!Category2.equals("")) {
        loc2 = ItemStr.indexOf((Category2));
    } else {
        loc2 = ItemStr.length();
    }
    String shortStr = ItemStr.substring(loc1,loc2);
    shortStr = shortStr.replace(Category1,"").trim();
    int len = shortStr.length();
    if (len > 0){
        if (shortStr.substring(len-1,len).equals(",")) {
            shortStr = shortStr.substring(0,Math.max(0,len-1));
        }
    }

    return shortStr;
}

}

I can watch the code execute and the GetView() executes as expected.

First, when the ListView is initially created (no specific Item Selected), the individual Item's Background Color is NOT Transparent as expected, but Gray. That's not right.

Then, when an Item is Selected the GetView() code portion where selectedPos == position executes as intended.
But No Background Color change results from it.

Have I totally messed things up or have I just missed a few things?

Try using setActivated.

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_activated="true" android:drawable="@color/amber_800" />
    <item android:state_pressed="true" android:drawable="@color/itemPressed" />
    <item android:drawable="@color/transparent" />
</selector>

Then just activate and deactivate

// change the row color based on selected state
if (selectedPos == position) {
    v.setActivated(true);
} else {
    v.setActivated(false);
}

I made some WAG's (Wild A** Guesses) and found the answer.

The problem was in the getView() BackgroundColor parameters.

if (selectedPos == position) {
    v.setSelected(true);
    v.setPressed(true);
    v.setBackgroundColor(R.color.amber_800);
} else {
    v.setSelected(false);
    v.setPressed(false);
    v.setBackgroundColor(R.color.text_white);
}

When I was attempting to use a Resource defined color such as: v.setBackgroundColor(R.color.amber_800); it did not work.
In fact occassionally the R.color.amber_800 was underlined in Red (an indication of a problem). The confusing part was that many times it was not underlined in Red and sometimes it was.

Regardless, when I changed those color parameters to:

v.setBackgroundColor(Color.YELLOW);
       and 
v.setBackgroundColor(Color.TRANSPARENT);  

Things began working.

Does anyone know how to get the Resource color settings to work as expected?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM