Related
I have a menu which has sharp rectangle background. I have tried a lot i can't change it to rounded background.
popup_menu.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#1F2026"
android:orientation="horizontal"
>
<TextView
android:id="#+id/details"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:fontFamily="#font/quicksand_regular"
android:text="#string/add_to_favourite"
android:textColor="#color/icon_color_dark" />
</LinearLayout>
The above given is my popup menu xml.
public static void showAlbumPopupOptions(final Activity activity, ImageView listMore,
final Song song, String songId, int playingState) {
final boolean isLogged = AppController.getBooleanPreference(Constants.LOGGED_IN, false);
String[] listItems;
listItems = activity.getResources().getStringArray(R.array.popup_menu_add_album);
ArrayAdapter<String> mPopupAdapter = new ArrayAdapter<>(activity, R.layout.popup_menu, R
.id.details, listItems);
final ListPopupWindow albumPopup = new ListPopupWindow(activity);
albumPopup.setContentWidth(Utils.measureContentWidth(mPopupAdapter, activity));
albumPopup.setAdapter(mPopupAdapter);
albumPopup.setHeight(ListPopupWindow.WRAP_CONTENT);
albumPopup.setAnchorView(listMore);
albumPopup.setModal(true);
albumPopup.setDropDownGravity(Gravity.END);
final LoadingProgressDialog loadingProgressDialog = new LoadingProgressDialog(activity, R
.style
.DialogThemeProgress, false);
albumPopup.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
if (position == 0) {
if (isLogged) {
DialogPlayList dialogPlayList = new DialogPlayList(activity,
activity, String.valueOf(song.getId()), loadingProgressDialog);
dialogPlayList.show();
loadingProgressDialog.setDimDialog(false);
loadingProgressDialog.showProgress();
} else {
redirectLogin(activity);
}
albumPopup.dismiss();
} else if (position == 2) {
showAudioShare(song, activity);
albumPopup.dismiss();
} else if (position == 1) {
AppController.addToQueueSongs(activity, song, songId,
playingState);
albumPopup.dismiss();
}
}
});
albumPopup.show();
}
The above given method is called when user clicks the more option in the list. I am adding datas to the list from this method. As a result I am getting this.
But actually what I want is - image given below.
I have tried setting background as rounded corners but no use. I literally have no idea how to achieve. Please suggest me some solutions. Thanks in advance.
With the a Material Components Theme you have a default rounded background with a corner radius of 4dp.
You can customize it using the listPopupWindowStyle attribute in your app theme:
<style name="AppTheme" parent="Theme.MaterialComponents.DayNight">
<item name="listPopupWindowStyle">#style/myListPopupWindow</item>
</style>
with:
<style name="myListPopupWindow" parent="Widget.MaterialComponents.PopupMenu.ListPopupWindow">
<item name="android:popupBackground">#drawable/popupMenuBackground</item>
</style>
where the drawable background is something like:
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="?attr/colorSurface"/>
<corners
android:bottomLeftRadius="8dp"
android:bottomRightRadius="8dp"
android:topLeftRadius="8dp"
android:topRightRadius="8dp"/>
<padding
android:bottom="8dp"
android:top="8dp"/>
</shape>
I found the answer. Add this code with ListPopupWindow before setting the adapter.
Drawable background = ContextCompat.getDrawable(activity, R.drawable
.res_black_menuroundfilled_corner);
albumPopup.setBackgroundDrawable(background);
Remove android:background="#1F2026" in popup_menu.xml
Below given code is for drawable file. res_black_menuroundfilled_corner
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#1F2026"/>
<corners android:radius="15dp"/>
</shape>
ListPopupWindow listPopupWindow = new ListPopupWindow(this);
listPopupWindow.setAdapter(popUpAdapter);
listPopupWindow.setAnchorView(itemView);
listPopupWindow.setDropDownGravity(Gravity.NO_GRAVITY);
listPopupWindow.setBackgroundDrawable(ContextCompat.getDrawable(this,R.drawable.round_corner));
listPopupWindow.setWidth(ListPopupWindow.WRAP_CONTENT);
listPopupWindow.setHeight(ListPopupWindow.WRAP_CONTENT);
listPopupWindow.show();
I want to make clickable item of my RecyclerView. However it is not working. item_background.xml is defined well, it works in other parts of my project. However in this case, I have more items in LinearLayout, which contain some onClick listeners. When I click on an item, background is not changed. Please see the code below.
I cannot set background for inside items instead, because I need the whole item to change background color, not only parts.
item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:background="#drawable/item_background"
android:clickable="true"
...
>
<TextView
<!-- NO BACKGROUND -->
... />
<ImageView
<!-- NO BACKGROUND -->
... />
...
</LinearLayout>
item_bg.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#android:color/darker_gray" android:state_pressed="true"/>
<item android:drawable="#android:color/darker_gray" android:state_focused="true"/>
<item android:drawable="#android:color/transparent"/>
</selector>
To change the background or highlight the selected item in recyclerview you can try this
public class AdapterClass extends RecyclerView.Adapter<AdapterClass.ViewHolder> {
private int selected_position = -1;
#Override
public void onBindViewHolder(PlacesLocationAdapter.ViewHolder holder, final int position) {
if (selected_position == position) {
// do your stuff here like
//Change selected item background
parentLayout.setBackgroundColor(Color.parse("darkgraycolorcode"));
} else {
// do your stuff here like
//Change unselected item background
parentLayout.setBackgroundColor(Color.TRANSPARENT);
}
// rest of the code here
holder.linelayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(selected_position==position){
selected_position=-1;
notifyDataSetChanged();
return;
}
selected_position = position;
notifyDataSetChanged();
}
});
//rest of the code here
}
}
Also you can define the parent layout click listener ie linearlayout in view holder also
I have an AppWidget with a ListView. To populate the ListView I'm using RemoteViewsFactory. In its getViewAt(int position) method which returns a RemoteViews object I fill my row with information.
How can I disable clicking on a ListView item? RemoteViews has no setEnabled() method that I would use for a 'normal' ListView.
Override adapter with:
#Override
public boolean areAllItemsEnabled() {
return false;
}
#Override
public boolean isEnabled(int position) {
return false;
}
Put a drawable shape as background using android:background="#drawable/list_background" in list_item.xml, when clicked it will not flash.
list_background.xml in res/drawable
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners
android:topLeftRadius="3dp"
android:topRightRadius="3dp"/>
<solid android:color="#ffff0000"/>
<stroke
android:color="#ffff0000"
android:width="1dp"/>
</shape>
I used Android Studio to implement the Navigation Drawer and I can't get the blue colour that is used to show which section we're currently in to change.
I've tried numerous things, I'm currently using a listSelector which looks like:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_activated="true" android:drawable="#color/selected" />
<item android:state_pressed="true" android:drawable="#color/highlight" />
</selector>
I've also tried state_checked. state_pressed works in this situation but the currently selected item is still blue.
EDIT:
I've been examining this more and when the adapter is created the context that is passed is getActionBar().getThemedContext() so I'm thinking if I can find the right attribute to assign to my actionbar style I can change it from there. I've tried a few different attributes with no luck. Does anyone know the exact attribute?
I've also realised if I put
<item name="android:activatedBackgroundIndicator">#drawable/nav_listview_selector</item>
in the main part of my theme and change getActionBar().getThemedContext() for getActivity.getBaseContext then I can change the color but I don't think this is the correct way. I think the themed context should be used. So if anyone knows where the activatedBackgroundIndicator could be put so that it would be used in getActionBar.getThemedContext()
EDIT2:
So the text view used for the listview is one within the SDK it looks like this:
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#android:id/text1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceListItemSmall"
android:gravity="center_vertical"
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
android:background="?android:attr/activatedBackgroundIndicator"
android:minHeight="?android:attr/listPreferredItemHeightSmall"
/>
So I tried modifying the "?android:attr/activatedBackgroundIndicator" at the theme level but it has no effect for checked/selected/activated but it does for pressed. Does anyone know why this is? And how I can change it?
To solve this problem:
1- You don't need android:listSelector under your ListView.
2- Open (or Create) styles.xml under (res/values).
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="android:activatedBackgroundIndicator">#drawable/drawer_list_selector</item>
</style>
3- Under res/drawable folder create drawer_list_selector.xml file
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="#drawable/light_gray_color" />
<item android:state_activated="true" android:drawable="#drawable/red_color" />
<item android:drawable="#android:color/transparent" />
</selector>
4- Under res/drawable create red_color.xml / light_gray_color.xml (or any other name) and add your desired Hex color:
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#C8FF0000"/>
</shape>
5- Open your project AndroidManifest.xml and add android:theme tag (if not exist)
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
Reference / Credit: Changing Navigation Drawer Selected Item Color from default blue
To change the "Navigation Drawer item background colour for selected item" you could do it with the attribut:
colorControlHighlight
In your "styles.xml" it could look like this:
<style name="YourStyleNameFor.NavigationDrawer" parent="ThemeOverlay.AppCompat.Light">
<item name="colorControlHighlight">#color/your_highlight_color</item>
</style>
Don't forget to apply your Style in the tag:
android.support.design.widget.NavigationView
For example in your activity_main.xml it could look like this:
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="#layout/navigationdrawer_header"
<!-- the following line referes to your style -->
app:theme="#style/YourThemeNameFor.NavigationDrawer"
<!-- the following two lines are maybe also interesting for you -->
app:itemIconTint="#color/gray3"
app:itemTextColor="#color/gray3"
app:menu="#menu/navigationdrawer_main" />
This is working for me:
First define a drawable item_bg.xml as:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="true" android:drawable="#drawable/nav_menu_bg" />
</selector>
Then use this drawable in navigation_main_layout.xml as:
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:itemBackground="#drawable/item_bg"
android:fitsSystemWindows="true"
app:headerLayout="#layout/nav_header_navigation"
app:menu="#menu/navigation_main_layout_drawer" />
here is how i have done and it is working, the brief concept is maintain the position of selected item in adapter and call notifyDataSetChanged on calling notifyDatasetChanged the getView method is called again and in get view check the position on the selected position change the background view. Here is the code :
Adapter of NavigationDrawer List View
public class MenuAdapter extends BaseAdapter {
private static final int TYPE_HEADER = 0;
private static final int TYPE_ITEM = 1;
private Context mContext;
private String name;
private int profile;
private int mIcons[];
private int selectedPosition = 0;
private String mNavTitles[];
private LayoutInflater mInflater;
public MenuAdapter(String titles[], int icon[], String Name, int profile) {
mNavTitles = titles;
mIcons = icon;
name = Name;
this.profile = profile;
}
public MenuAdapter(String Titles[], int Icons[], Context mContext) {
mNavTitles = Titles;
mIcons = Icons;
this.mContext = mContext;
mInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return mNavTitles.length;
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
convertView = mInflater.inflate(R.layout.item_row, parent, false);
TextView textView = (TextView) convertView.findViewById(R.id.rowText);
ImageView imageView = (ImageView) convertView.findViewById(R.id.rowIcon);
final LinearLayout layout = (LinearLayout) convertView.findViewById(R.id.outerLayout);
imageView.setImageResource(mIcons[position]);
textView.setText(mNavTitles[position]);
if (position == selectedPosition)
layout.setBackgroundColor(mContext.getResources().getColor(R.color.app_bg));
else
layout.setBackgroundColor(mContext.getResources().getColor(R.color.normal_bg));
return convertView;
}
public void setSelectedPosition(int position) {
this.selectedPosition = position;
}
}
in your activity do this
private class DrawerItemClickListener implements ListView.OnItemClickListener {
#Override
public void onItemClick(AdapterView parent, View view, int position, long id) {
mMenuAdapter.setSelectedPosition(position - 1);
mMenuAdapter.notifyDataSetChanged();
}
}
if anyone still face any difficulty, feel free to ask.
I have implement drawer menu with custom adapter class. May be it will help someone Drawer List
<ListView
android:id="#+id/listview_drawer"
android:layout_width="260dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="#color/menu_item_color"
android:choiceMode="singleChoice"
android:divider="#android:color/transparent"
android:dividerHeight="0dp"
android:fadingEdge="none"
/>
drawer_list_item.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/menu_selector"
>
<ImageView
android:id="#+id/imgIcon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="12dp"
android:layout_marginRight="12dp"
android:src="#drawable/ic_menu_home" />
<TextView
android:id="#+id/lblName"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_centerVertical="true"
android:gravity="center_vertical"
android:layout_toRightOf="#+id/imgIcon"
android:minHeight="48dp"
android:textColor="#color/menu_txt_color" />
menu_selector.xml
<selector xmlns:android="http://schemas.android.com/apk/res/android" android:exitFadeDuration="#android:integer/config_mediumAnimTime">
<!-- selected -->
<item android:drawable="#color/menu_item_active_color" android:state_focused="true" android:state_pressed="false"/>
<item android:drawable="#color/menu_item_active_color" android:state_pressed="true"/>
<item android:drawable="#color/menu_item_active_color" android:state_activated="true"/>
<item android:drawable="#color/menu_item_active_color" android:state_checked="true"/>
<item android:drawable="#color/menu_item_active_color" android:state_selected="true"/>
<item android:drawable="#color/menu_item_color" android:state_activated="false"/>
Add this on item click listner of listview
yourlistview.setItemChecked(position, true);
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#color/list_item_back_pressed" android:state_pressed="true" />
<item android:state_activated="true"><color android:color="#color/primary_blue"/></item>
<item android:drawable="#color/list_item_back_normal"/>
</selector>
In addition to providing a custom selector drawable for the listSelector, you should also set the background resource of the list item to a similar selector drawable that has different drawables for the different states.
I usually use my custom adapter that has an int selection field, and a setSelection(int) function. And in the getView function I set the background of the view according to position == selection.
Still not sure why it is that it doesn't work. But the way I found around it is to use my own simple_list_item_activated layout to be passed to the ArrayAdapter which was basically the same except for setting the text colour to white. I then replaced getActionBar().getThemedContext() with getActivity().getBaseContext() and it now has an effect.
This may not be the correct way and may have repercussions in the future, but for now I have it working the way I want it to.
I know its too late but I have solved this issue in my app.
Pls dont think it is silly, just simply change the position of "state_pressed" to top.
<item android:drawable="#drawable/list_item_bg_pressed" android:state_pressed="true"/>
<item android:drawable="#drawable/list_item_bg_normal" android:state_activated="false"/>
<item android:drawable="#drawable/list_item_bg_selected" android:state_activated="true"/>
In Future if anyone comes here using, Navigation Drawer Activity (provided by Studio in Activity Prompt window)
The answer is -
Use this before OnCreate() in MainActivity
int[][] state = new int[][] {
new int[] {android.R.attr.state_checked}, // checked
new int[] {-android.R.attr.state_checked}
};
int[] color = new int[] {
Color.rgb(255,46,84),
(Color.BLACK)
};
ColorStateList csl = new ColorStateList(state, color);
int[][] state2 = new int[][] {
new int[] {android.R.attr.state_checked}, // checked
new int[] {-android.R.attr.state_checked}
};
int[] color2 = new int[] {
Color.rgb(255,46,84),
(Color.GRAY)
};
ColorStateList csl2 = new ColorStateList(state2, color2);
and use this in onNavigationItemSelected() in MainActivity (you dont need to Write this function if you use Navigation Drawer activity, it will be added in MainActivity).
NavigationView nav = (NavigationView) findViewById(R.id.nav_view);
nav.setItemTextColor(csl);
nav.setItemIconTintList(csl2);
nav.setItemBackgroundResource(R.color.white);
Tip - add this code before If else Condition in onNavigationItemSelected()
This worked for me :
implemented menu drawer not by populating the navigation view with list, but with menu items.
created a drawable like this :
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#color/drawer_menu_selector_color" android:state_checked="true"></item>
<item android:drawable="#color/drawer_menu_selector_color" android:state_activated="true"></item>
and in onCreate method , set the id of the menu item which corresponds to selected activity as checked.
and implement the drawable selector file to your navigation drawer like this
app:itemBackground="#drawable/drawer_menu_selector"
fyi : need to define your 'app' namespace.
I searched for solution on this issue, tried everything, and only this solution worked for me.
You can find it on this link https://tuchangwei.github.io/2016/07/18/The-solution-that-the-menu-item-of-Navigation-View-can-t-change-its-background-When-it-is-selected-checked/
All the credit to https://tuchangwei.github.io/
I want to know on how I can change the background color of the selected item on my listView. I only want to change the specific item clicked by the user, meaning if the user clicks another item it will be the one which is highlighted. Well since I want it to keep simple as possible and use the default android listview I used this code instead:
record_list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
try{
for (int ctr=0;ctr<=record_items.length;ctr++){
if(i==ctr){
record_list.getChildAt(ctr).setBackgroundColor(Color.CYAN);
}else{
record_list.getChildAt(ctr).setBackgroundColor(Color.WHITE);
}
}
}
catch (Exception e){
e.printStackTrace();
}
Log.v("Selected item",record_list.getItemAtPosition(i));
}
});
Ok this one is working but the problem is that it's slow. Now I want to know if there's any other way around that I can do which will give the same output as I made.
I tried using record_list.getSelectedView().setBackgroundColor(Color.CYAN); but it gives me a null pointer exception.
I also tried the selector.xml but it also didn't do the trick.
Furthermore, there is one properties here on ListView which is called listSelector. It's a drawable as said by the documentation "Drawable used to indicate the currently selected item in the list." I also believe that this should do the trick and yes it do the trick on my emulator but not on my galaxy tab. I also tried the other methods but nothing works as I wanted it to be.
You can keep track the position of the current selected element:
OnItemClickListener listViewOnItemClick = new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapter, View arg1, int position, long id) {
mSelectedItem = position;
mAdapter.notifyDataSetChanged();
}
};
And 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;
}
For me it did the trick.
You can use a selector. Change the colors values and modify the below according to your needs.
bkg.xml in drawable folder
<?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/pressed" />
<item android:state_focused="false"
android:drawable="#drawable/normal" />
</selector>
pressed.xml in drawable folder
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#FF1A47"/> // color
<stroke android:width="3dp"
android:color="#0FECFF"/> // border
<padding android:left="5dp"
android:top="5dp"
android:right="5dp"
android:bottom="5dp"/>
<corners android:bottomRightRadius="7dp" // for rounded corners
android:bottomLeftRadius="7dp"
android:topLeftRadius="7dp"
android:topRightRadius="7dp"/>
</shape>
normal.xml in drawable folder
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#FFFFFF"/>
<stroke android:width="3dp"
android:color="#0FECFF" />
<padding android:left="5dp"
android:top="5dp"
android:right="5dp"
android:bottom="5dp"/>
<corners android:bottomRightRadius="7dp"
android:bottomLeftRadius="7dp"
android:topLeftRadius="7dp"
android:topRightRadius="7dp"/>
</shape>
Set the background drawable to listview custom layout to be inflated for each row
I recommend using a custom listview with a custom adapter.
android:background="#drawable/bkg"
If you have not used a custom adapter you can set the listselector to listview as below
android:listSelector="#drawable/bkg"
Define variable
private ListView mListView;
Initialize variable
mListView = (ListView)findViewById(R.id.list_view);
OnItemClickListener of listview
mListView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adpterView, View view, int position,
long id) {
for (int i = 0; i < mListView.getChildCount(); i++) {
if(position == i ){
mListView.getChildAt(i).setBackgroundColor(Color.BLUE);
}else{
mListView.getChildAt(i).setBackgroundColor(Color.TRANSPARENT);
}
}
}
});
Build and run the project - Done
If you want to have the item remain highlighted after you have clicked it, you need to manually set it as being selected in the onItemClick listener
Android ListView selected item stay highlighted:
myList.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
view.setSelected(true); // <== Will cause the highlight to remain
//... do more stuff
}});
This assumes you have a state_selected item in your selector:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="true" android:state_pressed="true" android:drawable="#color/red" />
<item android:state_enabled="true" android:state_focused="true" android:drawable="#color/red" />
<item android:state_enabled="true" android:state_selected="true" android:drawable="#color/red" />
<item android:drawable="#color/white" />
</selector>
Method 1:
Update ListView in the your xml layout activity/fragment:
<ListView
...
android:choiceMode="singleChoice"
android:listSelector="#android:color/darker_gray"
/>
That's it, you're done!
If you want a programmatic way to handle this then use method 2...
Method 2:
If you're using a ListFragment you can override onListItemClick(), using the view to set the colour. Save the current View selected to reset the colour of the last selection.
Please note, this only works on listviews that fit on one screen, as the view is recycled.
public class MyListFragment extends ListFragment {
View previousSelectedItem;
...
#Override
public void onListItemClick(ListView parent, View v, int position, long id) {
super.onListItemClick(parent, v, position, id);
if (previousSelectedItem!=null) {
previousSelectedItem.setBackgroundColor(Color.WHITE);
}
previousSelectedItem=v;
v.setBackgroundColor(Color.BLUE);
}
}
First you can create selector xml file like below in your drawable folder drawable/list_item_selector.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_activated="true">
<shape android:shape="rectangle">
<solid android:color="#333333" />
<padding android:left="5dp" android:right="5dp" />
</shape></item>
<item><shape android:shape="rectangle">
<solid android:color="#222222" />
</shape></item>
</selector>
And then in your listview specify background as
android:background="#drawable/list_item_selector"
For those wondering what EXACTLY needs to be done to keep rows selected even as you scroll up down. It's the state_activated The rest is taken care of by internal functionality, you don't have to worry about toggle, and can select multiple items. I didn't need to use notifyDataSetChanged() or setSelected(true) methods.
Add this line to your selector file, for me drawable\row_background.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="#android:color/holo_blue_light"/>
<item android:state_enabled="true" android:state_pressed="true" android:drawable="#android:color/holo_blue_light" />
<item android:state_enabled="true" android:state_focused="true" android:drawable="#android:color/holo_blue_bright" />
<item android:state_enabled="true" android:state_selected="true" android:drawable="#android:color/holo_blue_light" />
<item android:state_activated="true" android:drawable="#android:color/holo_blue_light" />
<item android:drawable="#android:color/transparent"/>
</selector>
Then in layout\custom_row.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="10dip"
android:background="#drawable/row_background"
android:orientation="vertical">
<TextView
android:id="#+id/line1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
For more information, I'm using this with ListView Adapter, using
myList.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
and
myList.setMultiChoiceModeListener(new MultiChoiceModeListener()...
from this example: http://www.androidbegin.com/tutorial/android-delete-multiple-selected-items-listview-tutorial/
Also, you (should) use this structure for your list-adapter coupling: List myList = new ArrayList();
instead of: ArrayList myList = new ArrayList();
Explanation: Type List vs type ArrayList in Java
Simplest way I've found:
in your activity XML add these lines:
<ListView
...
android:choiceMode="singleChoice"
android:listSelector="#666666"
/>
or programatically set these properties:
listView.setSelector(Drawable selector)
listView.setSelector(int resourceId)
My particular example:
<ListView
android:choiceMode="singleChoice"
android:listSelector="#666666"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/listView"/>
thanks to AJG:
https://stackoverflow.com/a/25131125/1687010
View updateview;// above oncreate method
listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if (updateview != null)
updateview.setBackgroundColor(Color.TRANSPARENT);
updateview = view;
view.setBackgroundColor(Color.CYAN);
}
});
I'm also doing the similar thing: highlight the selected list item's background (change it to red) and set text color within the item to white.
I can think out a "simple but not efficient" way:
maintain a selected item's position in the custom adapter, and change it in the ListView's OnItemClickListener implement:
// The OnItemClickListener implementation
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
mListViewAdapter.setSelectedItem(position);
}
// The custom Adapter
private int mSelectedPosition = -1;
public void setSelectedItem (int itemPosition) {
mSelectedPosition = itemPosition;
notifyDataSetChanged();
}
Then update the selected item's background and text color in getView() method.
// The custom Adapter
#Override
public View getView(int position, View convertView, ViewGroup parent) {
...
if (position == mSelectedPosition) {
// customize the selected item's background and sub views
convertView.setBackgroundColor(YOUR_HIGHLIGHT_COLOR);
textView.setTextColor(TEXT_COLOR);
} else {
...
}
}
After searching for a while, I found that many people mentioned about to set android:listSelector="YOUR_SELECTOR". After tried for a while, I found the simplest way to highlight selected ListView item's background can be done with only two lines set to the ListView's layout resource:
android:choiceMode="singleChoice"
android:listSelector="YOUR_COLOR"
There's also other way to make it work, like customize activatedBackgroundIndicator theme. But I think that would be a much more generic solution since it will affect the whole theme.
use the below xml as listitem background it will solve all the issues.
The selected will be highlighted though you scrolled down.
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#android:color/holo_orange_dark" android:state_pressed="true"/>
<item android:drawable="#android:color/holo_green_light" android:state_selected="true"/>
<item android:drawable="#android:color/holo_green_light" android:state_activated="true"/>
Thanks,
Nagendra
I know this is a old question, but i give a simple solution for this need (without loops!):
//On your adapter create a variable:
private View lastSelectedItem;
//Define the folowing method:
private void toggleBackgroundItem(View view) {
if (lastSelectedItem != null) {
lastSelectedItem.setBackgroundColor(Color.TRANSPARENT);
}
view.setBackgroundColor(getResources().getColor(R.color.colorPrimaryDark));
lastSelectedItem = view;
}
//finally invoque the method onItemClick
lvSac.setOnItemClickListener(new AdapterView.OnItemClickListener()
{
#Override
public void onItemClick (AdapterView < ? > adapterView, View view,int i, long l){
toggleBackgroundItem(view);
}
}
In a ListView set:
android:choiceMode="singleChoice"
Create a selector for a background (drawable/selector_gray.xml):
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#color/gray" android:state_checked="true" />
<item android:drawable="#color/white" />
</selector>
Add an item for a list:
<?xml version="1.0" encoding="utf-8"?>
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:padding="5dp"
android:background="#drawable/selector_gray"
android:textColor="#color/colorPrimary"
tools:text="Your text" />
In a ViewHolder you can inflate this item.
nameofList.getChildAt(position).setBackgroundColor(RED);
worked for me
assume you want one item to be clicked each time. Then this code works well. Let's take the listview name as stlist
stList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
// here i overide the onitemclick method in onitemclick listener
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
//color change
//selected item colored
for(int i=0; i<stList.getAdapter().getCount();i++)
{
stList.getChildAt(i).setBackgroundColor(Color.TRANSPARENT);
}
parent.getChildAt(position).setBackgroundColor(Color.GRAY);
});
This is a simple method that can handle selection even if the list is long as well:
public View getView(final int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
Holder holder=new Holder();
View rowView;
rowView = inflater.inflate(R.layout.list_item, null);
//Handle your items.
//StringHolder.mSelectedItem is a public static variable.
if(getItemId(position)==StringHolder.mSelectedItem){
rowView.setBackgroundColor(Color.LTGRAY);
}else{
rowView.setBackgroundColor(Color.TRANSPARENT);
}
return rowView;
}
And then in your onclicklistener:
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
StringHolder.mSelectedItem = catagoryAdapter.getItemId(i-1);
catagoryAdapter.notifyDataSetChanged();
.....
It's very simple. In the constructor of the "OnItemClick" use the parameter "view" which is the second one that represents the listView or GridView's items's view and it becomes the new item's view made by the adapterView it self. So to set new color ONLY to the SELECTED ITEM itself do as the following:
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l){
//view is instead of the view like textView , ImageView, or whatever
view.setBackgroundColor(Color.green);
}
If you do any different codes to set new color, you will face awkward behaviours like the green color will be applied to the unclicked item.