I have created a GridView that displays various Bitmaps . I want that when a user selects selects a cell its back ground color changes. This is what i am doing. My ImageAdapter extends BaseAdapter has the following lines of code in it the getView function
if(videoObjects.get(position).isSelected)
{
gridView.setBackgroundColor(Color.BLUE);
}
else
{
gridView.setBackgroundColor(Color.TRANSPARENT);
}
My GridView has a OnItemClickListener that has the following code in onItemClick.
userVideos.get(postion).isSelected=!userVideos.get(postion).isSelected;
videoBitmapsAdapter.notifyDataSetChanged();
This should toggle the boolean variable and then i redraw the adapter. But the selection does not work.
Kind Regards.
It might be better to use a selector as background with 2 states:
<selector>
<item state_selected="true" drawable="yourbg" />
<item state_selected="false" drawable="otherbg" />
</selector>
Then in your
onItemClick(View v, ViewGroup parent, int position){
if (this.previousSelectedView != null) this.previousSelectedView.setSelected(false);
v.setSelected(true);
}
That way, there is no need to invalidate the whole gridview. You'll have to keep a reference to the currently selected griditem, so you can deselect it when a different item is clicked.
(This code is not tested)
Related
I'm trying to change the background of a selected item in a gridview, so I used the following code to do that
gridview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
// Basically changes the boolean value of an object's variable to "true", this means it has been clicked on
Themes.themes.get((int)id).clicked= true;
// Reload the list
adapter.notifyDataSetChanged();
}
});
Then in the getview() method of my adapter class I use
if(theme.clicked)
convertView.setBackgroundColor(context.getResources().getColor(android.R.color.holo_green_dark));
Once I click on a item of my gridview its background color changes, but when I scroll down the background color of other cells in the gridview also changes. I tired using different methods to apply the onclick event (like using a selector) but nothing seems to be working.
Does someone know of a way to solve this issue ?
Thanks in advance !
This issue is because of recycling of views. You need to set the background color for unselected items also.
if(theme.clicked)
convertView.setBackgroundColor(context.getResources().getColor(android.R.color.holo_green_dark));
else {
//Set the default color here for unselected items
}
let's say you have a background in the drawable folder name selector_bg.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="#color/colorPrimaryPress"/>
<item android:drawable="#color/colorPrimary" />
</selector>
i supose you have a layout for the cellule of your gridView ?
if so set android:background="#drawable/selector_bg"
I have two TextViews and One ImageView in GridView and trying to change the background of ImageView when user clicks on it. I am able to change the background first time and after that if i click on it nothing is happening. Another issue is if I scroll down I see the background image of other images changing. I want to change the background of image at the specific position. Say If i click on first item image I want to change only for that image. Below is my code. Thanks in advance and I really appreciate your help.
GridView1.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View v, int position, long arg3) {
btnCheckImage1 = (ImageView)v.findViewById(R.id.btnCheckImaget);
if (btnCheckImage1.getDrawable() != v.getResources().getDrawable(R.drawable.compselection_checked_btn) ) {
btnCheckImage1.setBackgroundResource(R.drawable.compselection_checked_btn);
}
else if (btnCheckImage1.getDrawable() == v.getResources().getDrawable(R.drawable.compselection_checked_btn) ) {
btnCheckImage1.setBackgroundResource(R.drawable.compselection_btn);
}
}
});
You need to use the OBJECT.equals(OBJECT) method to compare the drawables.
btnCheckImage1 = (ImageView)v.findViewById(R.id.btnCheckImaget);
if (btnCheckImage1.getDrawable() != v.getResources().getDrawable(R.drawable.compselection_checked_btn) ) {
btnCheckImage1.setBackgroundResource(R.drawable.compselection_checked_btn);
}
Fires on every item click, so after the first click you won't notice a change unless you do the comparison correctly.
I want to change the background of image at the specific position.
Say If i click on first item image I want to change only for that
image.
For this issue u have to call yourGridViewAdapter.notifyDataSetChanged(); in onItemClick
trying to change the background of ImageView when user clicks on it.
For this u have to use selector in res folder create drawable folder in that folder create selector
code snippet
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#color/blue" android:state_selected="true"/>
<item android:drawable="#color/transparent"/>
</selector>
and in main layout's gridview set selector for gridview like tjis
android:listSelector="#drawable/your_selector"
i have a android listview. i want to change listview item background when i click one listview item.
and then previous selected item must go back to default background. this means only one item has to be selected.
i have searched it for a long time. i can change background of selected item using onItemClick()
but i can't change previous selected item. for example, if i select second item, it was changed. and then i select third item. oh my god! it is changed too! what can i do for this. how can i get the previous position?
here is my android code.
private class ListViewItemClickListener implements
AdapterView.OnItemClickListener {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
TextView title = (TextView) view.findViewById(R.id.title);
title.setBackgroundResource(R.drawable.list_shape);
}
}
You should use the built in methods of selecting items in a listview. Manually changing the background is prone to error as you have found.
Add this attribute to the root view in your listview item xml
android:background="?android:attr/activatedBackgroundIndicator"
then call setItemChecked(x, true) on your ListView where x is the position of the item you want to be selected.
Ensure your listview has a ChoiceMode set that allows selection (such as "SingleChoice")
When I have this in a similar example I have a global field named:
selectedListItem;
This would be updated in your onitemClickListener and the previous item would then have it's background returned to the default.
So to update your code:
private class ListViewItemClickListener implements
AdapterView.OnItemClickListener {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
//First update the previously selected item if one has been set
if(selectedListItem!=null){
TextView previousTitle = (TextView) selectedListItem.findViewById(R.id.title);
previousTitle.setBackgroundResource(R.drawable.list_default_background);
}
//Then update the new one
TextView title = (TextView) view.findViewById(R.id.title);
title.setBackgroundResource(R.drawable.list_shape);
selectedListItem = view;
}
}
So simply initalise selectedListItem as a field in your adapter with the onClickListener as an inner class and have your default background drawable instead of list_default_background .
Alternatively you can track the position numbers instead of the actual view.
EDIT:
To use this method for your list you will also have to keep track of an ID or object instance for your specific list item. In my own solution, in my ListAdapter's getView method I make sure only the list item that matches the ID/instance of the correct item is updated. With your code the way it is you will also find that when you scroll down the view at the same position in this list of visible items is also updated. This is because list view's refer to the list in sets of items, where each set corresponds to the items visible on the screen at any one time.
To update a singular, specific item you would be better suited to using a selector background or indicator as mentioned in the other answers.
HTH
You can change the ListView item colour on clicking it like below. Follow these steps.
(Remember, This is for Custom List View)
Create an XML file in Drawable Folder as Below:
<item android:drawable="#color/orange" android:state_focused="true"/>
<item android:drawable="#color/orange" android:state_pressed="true"/>
<item android:drawable="#drawable/listview"></item>
Choose your own resources.
While implementing Custom ListVIew, you'll have additional layout for Custom List Item design. Below is such an Example.
<ImageView
android:id="#+id/imageView1"
android:layout_width="60dp"
android:layout_height="60dp" />
<TextView
android:id="#+id/textView1"
android:layout_width="fill_parent"
android:layout_height="60dp"
android:layout_toRightOf="#+id/imageView1"
android:background="#drawable/listselect_picture"
android:gravity="center"
android:text="TextView"
android:textColor="#drawable/select_txtcolor"
android:textSize="16sp" />
In Above code I have put the set the XML file from Step 1 as "background" attribute. This will work as you want to.
Additionally if you want to change the text colour on ListItem selection as well, use below XML code and set that XML file as "TextColor" attribute.
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true" android:color="#android:color/white"/>
<item android:state_focused="true" android:color="#android:color/white"/>
<item android:state_pressed="true" android:color="#android:color/white"/>
<item android:color="#android:color/black"/>
</selector>
The code above will change the text color to while on selection and revert to original when unclicked.
I am using multiple choice ListView items. The user can select multiple items. So I wanted to highlight the items selected by the user by changing either the text color or background color of the list row. I have gone through stack overflows links but didn't get the proper solution. When I am trying to do it, it is randomly changing any unselected item background color. Help!!!
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
videocursor.moveToPosition(position);
v.setBackgroundColor(Color.parseColor("#80B7DBE8"));
SaveSelections();
}
That randomly changing background color is due to the reason that ListView recycles views in its list to avoid unnecessary memory consumptions. You need to provide your own custom adapter in which you need to override getView method and perform some checks to highlight only those list items who have some kind of flag set to true for background color
Far better than the above suggestions is to use a selector, also known as a state-list drawable. That way, the OS takes care of all of the business of color highlighting, etc.
more explicitly, take the following xml and save it under res/drawable as something like li_background.xml (I'm using images, but feel free to swap out colors as is appropriate to your situation)
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_focused="true"
android:drawable="#drawable/list_item_pressed" />
<item android:state_pressed="true"
android:drawable="#drawable/list_item_pressed" />
<item android:state_selected="true"
android:state_activated="true"
android:drawable="#drawable/list_item_selected" />
<item android:state_activated="true"
android:drawable="#drawable/list_item_selected" />
<item android:state_selected="true"
android:drawable="#android:color/black" />
<item android:drawable="#android:color/transparent" />
</selector>
and set the background of All ListItems in the ListView to R.drawable.li_background. if your listView is properly configured for multiple selections (android:choiceMode="multipleChoice" or listView.setChoiceMode(AbsListView.CHOICE_MODE_MULTIPLE); if you prefer) then android will take care of the rest. This stuff isn't well documented, I had a hard time finding the solution and I see similar questions all the time, but the relevant dos are here and here
Wagas is correct. In your adapter's getView, you are passed a View (called convertView by Eclipse's autocomplete). This is because ListViews recycle the views for each row. If you set a property for a given View, it will retain that property when it is recycled.
For this reason, you should never set the properties of anything in a given row's View outside the getView method of the Adapter backing the ListView.
There are a number of ways you could handle this, but the basic idea is that you want to set some piece of data that uses the position passed in to onItemClick to set a flag. Then check the flag in the Adapter's getView to decide how to set the background for the row's View.
For example, if only one item can be selected, you might just set a member variable, say mPosition on the Adapter itself to the position passed in to onItemClick, and then check in getView if position == mSelectedPosition to decide how to set the View. If multiple items can be selected, perhaps you set a member variable on each object contained in the Adapter.
You probably should override getView() in the adapter, and change the row background color in there.
An example:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView != null) {
if (mSelectedPositions.contains(position)) {
convertView.setBackgroundColor(Color.parseColor("#3fa9f5"));
} else {
convertView.setBackgroundColor(Color.parseColor("#ffffff"));
}
}
return super.getView(position, convertView, parent);
}
in onItemClick() just use adapter.notifyDataChange(); also set a flag to true;
in the getView() of your CustomAdapter use boolean flag to know whether the row was selected or not.
Then just check that flag and proceed as you want
i.e.,
if(flag){
v.setBackgroundColor(Color.parseColor("#80B7DBE8"));
}else{
v.setBackgroundColor(Color.parseColor("#FF0000"));
}
I have a ListView that opens another activity when an item row is clicked via a onItemClick listener.
I would like that row to stay in its pressed state from the time it is clicked to the time the screen switches to a new activity. I think this would be a clearer experience for the user and you see this kind of thing with most buttons that open/close dialogs or switch activities.
I tried setting view.setPressed(true) in the onItemClick() listener but it seems to get called just a moment after the press state changed back to normal because it flickers slightly.
For example:
mListView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
view.setPressed(true);
//start an activity
}
});
That code almost works except for the flicker (User presses the list item and it turns to its pressed state, then user lets go (completing the click) and it turns back to its normal state for a split second before turning back to the pressed state from the setPressed(true) call)
Any ideas?
Thanks
Edit: I should mention that I am using an xml drawable selector to define the normal, pressed, selected, etc states for the background of the list.
I had the exact same problem to much frustration!
It is, however, easily solved by substituting state_pressed with state_selected. The pressed state will still change rapidly before onItemClick() is called, but since your theme does not depend on state_pressed the flicker won't be visible. Once in onItemClick() you set state_selected and the item will stay selected without any flicker occurring.
Here's my selector:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Selected Item -->
<item android:state_selected="true"
android:drawable="#color/list_pressed" />
<!-- Default Item -->
<item android:state_selected="false"
android:drawable="#android:color/list_default" />
</selector>
And my onListItemClick(...):
#Override
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
v.setSelected(true);
//TODO: add further actions here
}
The best way you can do this before Android 3.0 is to use a custom state in a custom view or to change your view's background color from the adapter. Starting with Android 3.0 you can use the new state_activated to keep a list item selected.
From inside an Adapter you can reference the view you want to change the state on. Say you have a ListView with a title and a star (ie. favorite star) and you want that to stay "selected/pressed" when touched. Override your getView and do something like:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
final View view = super.getView(position, convertView, parent);
final ImageButton favorite = (ImageButton) view.findViewById(R.id.favorite);
favorite.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Log.d(TAG, "Star pressed...");
v.setSelected(!v.isSelected());
}
});
return view;
}
And your ImageButton layout should reference a drawable like this:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true" android:drawable="#android:drawable/star_big_on" />
<item android:state_pressed="true" android:drawable="#android:drawable/star_big_on" />
<item android:drawable="#android:drawable/star_big_off" />
</selector>
You are using xml for selector. check whether you have correctly given the state.
While you set view.setPressed(true) it will use the drawable that is set for the state android:state_pressed="true" like
<item android:state_pressed="true"
android:drawable="#color/gray" />
Have you already tried to use unscheduleDrawable in combination with drawableStateChanged
So you could maybe listen if the state changed and then immediately unschedule and set it back to pressed.
Maybe there isn't flickering anymore.
In this example the background is changed after the button is pressed in a list item.
http://androidforbeginners.blogspot.com/2010/03/clicking-buttons-in-listview-row.html
You can do a similar thing in onItemSelected() by manipulating View which has been passed to this call. Usually the view passed is a LinearLayout which contains children views such as textView.
Do not use the selector XML. Instead change the list item images manually. This way you will be able to control the duration of a particular image