Altered GradientDrawable gets unwantedly reused in different places - android

I have a ShapeDrawable drawable/my_shape.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid
android:color="#FFFF00" />
<padding android:left="1dp"
android:top="1dp"
android:right="1dp"
android:bottom="1dp" />
</shape>
which I use as background of some TextViews at several places in my app. Like in layout/my_fragment.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout...>
<TextView
android:id="#+id/tag"
android:background="#drawable/my_drawable"
android:layout_height="wrap_content"
android:layout_width="wrap"
android:text="Some text"
/>
<!-- other tags -->
</RelativeLayout>
or in a layout which gets used as list item layout/my_list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout...>
<TextView
android:id="#+id/subject"
android:background="#drawable/my_drawable"
android:layout_height="wrap_content"
android:layout_width="wrap"
/>
<!-- other tags -->
</RelativeLayout>
Now, when I alter the color of the shape programmatically inside my ArrayAdapter of my list, the background of the TextView inside a fragment at a totally different place in my app gets the same color like the last item in my list! From that time on the shape with the altered color gets used in all other activities which have my_fragment.xml in their layout.
holder.subject = (TextView) v.findViewById(R.id.subject);
GradientDrawable bgShape = (GradientDrawable)holder.subject.getBackground();
bgShape.setColor( position % 2 == 0 ? Color.BLACK : Color.WHITE );
How is that possible and how can I avoid that "reuse" behavior?
Here is the code of my array adapter:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
ViewHolder holder; // to reference the child views for later actions
if (v == null) {
LayoutInflater vi =
(LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.my_list_item, null);
// cache view fields into the holder
holder = new ViewHolder();
holder.subject = (TextView) v.findViewById(R.id.subject);
// associate the holder with the view for later lookup
v.setTag(holder);
}
else {
// view already exists, get the holder instance from the view
holder = (ViewHolder) v.getTag();
}
GradientDrawable bgShape = (GradientDrawable)holder.subject.getBackground();
bgShape.setColor( position % 2 == 0 ? Color.BLACK : Color.WHITE );
holder.subject.setText(getItem(position));
}
// somewhere else in your class definition
static class ViewHolder {
TextView subject;
}

I have to use bgShape.mutate().setColor(..)
Also see
Android: Cloning a drawable in order to make a StateListDrawable with filters
http://developer.android.com/reference/android/graphics/drawable/Drawable.html#mutate%28%29

Related

Spinner custom style is not applying properly

I want to apply alternative spinner element background colour, and it works fine for spinner list with limited items that don't need to scroll. when the scroll is possible, the background colour is only applied to text background
#Override public View getDropDownView(int position, View view, ViewGroup parent) {
ViewHolder holder = null;
if(view==null)
{
view= inflater.inflate(R.layout.citylist, parent, false);
holder=new ViewHolder();
holder.txtTitle = (TextView) view.findViewById(R.id.tv);
holder.txtTitle.setTextSize(TypedValue.COMPLEX_UNIT_DIP,db.getSettings().getInt(15)-3);
holder.txtTitle.setPadding(10, 10, 10, 10);
view.setTag(holder);
}
else{
holder=(ViewHolder)view.getTag();
}
holder.txtTitle.setText(data.get(position));
if(position % 2 == 0)view.setBackgroundColor(Color.rgb(224, 224, 235));
if(position % 2 == 1)view.setBackgroundColor(Color.WHITE);
return view;
}
XML of Spinner
<Spinner
android:id="#+id/pnakshathram"
android:layout_width="0dp"
android:layout_weight="2"
android:paddingLeft="15dp"
android:background="#drawable/edittextbackground"
android:layout_height="wrap_content"/>
You need to create a custom layout with the background you want to set and then You need to do this -
set your custom layout in setDropDownViewResource
Spinner yourSpinner = (Spinner) findViewById(R.id.yourSpinner);
yourAdapter.setDropDownViewResource(R.layout.my_spinner);
yourSpinner.setAdapter(adapter);
You need to use your layout in place of android.R.layout.simple_spinner_dropdown_item
dont use android.R.layout.simple_spinner_dropdown_item use your_custom_layout_here
go to your res folder , create a new xml file give any name like my_spinner.xml
my_spinner.xml
<?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:fontFamily="#font/clear_sans_regular"
android:gravity="left"
android:padding="15dp"
android:textColor="#color/warm_grey"
android:textSize="14sp" />
and then add this line
yourAdapter.setDropDownViewResource(R.layout.my_spinner);
In your citylist.xml you have to make your TextView (tv) property to android:layout_width="match_parent" it will show like exactly you want.
Update
if(position % 2 == 0)holder.txtTitle.setBackgroundColor(Color.rgb(224, 224, 235));
if(position % 2 == 1)holder.txtTitle.setBackgroundColor(Color.WHITE);

How to customize the appearance of a Listview rows

I would like to have a Listview in which the rows:
have rounded corners;
are partially colored (the left part of each row);
contain a shape in their colored area which is filled with another color.
Here is an example from another app:
I currently have two leads but I did not succeed with any of them.
My first lead (shape)
I found how to get rounded corners by using a shape and use it as a background for the Listview.
The drawable shape file "rounded_rectangle.xml":
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<corners
android:bottomRightRadius="7dp"
android:bottomLeftRadius="7dp"
android:topLeftRadius="7dp"
android:topRightRadius="7dp"/>
</shape>
The activity file:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:custom="http://schemas.android.com/apk/res-auto"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
android:layout_width="match_parent"
android:layout_height="match_parent">
// ...
<ListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="#+id/splitView"
android:id="#+id/lv_player"
android:layout_alignParentTop="true"
android:background="#drawable/rounded_rectangle"/>
// ...
</FrameLayout>
However, I don't know how to use a shape to have a row partially colored or draw an icon. I can fill the shape with a color but then the rows are completely colored.
My second lead (vector)
I also found that I can use a vector as a background of my Listview. The advantage is that I can draw whatever I want using paths.
An example of a vector file:
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="64dp"
android:width="64dp"
android:viewportHeight="600"
android:viewportWidth="600" >
<path
android:name="w"
android:fillColor="#000000"
android:pathData="m 290,103 l-200,0 c -50,0 -50,-100 0,-100 l200,0 z"
/>
</vector>
I can easily create a path for the colored area of my rows and another for the icon. However, now the problem is that I don't know how to scale the size of the vector to the size of the line.
Do you know what would be the best option and how can I obtain the expected result?
Thanks in advance.
Consider using a CardView, it will help you to get the rounded corners. Inside the CardView create a RelativeLayout in order to get the rest of the stuff you've mentioned above.
Here is a good tutorial : Using the CardView | CodePath Android Cliffnotes
First of all you need to create your fancy item separately like having xml layout contain the description of the custom item :
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<TextView
android:id="#+id/optionName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginStart="10dp"
android:layout_weight="10"
android:fontFamily="sans-serif-medium"
android:text="#string/option"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="#android:color/white"
android:textStyle="bold" />
<CheckBox
android:id="#+id/activated"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center" />
</LinearLayout>
than create your adapter that will make your list have your layout as an item
public class ListOptionsAdapter extends BaseAdapter {
List<OptionsObject> Features = new ArrayList<OptionsObject>();
LayoutInflater inflater;
Context context;
public ListOptionsAdapter(List<OptionsObject> features, Context context) {
super();
Features = features;
inflater = LayoutInflater.from(context);
this.context = context;
}
#Override
public int getCount() {
return Features.size();
}
#Override
public OptionsObject getItem(int position) {
return Features.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = inflater.inflate(R.layout.item_list_view, parent, false);
holder = new ViewHolder();
holder.optionName = (TextView) convertView.findViewById(R.id.optionName);
holder.isActivate = (CheckBox) convertView.findViewById(R.id.activated);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
return convertView;
}
static class ViewHolder {
TextView optionName;
CheckBox isActivate;
}
}
after that as above i specified the name of the layout i will use as item in the method getView() and affect every element to the view holder
NB : in getView you have to specify the values for the elements that they will be displayed or leave them blank if u dont need
after that simply in my activity class i call my listview and my adapter
OptionList = (ListView) findViewById(R.id.optionList);
adapter = new ListOptionsAdapter(Features, getApplicationContext(), this);
OptionList.setAdapter(adapter);

How to Enable and Disable Image button on Each List Item Click for Lazy Adapter [duplicate]

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 :)

Marking GridView item as selected

I'm trying to create an Icon selector. The icon selector activity opens once I click on an icon in Main activity:
Intent intent_open_icon_picker = new Intent(Activity_Add_Edit_Trip.this, Activity_Icon_Picker.class);
intent_open_icon_picker.putExtra("SELECTED_ICON", current_icon_position);
startActivityForResult(intent_open_icon_picker, Constants.Request_Codes.REQUEST_CODE_SET_TRIP_ICON);
current_icon_position by default is 0, setting the first icon in the array to the ImageView.
Then in row_grid.xml I have this code, for each row in GridView (notice the background):
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:background="#drawable/grid_color_selector"
android:clickable="false"
android:focusable="false"
android:orientation="vertical"
android:padding="5dp" >
<ImageView
android:id="#+id/image"
android:layout_width="60dp"
android:layout_height="60dp"
android:scaleType="fitCenter"
android:focusable="false"
android:clickable="false" >
</ImageView>
</LinearLayout>
And this is the #drawable/grid_color_selector:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#color/color_BLUE" android:state_pressed="true"/>
<item android:drawable="#color/color_BLUE" android:state_selected="true"/>
<item android:drawable="#color/color_WHITE"/>
</selector>
When the icon picker activity opens - I want automatically highlight (or mark as selected) the current icon (the one that I corresponds to current_icon_position that I pass in the Intent). So I tried a few things, but none seems to work. I tried to do this:
if(getIntent().getExtras()!=null)
{
curr_icon_position = getIntent().getExtras().getInt("SELECTED_ICON");
}
grid_view = (GridView) findViewById(R.id.gv_icons);
adapter = new GridView_Adapter(this, R.layout.row_grid, get_icons(), curr_icon_position);
grid_view.setAdapter(adapter);
**grid_view.setSelection(curr_icon_position);**
Then I tried to make a boolean flag in my Trip_Icon object and set it like that:
private ArrayList get_icons() {
final ArrayList arr_trip_icons = new ArrayList();
TypedArray imgs = getResources().obtainTypedArray(R.array.trip_icons_blac);
for (int i = 0; i < imgs.length(); i++) {
Bitmap bitmap = BitmapFactory.decodeResource(this.getResources(),
imgs.getResourceId(i, -1));
Trip_Icon current_icon = new Trip_Icon(bitmap);
**if(i==curr_icon_position)
{
current_icon.setSelected(true);
}**
arr_trip_icons.add(current_icon);
}
imgs.recycle();
return arr_trip_icons;
}
and in my adapter do something like that:
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
ViewHolder holder;
if (row == null) {
holder = new ViewHolder();
LayoutInflater inflater = ((Activity) context).getLayoutInflater();
row = inflater.inflate(layout_resource_id, parent, false);
holder.image = (ImageView) row.findViewById(R.id.image);
row.setTag(holder);
} else {
holder = (ViewHolder) row.getTag();
}
Trip_Icon icon = (Trip_Icon) data.get(position);
holder.image.setImageBitmap(icon.getImage());
**if(icon.isSelected())
{
row.setSelected(true);
}**
return row;
}
But as I said, I never see the icon highlighted.
Just to be clearer, this is what I want to do - if the current_icon_position is 0, then I want the first item in the GridView to be highlighted, like in the picture:
What am I doing wrong and how can I make a current icon be highlighted?
Eventually, after many, many tries and errors, looks like somehow I managed to solve this problem. Maybe this solution will be useful to somebody else:
First of all I added this line to my GridView:
android:choiceMode="singleChoice"
Then I added this line to my #drawable/grid_color_selector:
<item android:drawable="#color/color_BLUE" android:state_activated="true"/>
And finally in my icon picker activity I added this line, after the adapter was set to Grid_view:
grid_view.setItemChecked(curr_icon_position, true);
And curr_icon_position, as I stated in the question, is being passed as Intent extra.

Android ListView listSelector not working

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.

Categories

Resources