Does anyone have an idea why the setItemChecked() function doesn't work for my below example:
private class DrawerItemClickListener implements
ListView.OnItemClickListener {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
int pos = position;
...
default:
break;
}
listView.setItemChecked(pos, true);
setTitle(titles[pos]);
drawerLayout.closeDrawer(listviewLayout);
}
}
In all examples I've seen so far, the setItemChecked is done inside the DrawerItemClickListener method. But for some reason it does not want to work. I've tried to put it inside onCreate() or onResume(), but still no result.
I tested for simple listView, and it seems it doesn't work there either. Any suggestions ?
Code for my adapter:
public View getView(int position, View convertView, ViewGroup parent) {
Account account = this.items.get(position);
ViewHolder viewHolder;
if (convertView == null) {
viewHolder = new ViewHolder();
LayoutInflater inflater = LayoutInflater.from(getContext());
convertView = inflater.inflate(layoutResID, parent, false);
viewHolder.textViewTitle = (TextView) convertView
.findViewById(R.id.textViewTitle);
viewHolder.imageViewImage = (ImageView) convertView
.findViewById(R.id.imageView);
convertView.setTag(viewHolder);
} else
viewHolder = (ViewHolder) convertView.getTag();
return convertView;
}
It almost doesn't matter where you call setItemChecked(). Are you using custom ListView views?
If your answer is yes, you have to specify selectors for ListView items.
This might be your drawer's ListView item:
<TextView
android:id="#+id/drawer_item_text_view"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/drawer_list_item_background"/>
Your item's background (R.drawable.drawer_list_item_background) must be specified as selector:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/bg_menu_active" android:state_checked="true"/>
<item android:drawable="#drawable/bg_menu_active" android:state_selected="true"/>
<item android:drawable="#drawable/bg_menu_active" android:state_activated="true"/>
<item android:drawable="#drawable/bg_menu_normal" android:state_checked="false"/>
</selector>
R.drawable.bg_menu_active:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<stroke android:width="1dp" android:color="#color/white"/>
</shape>
R.drawable.bg_menu_normal:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<solid android:color="#android:color/black"/>
</shape>
After this done, you are able to set chosen item as checked and highlight it somehow.
Related
I pretty like the selector behavior generated in navigation drawer.
It has ripple effect.
Its ImageView and TextView has proper color, when being selected.
In my dialog, I try to achieve the same effect, by using the following layout.
label_array_adapter.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:background="?android:attr/selectableItemBackground"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal">
<ImageView
android:duplicateParentState="true"
android:id="#+id/image_view"
android:paddingStart="24dp"
android:paddingLeft="24dp"
android:paddingEnd="16dp"
android:paddingRight="16dp"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:src="?attr/labelIconSelector" />
<TextView
android:duplicateParentState="true"
android:textSize="16sp"
android:id="#+id/text_view"
android:layout_width="0dp"
android:width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:textColor="?attr/labelTextViewColorSelector" />
</LinearLayout>
labelIconSelector
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true">
<bitmap android:src="#drawable/ic_label_white_24dp"
android:tint="#color/colorPrimaryBrown" />
</item>
<item>
<bitmap android:src="#drawable/ic_label_white_24dp"
android:tint="#ff757575" />
</item>
</selector>
labelTextViewColorSelector
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true" android:color="#color/colorPrimaryBrown" />
<item android:color="#color/primaryTextColorLight" />
</selector>
In my ArrayAdapter, I try to programmatically select the 1st item via view.setSelected(true)
public class LabelArrayAdapter extends ArrayAdapter<TabInfo> {
private static class ViewHolder {
public final ImageView imageView;
public final TextView textView;
public ViewHolder(View view) {
imageView = view.findViewById(R.id.image_view);
textView = view.findViewById(R.id.text_view);
Utils.setCustomTypeFace(textView, Utils.ROBOTO_REGULAR_TYPE_FACE);
}
}
public LabelArrayAdapter(#NonNull Context context, List<TabInfo> tabInfos) {
super(context, R.layout.label_array_adapter, tabInfos);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = null;
if (convertView == null) {
LayoutInflater inflator = LayoutInflater.from(this.getContext());
view = inflator.inflate(R.layout.label_array_adapter, null);
final ViewHolder viewHolder = new ViewHolder(view);
view.setTag(viewHolder);
// Not sure why this is required.
view.setLayoutParams(new AbsListView.LayoutParams(AbsListView.LayoutParams.MATCH_PARENT, Utils.dpToPixel(48)));
} else {
view = convertView;
}
ViewHolder holder = (ViewHolder) view.getTag();
TabInfo tabInfo = getItem(position);
if (tabInfo == null) {
holder.imageView.setVisibility(View.INVISIBLE);
holder.textView.setText("(No label)");
} else {
holder.imageView.setVisibility(View.VISIBLE);
holder.textView.setText(tabInfo.getName());
}
if (position == 0) {
view.setSelected(true);
} else {
view.setSelected(false);
}
return view;
}
}
This is how I try to show Dialog via DialogFragment.
return new AlertDialog.Builder(getActivity())
.setTitle("Move to")
.setAdapter(new LabelArrayAdapter(this.getContext(), customTabInfos), (dialog, which) -> {
})
.create();
However, it doesn't work as you can see in the following screenshot. The 1st item doesn't look like it is being selected.
May I know, is there anything I had missed out?
How to make a View looks like it is being selected programmatically, if its background is ?android:attr/selectableItemBackground (ListView in AlertDialog)
Update
Using
alertDialog.getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
alertDialog.getListView().setSelection(position);
wouldn't help either.
Here is an approach using a layer list drawable as the background for the view group that represents the item being selected.
First, for API 21+, we define a layer list drawable that displays the selected color when the item is selected. A call to View#setSelected() must be made for this to have an effect.
layer_list.xml (v21)
color/selected is #2000ffe5 for the demos.
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<selector>
<item
android:drawable="#color/selected"
android:state_selected="true" />
</selector>
</item>
<item
android:id="#+id/selectableBackground"
android:drawable="?android:selectableItemBackground" />
</layer-list>
For API < 21, we cannot use android:drawable="?android:selectableItemBackground" in the layer list, so we will fall back to an alternate but similar visual cue.
layer_list < API 21
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<selector android:exitFadeDuration="#android:integer/config_shortAnimTime">
<item
android:drawable="#color/selected"
android:state_pressed="false"
android:state_selected="true" />
<item
android:drawable="#color/selectable_background"
android:state_pressed="true" />
</selector>
</item>
</layer-list>
I want to set selector on its groupView but when I click selector on groupView it goes to childView in expandable listview..
Here is my expandable listview.
<ExpandableListView
android:id="#+id/lvLeft"
android:layout_width="280dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="#color/white"
android:choiceMode="singleChoice"
android:dividerHeight="0dp"
android:listSelector="#drawable/group_indicator"
android:transcriptMode="alwaysScroll
/>
Here is my group_indication.xml.
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/normal" android:state_expanded="true"></item>
<item android:drawable="#drawable/normal"></item>
</selector>
Here is my normal.xml.
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#color/red" />
<padding
android:bottom="5dp"
android:left="5dp"
android:right="5dp"
android:top="5dp" />
</shape>
actually I want to set custom color on groupView in expandable listview but when I click on groupView, custom color set on groupView 's childView. I have attach screen shot which problem I am getting now in which Transaction History is GroupView and My Transaction is childView . Please help me solve this issue. Thanks in advance.
I have solve the problem by Prakash Gavade's answer. here is answer. In expandable listiview adapter, I have added below code.
#Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent)
{
TextView tvUserName = null;
ImageView imgMenuIcon = null;
View drawerView = convertView;
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (groupPosition == 0)
{
drawerView = inflater.inflate(R.layout.profile_image, parent, false);
ImageView ivProfilePic = (ImageView) drawerView.findViewById(R.id.imgProfile);
tvUserName = (TextView) drawerView.findViewById(R.id.tvFname);
TextView tvLname = (TextView) drawerView.findViewById(R.id.tvLname);
}
else if(isExpanded){
convertView.setBackgroundResource(R.color.gray);
}
return drawerView;
}
i wanna set my listview's background like in the link's pic, it should be shown as button but i cant set background separately.
http://www.delta.edu/images/OIT/Android%20List%20View.png
i've tried android:listSelector="#drawable/pic" and this didnt work for me.
i tried tools:listitem="#layout/row" too, but it didnt worked for me.
I hope i was clear about my problem.
Check out a tutorial like this for some hints.
Create an XML file in drawable similar to this:
rounded_corners.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<solid android:color="#00FF00"/>
<corners android:radius="5dp" />
<padding android:left="3dp" android:top="3dp" android:right="3dp" android:bottom="3dp" />
<stroke android:width="3dp" android:color="#00CC00"/>
</shape>
listview_selector.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:drawable="#drawable/rounded_corner" android:state_enabled="true"/>
<item android:drawable="#drawable/rounded_corner" android:state_pressed="true"/>
<item android:drawable="#drawable/rounded_corner" android:state_focused="true"/>
</selector>
Apply it to the ListView Adapter similar to this:
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
PlanetHolder holder = new PlanetHolder();
// First let's verify the convertView is not null
if (convertView == null) {
// This a new view we inflate the new layout
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.row_layout, null);
// Now we can fill the layout with the right values
TextView tv = (TextView) v.findViewById(R.id.name);
holder.planetNameView = tv;
v.setTag(holder);
v.setBackgroundResource(R.drawable.rounded_corner);
}
else
holder = (PlanetHolder) v.getTag();
Planet p = planetList.get(position);
holder.planetNameView.setText(p.getName());
return v;
}
I am looking to implement a navigation drawer selector which shows the currently selected item at all times when the drawer is opened and that is retained even when the drawer is closed. Something like this:
I have used something like this but it only shows the selector when I click on the list item. This is in my res 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/list_activated_holo" />
</selector>
How do i attain the above shown implementation?Which state do i need to implement? Thanks
Have resolved same issue by setting color in getView() of ArrayAdapter that populates my list in NavigationDrawer:
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = LayoutInflater.from(getActivity()).inflate(
R.layout.side_menu_list_item,
parent,
false);
holder = new ViewHolder();
holder.title = (TextView) convertView.findViewById(R.id.text1);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
if (mCurrentSelectedPosition == position) {
holder.title.setBackgroundResource(R.color.menu_list_separator_line);
} else {
holder.title.setBackgroundResource(R.color.app_background_light);
}
holder.title.setText(menuItems[position]);
return convertView;
}
There's another state, "android:state_selected", that you must use. Use a state drawable for the background of your list item, and use a different state drawable for listSelector of your list:
list_row_layout.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="?android:attr/listPreferredItemHeight"
android:background="#drawable/listitem_background"
>
...
</LinearLayout>
listitem_background.xml:
<?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/android:transparent" />
<item android:drawable="#drawable/listitem_normal" />
</selector>
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>
Normally when I create a ListView in simple ArrayAdapter. It got this highlight feature automatically without additional setup. However, when I create this ListView with my custom CursorAdapter this feature seem to be missing and I cannot find a way to solve it.
Here is my custom CursorAdapter
public class RecentCallAdapter extends CursorAdapter {
private final String tag = this.getClass().getSimpleName();
public RecentCallAdapter(Context context, Cursor c, int flags) {
super(context, c, flags);
// TODO Auto-generated constructor stub
}
private static class ViewHolder {
TextView name;
TextView date;
int nameCol;
int dateCol;
int numberCol;
Calendar cal;
}
#Override
public void bindView(View v, Context context, Cursor cursor) {
// TODO Auto-generated method stub
ViewHolder holder = (ViewHolder) v.getTag();
if (holder == null) {
holder = new ViewHolder();
holder.name = (TextView) v.findViewById(R.id.recentcall_item_name);
holder.date = (TextView) v.findViewById(R.id.recentcall_item_date);
holder.nameCol = cursor.getColumnIndex(Calls.CACHED_NAME);
holder.dateCol = cursor.getColumnIndex(Calls.DATE);
holder.numberCol = cursor.getColumnIndex(Calls.NUMBER);
holder.cal = Calendar.getInstance();
v.setTag(holder);
}
String name = cursor.getString(holder.nameCol);
if(name == null){
name = cursor.getString(holder.numberCol);
}
holder.name.setText(name);
holder.cal.setTimeInMillis(Long.valueOf(cursor.getString(holder.dateCol)));
holder.date.setText(Utility.calculateTimePass(holder.cal.getTime()));
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
// TODO Auto-generated method stub
LayoutInflater inflater = LayoutInflater.from(context);
View v = inflater.inflate(R.layout.recentcall_item, parent, false);
bindView(v, context, cursor);
return v;
}
Any way to solve this?
Thank.
use selector same following
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_focused="true" android:drawable="#android:drawable/list_selector_background">
</item>
<item android:state_focused="true" android:state_selected="true" android:drawable="#android:drawable/list_selector_background">
</item>
</selector>
and use this code in listview tag for set selector
android:drawSelectorOnTop="true"
android:listSelector="#drawable/selector"
I will give you an example which is working for me.
To hold the color of listview item when you press it, include the following line in your
listview layout:
android:background="#drawable/bg_key"
Then define bg_key.xml in drawable folder like this:
<?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/pressed_color"/>
<item
android:drawable="#color/default_color" />
</selector>
Finally, include this in your listview onClickListener:
listView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,long arg3) {
view.setSelected(true);
...
}
}
This way, only one item will be color-selected at any time. You can define your color values in res/values/colors.xml with something like this:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="pressed_color">#4d90fe</color>
<color name="default_color">#ffffff</color>
</resources>
In your custom layout set the background as android:background="#drawable/bkg"
bkg.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/pressed" />
<item android:state_focused="false"
android:drawable="#drawable/normal" />
</selector>
normal.xml
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#10EB0A"/>
<stroke android:width="3dp"
android:color="#0FECFF" />
</shape>
pressed.xml
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#FF1A47"/>
<stroke android:width="3dp"
android:color="#0FECFF"/>
</shape>