Android StateListDrawable bug? - android

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>

Related

How to change the colour of the navigation drawer item

I want to change my navigation drawer list item's background colour to be changed when i click on it.
Also it should change the text and icon colour of that item as well.
Thanks in advance..
This is quite simple and is similar to changing the background of any view that you use. You can simply create a method and write all the change code into it. Pass the view as a parameter in the method.
Whenever you click on any of the navigation drawer items, pass your view on the method.
For instance, check this method
private boolean viewSelected(View view) {
ViewHolder currentViewHolder = (ViewHolder) view.getTag();
KTextView yourtextView = currentViewHolder.yourtextView;
view.setBackgroundColor(ResourceUtil.getInstance().getColor(R.color.colorSideMenuSelectedBackground));
currentViewHolder.viewSelector.setVisibility(View.VISIBLE);
yourtextView.setTypeface(yourtextView.getContext(), ResourceUtil.getInstance().getString(R.string.yourFontName));
if (lastSelectedView == null) {
lastSelectedView = view;
return true;
}
if (lastSelectedView != view) {
ViewHolder oldViewHolder = (ViewHolder) lastSelectedView.getTag();
oldViewHolder.viewSelector.setVisibility(View.GONE);
lastSelectedView.setBackgroundColor(ResourceUtil.getInstance().getColor(android.R.color.white));
KTextView newTextView = oldViewHolder.yourtextView;
newTextView.setTypeface(yourtextView.getContext(), ResourceUtil.getInstance().getString(R.string.yourfontname));
lastSelectedView = view;
return true;
}
return false;
}
This method will simply change the background, font and color of the views.
Hope this helps!
This can be done using https://developer.android.com/guide/topics/resources/color-list-resource.
Create two drawable files :
1.drawer_background
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="checked_background_color" android:state_checked="true" />
<item android:color="default_background_color" />
</selector>
2.drawer_text_background
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="checked_text_color" android:state_checked="true" />
<item android:color="default_text_color" />
</selector>
And add these two properties to your NavigationView ie
app:itemIconTint="#drawable/drawer_background"
app:itemTextColor="#color/drawer_text_background"
one more if some color is overlapping with some other color
app:itemBackground="#android:color/transparent"
Now, All you have to do is to set an item as checked on Click listener of that item to change background and text color. You can do it programmatically.
I solved it setting this attribute to my NavigationView app:itemBackground="#drawable/drawer_selector"
and my drawer_selector is as below
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="#color/white" />
<item android:state_focused="true" android:drawable="#color/white" />
<item android:state_activated="true" android:drawable="#color/white" />
<item android:drawable="#color/orange" />

ListView android looses background color

I have an adapter which extends ArrayAdapter> filling fragment layout with multiple choices each time.
The problem is that sometimes background disappears completely on items choose before, or all other items. If you check this image
http://i.imgur.com/S1KEfM1.png
you can see that ccc option lost background. Layout inflates this Relative Layout
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="67dp"
android:background="#drawable/selectable_background_example"
android:descendantFocusability="blocksDescendants"
android:gravity="center_vertical"
android:paddingLeft="20dp"
android:paddingRight="10dp" >
With this background xml
<selector xmlns:android="http://schemas.android.com/apk/res/android" android:exitFadeDuration="#android:integer/config_mediumAnimTime">
<item android:drawable="#drawable/list_focused_example" android:state_focused="true" android:state_pressed="false"/>
<item android:drawable="#drawable/pressed_background_example" android:state_pressed="true"/>
<item android:drawable="#drawable/pressed_background_example" android:state_selected="true"/>
<item android:drawable="#drawable/pressed_background_example" android:state_activated="true"/>
<item android:drawable="#drawable/new_strip"/>
</selector>
Pressed_background_example
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<solid android:color="#color/pressed_example" />
<stroke
android:width="3dp"
android:color="#color/pressed_example" />
<padding
android:bottom="1dp"
android:left="1dp"
android:right="1dp"
android:top="1dp" />
</shape>
Pressed_example
<resources>
<color name="pressed_example">#CCCC0000</color>
</resources>
And new_strip is basically just that background white image with border, and list_focused_example is image for checkbox pressed.
GetView in my class
public View getView(int position, View convertView, ViewGroup parent) {
Holder mhHolder;
if (convertView == null) {
mhHolder = new Holder();
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.row_a, parent, false);
mhHolder.txtValue = (TextView) convertView.findViewById(R.id.txtValue);
mhHolder.txtCheckbox = (CheckBox) convertView.findViewById(R.id.checkBox1);
mhHolder.txtText = (TextView) convertView.findViewById(R.id.txtText);
convertView.setTag(mhHolder);
} else {
mhHolder = (Holder) convertView.getTag();
}
HashMap<String, String> hm = values.get(position);
mhHolder.txtValue.setText(hm.get("Value"));
mhHolder.txtText.setText(hm.get("Text"));
mhHolder.txtCheckbox.setVisibility(View.VISIBLE);
//TODO CHANGE WHEN CHECKED IS SEND
mhHolder.txtCheckbox.setChecked(Base.checked[position]);
}
Does anyone have any clue on why the background dissapears on previous selected items or sometimes on all items except the selected one.
I think it´s a kind of bug (or I don't really get the real function).
Anyhow you should try to call
mhHolder.txtValue.setbackground(R.drawable.selectable_background_example);
in your code so that it is executed for each item.
In the end the problem was the image (new_strip). I had to make a drawable the same as the image (which had only white background and gray rounded corners), so that fixed the problem.

Setting background programmatically overrides drawable

I have a ListView and I have a Drawable for each item in the ListView to highlight each row when it's selected/pressed. I also have a custom adapter where I'm programatically setting the background color of each row (I want to have alternating background colors). This is a new feature I added and before adding the code the rows would highlight blue, but after they do not highlight. Not sure how to fix it. Here is what I have:
ListView item layout
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:paddingLeft="5dip"
android:paddingRight="5dip"
android:paddingTop="8dip"
android:paddingBottom="8dip"
android:background="#drawable/app_selector"
>
<TextView
android:id="#+id/text"
style="#style/ListingTitle"
android:layout_alignParentTop="true"
android:paddingBottom="2dip"
/>
</RelativeLayout>
Drawable
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="#color/light_blue" />
<item android:state_selected="true" android:state_pressed="false" android:drawable="#color/light_blue" />
<item android:state_activated="true" android:state_selected="false" android:state_pressed="false" android:drawable="#color/light_blue" />
<item android:state_selected="false" android:state_pressed="false" android:drawable="#android:color/transparent" />
</selector>
Fragment
public class ListingFragment extends SherlockListFragment
{
public void onActivityCreated(final Bundle icicle)
{
ListView lv = getListView();
mListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
mListView.setMultiChoiceModeListener(new MultiChoiceModeListener() {
#Override
public void onItemCheckedStateChanged(android.view.ActionMode mode, int position, long id, boolean checked) {
}
#Override
public boolean onActionItemClicked(android.view.ActionMode mode, android.view.MenuItem item) {
}
}
}
/* ADAPTER */
private class CustomAdapter extends BaseAdapter
{
#Override
public View getView(final int position, View convertView, final ViewGroup parent)
{
final ViewHolder holder;
if (convertView == null)
{
holder = new ViewHolder();
convertView = mInflater.inflate(R.layout.item, parent, false);
}
else
{
holder = (ViewHolder)convertView.getTag();
}
if (position % 2 == 0)
convertView.setBackgroundColor(Color.GRAY);
else
convertView.setBackgroundColor(Color.TRANSPARENT);
return(convertView);
}
}
}
Expanding on dum's answer, you don't need to do all that work in code.
Drawable A
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="#color/light_blue" />
<item android:state_selected="true" android:state_pressed="false" android:drawable="#color/light_blue" />
<item android:state_activated="true" android:state_selected="false" android:state_pressed="false" android:drawable="#color/light_blue" />
<item android:state_selected="false" android:state_pressed="false" android:drawable="#android:color/transparent" />
</selector>
Drawable B
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="#color/light_blue" />
<item android:state_selected="true" android:state_pressed="false" android:drawable="#color/light_blue" />
<item android:state_activated="true" android:state_selected="false" android:state_pressed="false" android:drawable="#color/light_blue" />
<item android:state_selected="false" android:state_pressed="false" android:drawable="#android:color/gray" />
</selector>
In your Adapter:
if (position % 2 == 0) {
convertView.setBackgroundResource(R.drawable.A);
} else {
convertView.setBackgroundResource(R.drawable.B);
}
instead of changing the drawable with plain color, first create a new drawable programmatically and set the states just like in your xml and then set colors for each state. then try replacing your background with your programmatically created drwable.

How do I ensure change the background of a selected GridView cell?

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" />

Android listview item color change

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>

Categories

Resources