I have the following list adapter that uses an inflater, I've tried adding the color change here but it changes every item not just the one clicked.
private class ListAdapter extends ArrayAdapter<jsonData>{
private List<jsonData> jList;
public ListAdapter(Context context, int resource,List<jsonData> jList) {
super(context, resource, jList);
this.jList = jList;
}
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.listviewact_layout, null);
v.setBackgroundResource(R.layout.list_selector);
}
jsonData jd = jList.get(position);
if (jd != null) {
TextView name = (TextView) v.findViewById(R.id.memberName);
TextView dateJoined = (TextView) v.findViewById(R.id.dateJoined);
if (name != null) {
name.setText("Member Name: " + jd.name);
}
if (dateJoined != null) {
dateJoined.setText("Joined: " + getNewDate(jd.joined));
}
}
return v;
}
I am able to get the item position also, most of it works fine except the colors. I also tried adding a resource file for the selector, but I get the same result.
UPDATE: This seems to work. I have a glitch though when I scroll the item colors go crazy.
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
if(selectedItemPosition != position){
//Resets old item to original color
parent.getChildAt(selectedItemPosition).setBackgroundColor(Color.BLACK);
view.setBackgroundColor(Color.BLUE);
selectedItemPosition = position;
}
}
use android:listSelector not android:background for adding selector xml file to ur listview
<ListView
android:id="#+id/list"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:listSelector="#drawable/list_selector">
</ListView>
Try this selector xml
<?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/android:blue" />
<item android:state_enabled="true"
android:state_focused="true" android:drawable="#color/android:transparent" />
<item
android:drawable="#color/android:black" />
view.setbackground();
Changes the background of entire list .since your view points to that list not a field in that list.
try this
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_focused="true" android:drawable="#color/black" /> <!-- focused -->
<item android:state_focused="true" android:state_pressed="true" android:drawable="#color/black" /> <!-- focused and pressed-->
<item android:state_pressed="true" android:drawable="#color/green" /> <!-- pressed -->
<item android:drawable="#color/black" /> <!-- default -->
</selector>
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>
in my project when I select one image from the horizontal listview it is highlighting,but when I select another image,1st selected image highlighting too..I want at a time only one image should be highlighted. please help me out.
Here is my selector code,
<item android:state_selected="true"android:drawable="#drawable/light_
blue"/>
<item android:drawable="#android:color/transparent" /></selector>
xml code:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/parentchillayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/selector"
android:padding="2dp"
android:layout_marginLeft="5dp"
android:layout_marginTop="5dp"
android:orientation="vertical" >
<ImageView
android:id="#+id/Iv_front"
android:layout_width="80dp"
android:padding="1dp"
android:background="#null"
android:layout_height="80dp"
android:src="#drawable/bag"
/></LinearLayout>
java code:
public void onItemClick(AdapterView<?> arg0, View arg1,int pos,long arg3)
{ arg1.setSelected(true);
Iv_Product.setImageResource(data.get(pos));
position = pos;
}
The condition is mentioned in your selector code itself.
<item android:state_selected="false" ... />
First update youe selector code
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_focused="true" android:drawable="#color/black" /> <!-- focused -->
<item android:state_focused="true" android:state_pressed="true" android:drawable="#color/black" /> <!-- focused and pressed-->
<item android:state_pressed="true" android:drawable="#color/green" /> <!-- pressed -->
<item android:drawable="#color/black" /> <!-- default -->
</selector>
Remove your this code no need to do this.
public static int mSelectedItem =-1; // declare it as global vaiable
public void onItemClick(AdapterView<?> arg0, View arg1,int pos,long arg3)
{
mSelectedItem = position;
mAdapter.notifyDataSetChanged();
}
Keep track in your getView of position and setbackground
#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
view.setBackgroundColor(Color.CYAN);
}
return view;
}
i found the solution and here I am sharing it so that it can be useful to someone.
for(int i=0; i<parent.getChildCount(); i++)
{
if(i == position)
{ parent.getChildAt(i).setBackgroundResource(R.drawable.red);
}
else { parent.getChildAt(i).setBackgroundResource(R.drawable.white);
} }
I have a custom ListView in a tablet app where there's a ListView on the left and detailed fragment on the right, when you select an Item on the left from the listView I want it to be highlighted and stay highlighted (I did this part) but when I scroll down to the bottom of the list and back and due to The recycling of views it forgets the highlighting, how can I do it in a different way?
Here's the code I used in the adapter for the ListView:
protected LinearLayout selectedItem;
protected LinearLayout selectedItemPosition = -1;
.
.
.
#Override
public int getViewTypeCount() {
return 3; // I have 3 types of list Items, this part is working fine..
}
public int getItemViewType(int pos) {
// This part works fine too
}
.
.
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
.
.
.
if (selectedItemPosition == pos) {
holder.listItem.setSelected(true);
}
final LinearLayout listItem = holder.listItem;
holder.listItem.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if (clickCallback != null) {
if (activateOnClick) {
if (selectedItemPosition > -1) {
selectedItem.setSelected(false);
}
selectedItemPosition = pos;
listItem.setSelected(true);
selectedItem = listItem;
}
clickCallback.callback(NewsItems.get(pos));
}
}
});
You can try to create custom selector for listview item - listview_selector.xml
<?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/yourColor" />
<item android:state_enabled="true"
android:state_focused="true" android:drawable="#color/yourColor" />
<item android:state_enabled="true"
android:state_selected="true" android:drawable="#color/yourColor" />
<item
android:drawable="#color/yourColor" />
</selector>
And then, use
listView.setSelector(R.drawable.listview_selector);
i have StateListdrawable in xml
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_activated="false" android:drawable="#drawable/ic_checked_off" />
<item android:state_activated="true" android:drawable="#drawable/ic_checked_on" />
<item android:drawable="#drawable/ic_checked_on" android:state_pressed="true" />
<item android:drawable="#drawable/ic_checked_off" />
</selector>
i have GridView images which has StateListDrawable, and programically try to change drawable state with
if(mSelected.contains(photo)){
view.findViewById(R.id.selector).setActivated(true);
}
images which selected changes state, but when i click his state not change, i'm sorry i can't explain what i want, my english is worse
i try to explain it
if mSelected.contains(photo) [state - active] -> [checked_on.jpg] when i click ->
state drawable begins from first and ignoring my programically state changes
==Edit==
Adapter Item --
private View getPhoto(int position, View convertView, ViewGroup parent){
View view = convertView;
if(convertView == null){
view = LayoutInflater.from(mContext).inflate(R.layout.gallery_photo_item, parent, false);
}
ImageView mPhoto = (ImageView)view.findViewById(R.id.photoview);
Photo photo = (Photo) getItem(position - COLUMNS_NUM);
if(mSelected.contains(photo)){
view.findViewById(R.id.selector).setActivated(true); // here i change my drawable state because it's front of my imageView
}
mLoader.displayImage(MediaStore.Images.Media.EXTERNAL_CONTENT_URI + File.separator + photo.id,
mPhoto);
return view;
}
The problem is the order of the states. They are checked top to bottom, and the first one that matches the situation is used. So that means that the first two are always used. This should work:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="#drawable/ic_checked_on" />
<item android:state_activated="false" android:drawable="#drawable/ic_checked_off" />
<item android:state_activated="true" android:drawable="#drawable/ic_checked_on" />
<item android:drawable="#drawable/ic_checked_off" />
</selector>
In Android, I have a GridView - each cell in the GridView is an ImageView. When a user clicks on a cell, I would like that cell to be "selected" (have its background turn blue), and all other cells to "unselect" (have their backgrounds turn white).
I have implemented the following background drawable, but it only changes the background while the cell is pressed:
<?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/iconborder_selected" /> <!-- pressed -->
<item android:drawable="#drawable/iconborder_unselected" /> <!-- default -->
</selector>
EDIT: Here is my adapter code for the GridView.
class IconAdapter extends BaseAdapter {
private Context context = null;
private List<Drawable> icons = new ArrayList<Drawable>();
public IconAdapter(Context context) {
this.context = context;
for (Field f : R.drawable.class.getFields()) {
String path = f.getName();
if (path.contains("icon_")) {
int id = context.getResources().getIdentifier(path, "drawable",
context.getPackageName());
Drawable drawable = context.getResources().getDrawable(id);
icons.add(drawable);
}
}
}
#Override
public int getCount() {
return icons.size();
}
#Override
public Object getItem(int position) {
return icons.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ImageView iv = new ImageView(context);
iv.setImageDrawable(icons.get(position));
iv.setBackgroundResource(R.drawable.iconborder);
return iv;
}
}
You should add state_selected too:
<?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/iconborder_selected" /> <!-- selected -->
<item android:state_pressed="true"
android:drawable="#drawable/iconborder_pressed" /> <!-- pressed -->
<item android:state_pressed="false"
android:drawable="#drawable/iconborder_unselected" /> <!-- default -->
</selector>
Try in the XML declaration of the GridView to put these lines:
<GridView
<!-- Some stuff here, like id, width, e.t.c. -->
android:drawSelectorOnTop="true"
android:listSelector="path_to_your_selector"
/>
And your selector should contain something like this:
<item android:state_pressed="true">
<shape>
<!-- Or a drawable here -->
</shape>
</item>
<item android:state_focused="true">
<shape>
<!-- Or a drawable here -->
</shape>
</item>
<item android:drawable="#android:color/transparent" />