I am trying to set a custom selector to a ListView. It's working fine on newer devices but not working on lower version of devices.I want the ListView selected item to be stay highlighted.
Please help.
Thanks in advance.
ListView.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ListView
android:id="#+id/listViewBell"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:cacheColorHint="#00000000"
android:choiceMode="singleChoice"
android:divider="#b5b5b5"
android:dividerHeight="1dp"
android:listSelector="#drawable/list_selector_color" >
</ListView>
</LinearLayout>
list_selectror_color.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<solid android:color="#color/list_selector" />
<stroke
android:dashWidth="2dp"
android:width="1dp"
android:color="#color/white" />
</shape>
I have also tried with selector but nothing happens
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/list_selector_color" android:state_pressed="true"/>
<item android:drawable="#drawable/list_selector_color" android:state_focused="true"/>
<item android:drawable="#drawable/list_selector_color" android:state_selected="true"/>
<item android:drawable="#drawable/list_selector_normal"/>
</selector>
Here is my Custom adapter getView Method
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.listview_bell_items, parent,
false);
ImageView imageview = (ImageView) convertView
.findViewById(R.id.list_bell_image);
imageview.setImageResource(mDataImage[position]);
TextView textview = (TextView) convertView
.findViewById(R.id.txt_bell_title);
textview.setText(mDataText[position]);
return convertView;
}
I had similar problem. Sorry, cannot comment, so I post a possible answer.
Remove android:listSelector="#drawable/list_selector_color" property from your ListView declaration
In your R.layout.listview_bell_items specify your custom selector for a root layout. E.g., if root layout of your list item is RelativeLayout, try:
<RelativeLayout ... android:background="#drawable/listitem_selector">...
The same goes for any other type of Layout.
If this still still does not give you the result you want, provide more details.
Update
Ok, if nothing else helps, there's a temporary dirty workaround of your problem. I do not see why it would not work.
Introduce a selectedPos variable holding currently selected item.
private class MyAdapter extends .../*your base adapter*/ {
private static final int NOT_SELECTED = -1;
private int selectedPos = NOT_SELECTED;
// if called with the same position multiple lines it works as toggle
public void setSelection(int position) {
if (selectedPos == position) {
selectedPos = NOT_SELECTED;
} else {
selectedPos = position;
}
notifyDataSetChanged();
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = super.getView(position, convertView, parent);
if (position == selectedPos) {
// your color for selected item
view.setBackgroundColor(Color.parseColor("#000000"));
} else {
// your color for non-selected item
view.setBackgroundColor(Color.parseColor("#FFFFFF"));
}
return view;
}
}
Now, add the following code after you create and set ListView's adapter:
final MyAdapter adapter = new MyAdapter(...);
listView.setAdapter(adapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
adapter.setSelection(position);
}
});
That is what I found out:
To get the list selector working the are two approaches:
1)
You use the OnItemClickListener.
Then the list selector drawable/color will work as expected when set it on the list view.
Then you may use a TouchListener for getting ClickEvents of any child view instead of using a ClickListener.
2)
You have set ClickListener on any child of the row view.
In this case the list selector will not work when been set on the list view, so you have to set your list selector drawable/color as background of the row view.
Related
I'm trying to make a slight adjustment to the positioning of the selected item in the spinner. Not the dropdown list items, as I already have a custom view in my adapter for that, but the selected item specifically.
As you can see in the screenshot, "Any" is the currently selected item. But it is aligned oddly within the container because it has to accommodate the longest string in the dropdown, which is "Dark Purple Burnt Sienna" (or whatever). I want to align the selected text to the right so that "Any" is next to the dropdown indicator instead of way out in the middle.
I've attempted to make adjustments to my custom spinner-item view, but it doesn't have any affect on the selected item.
I've also attempted to set gravity and text alignment on the Spinner itself, but it has no effect.
Here's the image and the xml:
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#color/default_black"
android:layout_centerVertical="true"
android:text="Color" />
<Spinner
android:id="#+id/spn_color"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"/>
</RelativeLayout>
Edit: Here's my adapter:
public class ColorsAdapter<T> implements SpinnerAdapter {
ArrayList<String> mColors;
ArrayList<Integer> mValues;
Context mContext;
public ColorsAdapter(ArrayList<String> colors, ArrayList<Integer> values,
Context context) {
mContext = context;
mColors = colors;
mValues = values;
}
#Override
public int getCount() {
return mColors.size();
}
#Override
public Object getItem(int position) {
return mColors.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public int getItemViewType(int position) {
return R.layout.list_item_color;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
TextView v = new TextView(mContext);
v.setText(mColors.get(position));
return v;
}
#Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(
Context.LAYOUT_INFLATER_SERVICE );
View row = inflater.inflate(getItemViewType(position), parent, false);
TextView tvName = (TextView)row.findViewById(R.id.tv_name);
tvName.setText(mColors.get(position));
row.setTag(mValues.get(position));
return row;
}
#Override
public int getViewTypeCount() {
return 1;
}
#Override
public boolean hasStableIds() {
return false;
}
#Override
public boolean isEmpty() {
return false;
}
}
And here's the XML for the list item:
<TextView
android:id="#+id/tv_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:gravity="right"/>
You can adjust the settings for selected item in getView(int position, View convertView, ViewGroup parent) method. If you just want to set the gravity and text alignment, you should set it to the TextView in the method like
#Override
public View getView(int position, View convertView, ViewGroup parent) {
TextView v = new TextView(mContext);
v.setText(mColors.get(position));
v.setGravity(Gravity.END); // OR v.setGravity(Gravity.RIGHT);
return v;
}
Or you can simply inflate custom layout if you want to make further customization:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
View row = null;
if (inflater != null) {
row = inflater.inflate(R.layout.list_item_view_color, parent, false);
TextView textView = row.findViewById(R.id.textview);
textView .setText(mColors.get(position));
}
return row;
}
Where list_item_view_color.xml is your layout file for the selected value.
(NOTE: If you want to use options like autoSizeTextType, you can use them with app prefix for AppCompatTextView in xml files)
Simple solution would be to build another Custom view for the spinner TextView layout, and specify the gravity for your TextView in that. Something like :
<!--spinner_layout.xml (in layout/)-->
<?xml version="1.0" encoding="utf-8"?>
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="right"
/>
Use that in initalising the ArrayAdapter of your spinner :
ArrayAdapter<String> adapter = new ArrayAdapter<String>
(this, android.R.layout.spinner_layout,
spinnerArray);
UI output :
You can creating the TextView for the getView method programmatically so no property for alignment is being set, easy thing to do is inflate it in the same way you are doing it on the getDropdownView, or simply set the proper gravity in the view you are instantiated.
#Override
public View getView(int position, View convertView, ViewGroup parent) {
TextView v = new TextView(mContext);
v.setText(mColors.get(position));
v.setGravity(Gravity.RIGHT);
return v;
}
You can try this
android:autoSizeTextType="uniform"
Padding, Margins and Alignments get confusing when it comes to Spinners. I ran into a similar issue as well. But for me I wasn't using a custom view and adapter, so I managed to use styles to get around this issue.
For you since you are already using custom view and adapter, you can make the background null for the spinner so that the dropdown arrow will not be visible.
android:background="#null"
Then in the TextView, you can assign drawableRight to be the dropdown arrow.
android:drawableRight="#drawable/ic_spinner_drop_arrow_white_24dp"
The icon can be a dropdown vector drawable. Also to specify particular margin between the arrow and text, you should be able to use drawablePadding
Hope this helps.
I can give you a method that may work.
In XML
1) add a new text view called the_current_color text view
2) allign this text view above the spinner and to the start of the arrow icon
or wherever you want it to be.
In your code
1) when you listen to (on item selected ) from the spinner simply get the current text and set it in the (the_current_color) text view.
2) and try to hide the texts in the spinner by changing color to transparent.
Hope it works
Edit
I might also suggest something maybe it changes things
lets say that we have a spinner that uses this string resource file to populate its adapter
<string-array name="my_adapter">
<item>Blue </item>
<item>Red</item>
</string-array>
until now we have a spinner that shows (red item) and (blue item) at the far left from the arrow icon of the spinner.
create another string resources now like that
<string-array name="my_adapter_two">
<item> Blue </item>
<item> Red</item>
</string-array>
as you can see now the added space will give an illusion that the strings are beside the arrow icon
you can add space that fit your need and you can maybe switch the files after you click a certain item and then switch them back.
You can try the following Custom view.
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/textView1"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:gravity="right"
android:padding="15dp"
android:textAlignment="gravity"
android:textColor="#color/black"
android:textSize="10dp" />
Hello i want to change background of my listView item.but it only highlight on touch.but i want to change the background until i change the focus on other item.
What i did so far is below.
Back.xml
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_enabled="false" android:state_focused="true"
android:drawable="#android:color/black" />
<item android:state_pressed="true"
android:drawable="#android:color/holo_red_dark" />
<item android:state_focused="true"
android:drawable="#android:color/holo_red_dark" />
ListView
<ListView
android:id="#+id/list"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:fastScrollEnabled="true"
android:drawSelectorOnTop="true"
android:clickable="true"
android:listSelector="#drawable/listviewcolor"
android:scrollingCache="false">
</ListView>
In Main i have tried everything but does not works it only highlight on touch.
but i want to keep highlight until i change it .
ListView.requestFocus();
ListView.setActivated(true);
ListView.setPressed(true);
ListView.setItemChecked(4, true);
ListView.requestFocusFromTouch();
ListView.setSelection(2);
This can be achieved only by using customAdapter in the following way.
Initially a Listview will lose its focus, when user touches some other item in the layout design. One way of keeping it stay selected, even when it's out of focus is by:
Keeping track of selected position from ListView.
Use the selected position in the ListView adapter and set its view background color according to the selection.
By doing this your background color will stay selected.
Example:
Inside your custom Adapter:
Private int studentListItemSelected;
public void ItemSelected(int itemPosition)
{
//This method will keep track which position of the List is Selected and the background color of it is inside this.
this.studentListItemSelected=studentListItemSelected;
notifyDataSetChanged();
}
public View getView(int position, View convertView, ViewGroup parent)
{
//layout inflation code
if(this.studentListItemSelected==position)
{
convertView.setBackgroundColor(Color.Red);
}
else
{
convertView.setBackgroudnColor(Color.White);
}
return convertView;
}
In your Layout Java file:
yourListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
adapter.ItemSelected(position);
});
I am having a listview which I am populating using inflater. When I implement selector with some color it actually come on top of listview item which is fine, but it also affecting text of listview. The textfont color also get changes according to the selector color. How can I implement selector without affecting my listview text font color
layout.xml that includes the ListView:
<ListView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:listSelector="#drawable/listitem_selector"
/>
listitem_selector.xml:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="#drawable/listitem_pressed" />
<item android:state_focused="true" android:drawable="#drawable/listitem_selected" />
</selector
Or, you can set the selector of the View by Overriding the getView() method of your ListAdapter. Check more here
It will help you!!
Android: Programmatically set the listSelector for a ListView to the default for the current theme
private static void setDefaultListSelector(ListView listView, Context context) {
TypedArray typedArray = context.obtainStyledAttributes(null, new int[]{android.R.attr.listSelector}, android.R.attr.listViewStyle, 0);
Drawable drawable = typedArray.getDrawable(0);
listView.setSelector(drawable);
}
You can detect the position of the current selected item
OnItemClickListener listViewOnItemClick = new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapter, View arg1, int position, long id) {
mSelectedItem = position;
mAdapter.notifyDataSetChanged();
}
};
Override the getView method of your adapter
#Override
public View getView(int position, View convertView, ViewGroup parent) {
final View view = View.inflate(context, R.layout.item_list, null);
if (position == mSelectedItem) {
// set your color
}
return view;
}
So I have an activity with 2 ListView widgets, when you select a value in the first one, the second is populated with values related to the selection in the first ListView. This mechanic works without a problem, but now I want the user choices to stay highlighted. I've read a good ammount of question related to this topic and it seems there is a myriad of ways one can accomplish this but after trying about 4-5 of em' I still can't get it to work.
I've got it working on the second ListView using the android:listSelector="#CCCCCC" XML Attribute, but this seems to be wiped clean once a OnItemClickListener is introduced into the mix (like the one I use on my first ListView).
So far here's what I've got:
Custom OnItemClickListener I found browsing various answer regarding this topic (slightly modified it in order for it to load my info the second ListView):
private class ItemHighlighterListener implements OnItemClickListener {
private View oldSelection = null;
public void clearSelection() {
if(oldSelection != null) {
oldSelection.setBackgroundColor(android.R.color.transparent);
}
}
public void onItemClick(AdapterView<?> parent, View view, int pos, long id) {
clearSelection();
oldSelection = view;
view.setBackgroundDrawable(view.getContext().getResources().getDrawable(R.drawable.list_selector));
loadClubs(mXMLPortalOptions.getRegion(pos).getId());
mClubList.setAdapter(new ArrayAdapter<String>(getApplicationContext(), R.layout.list_item_white, mClubs));
}
}
Here's my list_selector.xml file :
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true"><shape>
<solid android:color="#CCCCCC" />
</shape></item>
<item android:state_selected="false"><shape>
<solid android:color="#FFFFFF" />
</shape></item>
</selector>
The method (OnItemClick) is called and executed, but the background of my ListItem stays the same color :/
I can't believe that this simple task has proven so complicated.
If I have omitted code that could be useful or if my question is lacking details, feel free to point that out and I'll do my best to explain myself.
Put a position variable for selected item. Change the position in onItemClicked() method. Check the selected position in List Adapter inside getView() and set the background for the selected item.
public class TestAdapter extends BaseAdapter
{
private Context context;
private ArrayList<TestList> testList;
private int selectedIndex;
private int selectedColor = Color.parseColor("#1b1b1b");
public TestAdapter(Context ctx, ArrayList<TestList> testList)
{
this.context = ctx;
this.testList = testList;
selectedIndex = -1;
}
public void setSelectedIndex(int ind)
{
selectedIndex = ind;
notifyDataSetChanged();
}
#Override
public int getCount()
{
return testList.size();
}
#Override
public Object getItem(int position)
{
return testList.get(position);
}
#Override
public long getItemId(int position)
{
return position;
}
private class ViewHolder
{
TextView tv;
}
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
View vi = convertView;
ViewHolder holder;
if(convertView == null)
{
vi = LayoutInflater.from(context).inflate(R.layout.test_list_item, null);
holder = new ViewHolder();
holder.tv = (TextView) vi;
vi.setTag(holder);
}
else
{
holder = (ViewHolder) vi.getTag();
}
if(selectedIndex!= -1 && position == selectedIndex)
{
holder.tv.setBackgroundColor(Color.BLACK);
}
else
{
holder.tv.setBackgroundColor(selectedColor);
}
holder.tv.setText("" + (position + 1) + " " + testList.get(position).getTestText());
return vi;
}
}
Now set the selectedIndex variable when a list item clicked.
public class TestActivity extends Activity implements OnItemClickListener
{
// Implemented onItemClickListener
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
adapter.setSelectedIndex(position);
}
}
To expand on Shaiful's great solution, you might not get his to work in your situation.
If you are using have your code all in public void onListItemClick(ListView l, View v, int index, long id), if you're using fragments and have to declare an interface instead of implementing OnListItemClickListener, or whatever is causing your IDE to generate errors, you might have to access variables and methods statically.
public static int selectedPosition = 0;
ArrayAdapter<Your_obj> adapter = null;
#Override
public void onListItemClick(ListView l, View v, int index, long id) {
super.onListItemClick(l, v, index, id);
selectedPosition = index;
Your_adapter.setSelectedIndex(selectedPosition);
adapter.notifyDataSetChanged();
}
And in Your_adapter:
private static int selectedIndex;
//public Your_adapter...
public static void setSelectedIndex(int ind) {
selectedIndex = ind;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
WellHolder holder = null;
if (null == convertView) {
//set up your "holder"
}
if (position == selectedIndex) {
convertView.setBackgroundColor(convertView.getResources().getColor(R.color.cyan));
}
else {
convertView.setBackgroundColor(convertView.getResources().getColor(R.color.silver));
}
return convertView;
}
Some other differences are that you don't have to initialize any variables as "0" or "-1" and notifyDataSetChanged() is called in your activity.
Once again, thanks for your solution #Shaiful. It certainly helped save me time trying to get what is default in iOS to work for Android, all while avoiding selector/item/focused/pressed/etc.
I faced similar problem. That's my solution:
First add custom list selector to your list view:
<ListView
android:id="#+id/list"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:listSelector="#drawable/listselector" />
Inside listselector.xml:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_accelerated="false"
android:drawable="#drawable/bg" />
</selector>
And finally a drawable bg.xml with color of your highlight:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#33b5e6"/>
</shape>
I think the best and easiest solution is this. You don't need to set any android:listSelector on the ListView itself or do any changes to the adapter. You don't even need to call any setSelection(position) in the OnItemClickListener as it is handled automatically.
Set to your ListView:
android:choiceMode="singleChoice"
Set background of the list item itself:
android:background="?android:attr/activatedBackgroundIndicator"
That's it.
This way you'll get default system behavior. That's how it is done in the default android.R.layout.simple_list_item_activated_1 layout.
lv.setSelector(R.drawable.highlighter);
put a highlighter.png image in drawable folder
simplest way to highlight selected item in list view.
I was looking for it two weeks ago and the result is that is not possible with a drawable selector.
For more info read this post in Android Developers Blog: Touch Mode
In resume: Only when your finger are on the screen, item is selected.
Other possibility is save which item is selected in a var and paint different using your custom adapter like Shaiful says.
//create a list_itemselectorin drawable folder
//you will get the list item selected background color change once you select //the item
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Focused State -->
<item android:state_focused="true"><shape>
<solid android:color="#66FFFFFF" />
</shape></item>
<!-- Pressed State -->
<item android:state_pressed="true"><shape>
<solid android:color="#color/Black" />
</shape></item>
<!-- Default State -->
<item><shape>
<solid android:color="#color/Black" />
</shape></item>
</selector>
//create a list in layout folder
<ListView
android:id="#+id/mySlidingList"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:choiceMode="singleChoice"
android:divider="#color/GrayHot"
android:dividerHeight="1dip"
android:listSelector="#drawable/list_itemselector"
android:scrollbars="none" />
// And see the output.
If you can use a drawable for displaying listItem Highlighted then you should use following code:-
listView.setSelector(R.drawable.bg_image);
It works.
There is simple fully-XML solution, which worked for me.
Firstly, define XML-drawable with selector code in which "normal" state will correspond to "selected unpressed" visual state of a list item, and state_pressed=true to "pressed" visual state.
Example of file "custom_item_selector.xml", resembling Holo blue selection:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true">
<shape android:shape="rectangle">
<solid
android:color="#643292ff">
</solid>
<stroke
android:width="1dp"
android:color="#c83292ff">
</stroke>
</shape>
</item>
<item>
<shape android:shape="rectangle">
<solid
android:color="#323292ff">
</solid>
<stroke
android:width="1dp"
android:color="#783292ff">
</stroke>
</shape>
</item>
</selector>
(may also set focused state there).
Secondly, apply this xml-drawable as ListView's listSelector and set it's desired choiceMode:
<ListView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/listView"
android:choiceMode="singleChoice"
android:listSelector="#drawable/custom_item_selector"/>
That's all. It allows to define different visual states for "simply selected" and "pressed selected" items, for example making items brighter on press.
To keep the list items(multiple selection) highlighted, when clicked(activated), please follow the steps.
1. Set background to list item layout as drawable.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="40dp"
android:background="#drawable/list_item_selector">
<ImageView
android:id="#+id/icon"
android:layout_width="22px"
android:layout_height="22px"
android:layout_marginLeft="4px"
android:layout_marginRight="10px"
android:layout_marginTop="4px"
android:src="#mipmap/ic_launcher" >
</ImageView>
<TextView
android:id="#+id/label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#+id/label"
android:textSize="20px" >
</TextView>
</LinearLayout>
2. drawable selector
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="#android:color/holo_red_light" />
<item android:state_activated="true" android:drawable="#android:color/holo_orange_dark" />
</selector>
3. Listview set multiple choice mode
getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
When Pressed:
Below image shows, when user selected multiple list items.
When Activated:
To summarize this post and maybe help someone else in future I suggest the answer :)
First, we need to create res/drawable/list_item_background.xml file with the following contents:
<?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/list_item_activated" />
<item
android:drawable="#color/list_item_default" />
</selector>
Specify your drawable resources, of course. And you can also add other <item> elemens with different states like state_pressed, state_focused etc.
Then, we should set the background parameter to our custom list item ViewGroup element (f.i. res/layout/list_item_layout.xml) like this:
android:background="#drawable/list_item_background"
The next step is modifying our custom Adapter class. Here is the following code fragment:
public class CustomAdapter extends BaseAdapter {
private List<Item> items;
private LayoutInflater itemInflater;
private int selectedIndex; // add this
public CustomAdapter(Context c, List<Item> items) {
this.items = items;
this.itemInflater = LayoutInflater.from(c);
selectedIndex = -1; // add this
}
/* add this */
public void setSelectedIndex(int index) {
selectedIndex = index;
notifyDataSetChanged();
}
/* other adapter's stuff */
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView == null) {
convertView = itemInflater.inflate(R.layout.list_item_layout, parent, false);
}
// add this
convertView.setActivated(selectedIndex != -1 && position == selectedIndex);
/* do some stuff */
return convertView;
}
}
Finally, we should call the setSelectedIndex(position) adapter's method in onItemClick(...) method of AdapterView.OnItemClickListener.
public class YourActivity extends Activity
implements AdapterView.OnItemClickListener {
private CustomAdapter mCustomAdapter;
/* activity implementation */
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
mCustomAdapter.setSelectedIndex(position);
}
}
Now, we can be satisfied with proper list items highlighting :)
P.S. If we want to enable multiple choice mode on our list we'll just place the following string to our activity class where listView instance is kept:
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
Thus, we'll get proper multiple items highlighting.
-- Hope this helps anyone :)
I have a Spinner and for populating him i use a SimpleCursorAdapter.
I want the font color for spinner to be Black and font color for drop down to be White.
I have this code:
String[] column = { "name" };
int[] viewIds = new int[] { R.id.spinner_dropdown_design_from };
SimpleCursorAdapter fromListAdapter = new SimpleCursorAdapter(MyClass.this, R.layout.spinner_drop_down_from, cursor,
column, viewIds) {
#Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {
View viewFromListAdapter = super.getDropDownView(position, convertView, parent);
if (position % 2 == 0) {
viewFromListAdapter.setBackgroundResource(R.layout.dropdown_selector_odd);
} else {
viewFromListAdapter.setBackgroundResource(R.layout.dropdown_selector_even);
}
return viewFromListAdapter;
}
};
So i use different layout for odd and even rows in the dropdown.
I give you an example for dropdown_selector_even
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true" android:drawable="#drawable/grey_background"/>
<item android:state_focused="true" android:drawable="#drawable/blue_background"/>
<item android:state_pressed="true" android:drawable="#drawable/blue_background"/>
<item android:drawable="#drawable/grey_background"/>
</selector>
And spinner_drop_down_from
<?xml version="1.0" encoding="utf-8"?>
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/spinner_dropdown_design_from"
android:layout_height="100dip"
android:layout_width="fill_parent"
android:paddingLeft="20dip"
android:textSize="40dip"
android:gravity="center_vertical"
android:textStyle="normal|bold"
android:textColor="#000000"/>
Can someone help me?
Thanks in advance!
I found the solution.
I must also overwrite the getView method
Something like this
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = super.getView(position, convertView, parent);
TextView text = (TextView) view.findViewById(R.id.spinner_dropdown_design_products);
text.setTextColor(Color.WHITE);
return view;
}
Please take a look to the following link. It worked for me, and not need to use custom adapters. Just xml.
http://www.broculos.net/2013/09/how-to-change-spinner-text-size-color.html#.U2eJI_l5OSo