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"
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 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.
Following scripts sets the color of (for example) ListItem position 1, but it also gives number 12 (11+1) a nice grey color. Is this some kind of bug in Android?
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
ListView.setSelection(arg2);
arg1.setBackgroundColor(Color.LTGRAY);
adapter.notifyDataSetChanged();
}
ListView recycles (reuses) the views. So you need to associate the background color with the data, not the view! Then, in getView() you have the chance to correctly set the background color based on the data.
#David Wasser is correct ... cell re-use is causing multiple listview rows to draw with gray background.
However, if you're trying to set your background based on SELECTION STATE, consider this technique:
// set single or multi-select on your list (CHOICE_MODE_SINGLE = single row selectable)
// do this in onCreate
listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
.
.
.
// in your onItemClick, set the checked state of the item
// you DO NOT need to call notifyDataSetChanged
listView.setItemChecked(position, true);
And, set the background on your listview cell layout to the built-in or a custom selector
BUILT-IN:
android:background="?android:attr/activatedBackgroundIndicator"
CUSTOM:
android:background="#drawable/myListBackground"
drawable/myListBackground.xml:
<?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/lightgray" />
<item android:drawable="#color/transparent" />
</selector>
the key is the state_activated entry, which will be used when the item is selected/checked. You can also specify colors for other states, the above example references colors from a colors.xml table.
For more details on this, please check out How does "?android:attr/activatedBackgroundIndicator" work?
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)
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