setItemChecked not working on Gingerbread - android

I am using the following selector to change the appearance of text in a listView item:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="true"
android:color="#FFFFFFFF" /> <!-- checked -->
<item android:state_activated="true"
android:color="#FFFFFFFF" /> <!-- activated -->
<item android:state_pressed="true"
android:color="#FFFFFFFF" /> <!-- pressed -->
<item android:state_focused="true"
android:color="#FFFFFFFF" /> <!-- focused -->
<item android:color="#FF000000" /> <!-- default -->
</selector>
The entire selector works fine on later versions of Android (ICS, JB), but on Gingerbread, while the pressed_state item is being applied correctly, when I call setItemChecked on the listView, the state_checked item isn't applied.
The code I am using to set the item is as follows:
#Override
protected void onResume()
{
super.onResume();
getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
for (int index = 0; index < measureList.size(); index++)
{
if (measureList.get(index).getId() == appContext.getMeasureId())
{
getListView().setItemChecked(index, true);
}
}
}
and the xml used to set the selector is this:
<TextView
android:id="#+id/item_text"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:layout_marginTop="8dp"
android:layout_marginLeft="8dp"
android:paddingRight="10dp"
android:ellipsize="end"
android:layout_toRightOf="#id/item_thumb"
android:maxLines="1"
android:scrollHorizontally="true"
android:textStyle="bold"
android:textSize="16sp"
android:textColor="#color/selected_text_selector"
/>
Does anyone know why this happens? I haven't yet tested it out on versions of Android between GB and ICS, but will edit this post as soon as I do.

After a little searching, it seems to me the reason that the state_checked isn't expressed pre-Honeycomb is the fact that the setActive method on View is not available before API level 11. This means that the checked state is not propagated to the child views of my layout.
THE KEY:
Swap the TextView for a CheckedTextView
Propagate the checked state from the parent view to the children
1) Was a simple switch in the XML, and for 2) I modified the code in the answer linked to by Voicu to give the following:
public class CheckableRelativeLayout extends RelativeLayout implements Checkable
{
private boolean checked = false;
public CheckableRelativeLayout(Context context) {
super(context, null);
}
public CheckableRelativeLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
private static final int[] CheckedStateSet = {
R.attr.state_checked
};
#Override
protected void dispatchSetPressed(boolean pressed)
{
super.dispatchSetPressed(pressed);
setChecked(pressed);
}
#Override
public void setChecked(boolean checked) {
this.checked = checked;
for (int index = 0; index < getChildCount(); index++)
{
View view = getChildAt(index);
if (view.getClass().toString().equals(CheckedTextView.class.toString()))
{
CheckedTextView checkable = (CheckedTextView)view;
checkable.setChecked(checked);
checkable.refreshDrawableState();
}
}
refreshDrawableState();
}
public boolean isChecked() {
return checked;
}
public void toggle() {
checked = !checked;
refreshDrawableState();
}
#Override
protected int[] onCreateDrawableState(int extraSpace) {
final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);
if (isChecked()) {
mergeDrawableStates(drawableState, CheckedStateSet);
}
return drawableState;
}
#Override
public boolean performClick() {
return super.performClick();
}
}

Related

Android ListView selection background

Okay I'm going absolutely nuts with this. I have a ListView in mode singleChoice, when I click on it I set it to selected. And I set the background to a drawable with a selector (and I tried many states that could correspond to a selected item). However when I select it the background doesn't change and I dont get why. I visited dozens of forums for this but couldn't get an answer. Here's my code:
The ListView in my activity:
<com.gaetanl.aspa.ui.component.ExtensibleListView
android:id="#+id/payment_billing_address_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/item_selectable"
android:choiceMode="singleChoice"></com.gaetanl.aspa.ui.component.ExtensibleListView>
Its class:
public class ExtensibleListView extends ListView {
public ExtensibleListView(Context context) {
this(context, null);
}
public ExtensibleListView(Context context, AttributeSet attrs) {
this(context, attrs, android.R.attr.listViewStyle);
}
public ExtensibleListView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Log.d(this, "item " + position + " selected = " + view.isSelected());
view.setSelected(true);
Log.d(this, "selected = " + view.isSelected());
}
});
}
#Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
}
}
The selector:
<?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/colorPrimary" />
<item
android:state_active="true"
android:drawable="#color/colorPrimary" />
<item
android:state_checked="true"
android:drawable="#color/colorPrimary" />
<item
android:state_selected="true"
android:drawable="#color/colorPrimary" />
<item
android:drawable="#android:color/transparent" />
</selector>
Method I:
In your list adapter,create getter and setter methods for position.Then in getView method, compare the position as in below:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.list_item.xml, null);
holder = new ViewHolder(); holder.itemLayout(LinearLyout)convertView.findViewById(R.id.item_layout);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
if(position==getPosition()){
holder.itemLayout.setBackgroundColor(ContextCompat.getColor(context,R.color.back_ground_color));
}else{
holder.itemLayout.setBackgroundColor(ContextCompat.getColor(context,R.color.background_unselect));
}
return convertView;
}
public void setPosition(int posit) {
this.position = posit;
}
private int getPosition() {
return this.position;
}
Then in the activity , inside listView's onItemSelected() method: call the adapter's setPositionMethod:
list_view.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
mAdapter.setPosition(i);
mAdapter.notifyDataSetChanged();
}
#Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});
Just set the list selector to transparent ..that should do the job.
Method II:
Or may be ,You need a selector like below:
<?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/color_primary" >
</item>
<item
android:state_focused="true"
android:drawable="#color/color_primary" >
</item>
<item
android:state_selected="true"
android:drawablecolor="#color/color_primary" >
</item>
<item android:color="#color/#color/transparent" >
</item>
</selector>
then put list selector as #drawable/list_selector
But, if that doesn't work then I think you can set the background of item xml layout as
android:background="#drawable/list_selector"
Okay I found the answer. I was stupidly trying to set the ListView background (see code above). What I needed to do was, when creating adapter, to select a view for the items that incorporates variation for selected items. Android has one by default: simple_list_item_single_choice.
So here's the working code:
myListView = ((ListView) findViewById(R.id.listview_id));
ArrayAdapter<String> myAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_single_choice, myList);
myListView.setAdapter(myAdapter);
myListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
view.setSelected(true);
}
});
And then you have it, a list view with radio buttons on the right that check themselves when you click on em.
And here's the ListView in my layout.xml:
<ListView
android:id="#+id/listview_id"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:choiceMode="singleChoice">
</ListView>

Change background color and Font type to bold on item selected in Listview

What i have tried :
listview_selector_focussed.xml:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient
android:startColor="#008000"
android:endColor="#00FF00"
android:angle="90" />
</shape>
listview_selector_pressed.xml:
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient
android:startColor="#800000"
android:endColor="#FF0000"
android:angle="90" />
</shape>
listview_selector.xml:
<?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/listview_selector_focused" />
<item
android:state_pressed="true"
android:drawable="#drawable/listview_selector_pressed" />
</selector>
listview layout :
<ListView
android:listSelector="#color/listview_selector"
/>
I have tried this much.. but un-fortunately this thing wont work
I want to change the listview row color when i click and when i click on another row previous row must be deselected and regain original state
Adapter class :
public class ListViewAdapter extends BaseAdapter {
Context ctx;
ArrayList<HashMap<String, String>> arraylist;
LayoutInflater inflater;
TextView tvA, tvB;
String a, b;
String out;
ListViewAdapter(Context ctx, ArrayList<HashMap<String, String>> arraylist) {
this.ctx = ctx;
this.arraylist = arraylist;
}
#Override
public int getCount() {
return arraylist.size();
}
#Override
public Object getItem(int position) {
return arraylist.get(position);
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
inflater = (LayoutInflater) ctx
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View itemView = inflater.inflate(R.layout.listitem, parent, false);
tvA = (TextView) itemView.findViewById(R.id.tvA);
tvB = (TextView) itemView.findViewById(R.id.tvB);
tvA.setText(arraylist.get(position).get("a"));
a = arraylist.get(position).get("a");
b = arraylist.get(position).get("b");
return itemView;
}
listview adapter layout :
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#ffffff"
android:orientation="horizontal">
<TextView
android:padding="5dp"
android:id="#+id/tvA"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:minLines="2"
android:gravity="center_vertical"
android:text="Large Text"
android:textStyle="bold"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="#0052a5"
android:textSize="#dimen/font_large" />
<TextView
android:padding="5dp"
android:id="#+id/tvB"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="bottom"
android:text="Small Text"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="#0052a5" />
</LinearLayout>
a good answer might be this one
You can set the onItemClick listener on your listview and in your adapter's getView() style the line.
PS: you will need to import the line background layout inside the adapter and set his background :)
try to something like my code
public class ReportActivity extends ActionBarActivity {
ListView listview;
Context mContext;
DatabaseHandler dbHandler;
ArrayList<ReportModel> mlist;
ReportAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_report);
mContext=this;
listview=(ListView) findViewById(R.id.listView);
dbHandler=new DatabaseHandler(mContext);
mlist=dbHandler.getAllContacts();
Collections.reverse(mlist);
adapter = new ReportAdapter(mContext, R.layout.adapter_layout,
mlist);
// Binds the Adapter to the ListView
listview.setAdapter(adapter);
listview.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
// Capture ListView item click
listview.setMultiChoiceModeListener(new AbsListView.MultiChoiceModeListener() {
#Override
public void onItemCheckedStateChanged(ActionMode mode,
int position, long id, boolean checked) {
// Capture total checked items
final int checkedCount = listview.getCheckedItemCount();
// Set the CAB title according to total checked items
mode.setTitle(checkedCount + " Selected");
// Calls toggleSelection method from ListViewAdapter Class
adapter.toggleSelection(position);
}
#Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
switch (item.getItemId()) {
case R.id.delete:
// Calls getSelectedIds method from ListViewAdapter Class
SparseBooleanArray selected = adapter
.getSelectedIds();
// Captures all selected ids with a loop
for (int i = (selected.size() - 1); i >= 0; i--) {
if (selected.valueAt(i)) {
ReportModel selecteditem = adapter
.getItem(selected.keyAt(i));
// Remove selected items following the ids
adapter.remove(selecteditem);
dbHandler.deleteContact(selecteditem.getId());
}
}
// Close CAB
mode.finish();
return true;
default:
return false;
}
}
#Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
mode.getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
#Override
public void onDestroyActionMode(ActionMode mode) {
// TODO Auto-generated method stub
adapter.removeSelection();
}
#Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
// TODO Auto-generated method stub
return false;
}
});
}
}
}
create xml file activity_main.xml in menu folder........
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="#+id/delete"
android:title="delete"/>
</menu>

How to let the Spinner items appear below itself when being clicked and with full width, like on G+ app

background
Google plus has a spinner-like view that shows a lot of items, but all of them appear below itself:
I need to mimic this in my own spinner (that's what I was told), but as of recently, Material-Design guidelines say (here) the Spinner should put its items on top of itself, and that's what the support library does for it.
The problem
I can't find a way to revert this behavior. I've tried changing the style of the Spinner, and also searched about this on the Internet (and here).
The questions
How do I let the spinner have its items below (or above instead, if needed), just as was done before Material Design, yet like on G+, so that they take full width?
Is the G+ Spinner a special kind? Does it have a name? Is it mentioned anywhere in the guidelines ? Maybe something that I can use instead of the normal spinner?
OK, the solution for the Spinner of how to put the items below itself, is to just add this:
<Spinner
...
android:overlapAnchor="false" />
Seems to work even on Kitkat, and not just on Lollipop, so my guess is that it should work on previous versions too.
However, I still would like to know how it works on G+, and if there are tutorials/samples for whatever it is that I see there.
I don't know, for example, how to make the window not appear like a window.
I've tried this:
android:dropDownWidth="match_parent"
android:popupBackground="#FFffffff"
android:popupElevation="0px"
but it doesn't help, as the right area is not covered by the spinner items.
I also tried using a TextView that looks like a spinner, and create a PopupMenu for it, but I still get the same issues:
PopupMenu popupMenu = new PopupMenu(getActivity(), v, Gravity.NO_GRAVITY, R.attr.popupMenuStyle, R.style.PopupMenuFullWidthStyle);
<style name="PopupMenuFullWidthStyle" parent="#style/Widget.AppCompat.PopupMenu">
<!--<item name="android:dropDownWidth">match_parent</item>-->
<item name="android:popupBackground">#FFFFFFFF</item>
</style>
It doesn't do anything using the styles.
Full solution
Since it's quite hard to customize the PopupMenu the way that I was instructed, I've made a full solution for it. Here are the relevant parts of it:
This will trigger showing the spinner's popup (and in fact act as a spinner) :
<com.example.user.myapplication.FullSizeFakeSpinner
android:id="#+id/spinner"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/spinner_selector"
android:gravity="start|center_vertical"
android:minHeight="44dp"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:text="Fake Spinner"
tools:ignore="UnusedAttribute"/>
MainActivity.java
    private static final String[] ITEMS = {"Item 0", "Item 1"};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FullSizeFakeSpinner spinner = (FullSizeFakeSpinner) findViewById(R.id.spinner);
spinner.setItems(ITEMS);
}
FullSizeFakeSpinner
public class FullSizeFakeSpinner extends TextView {
private String[] mItems;
private int mSelectedItemPosition = -1;
private PopupWindow mPopupWindow;
private boolean mInitialized = false;
private OnItemClickListener mOnItemSelectedListener;
public interface OnItemClickListener {
void onItemClick(FullSizeFakeSpinner parent, View clickedView, int position, String item);
void onNothingSelected(FullSizeFakeSpinner parent);
}
public FullSizeFakeSpinner(final Context context) {
super(context);
init(context);
}
public FullSizeFakeSpinner(final Context context, final AttributeSet attrs) {
super(context, attrs);
init(context);
}
public FullSizeFakeSpinner(final Context context, final AttributeSet attrs, final int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
#Override
public Parcelable onSaveInstanceState() {
Parcelable superState = super.onSaveInstanceState();
SavedState ss = new SavedState(superState);
ss.mSelectedItemPosition = this.mSelectedItemPosition;
ss.mItems = mItems;
return ss;
}
#Override
public void onRestoreInstanceState(Parcelable state) {
if (!(state instanceof SavedState)) {
super.onRestoreInstanceState(state);
return;
}
SavedState ss = (SavedState) state;
super.onRestoreInstanceState(ss.getSuperState());
setItems(ss.mItems);
setSelectedItemPosition(ss.mSelectedItemPosition);
}
public String[] getItems() {
return mItems;
}
public void setItems(final String[] items) {
mItems = items;
if (mItems != null && mSelectedItemPosition >= 0 && mSelectedItemPosition < mItems.length)
setText(mItems[mSelectedItemPosition]);
}
public int getSelectedItemPosition() {
return mSelectedItemPosition;
}
public void setSelectedItemPosition(final int selectedItemPosition) {
mSelectedItemPosition = selectedItemPosition;
if (mItems != null && mSelectedItemPosition >= 0 && mSelectedItemPosition < mItems.length)
setText(mItems[mSelectedItemPosition]);
}
public void setOnItemSelectedListener(OnItemClickListener onItemSelectedListener) {
mOnItemSelectedListener = onItemSelectedListener;
}
#Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
if (mPopupWindow != null)
mPopupWindow.dismiss();
}
protected void init(final Context context) {
if (mInitialized)
return;
mInitialized = true;
setSaveEnabled(true);
setOnClickListener(new OnClickListener() {
#Override
public void onClick(final View v) {
if (mItems == null)
return;
LayoutInflater layoutInflater = LayoutInflater.from(context);
final View popupView = layoutInflater.inflate(R.layout.spinner_drop_down_popup, null, false);
final LinearLayout linearLayout = (LinearLayout) popupView.findViewById(android.R.id.list);
linearLayout.setOrientation(LinearLayout.VERTICAL);
mPopupWindow = new PopupWindow(popupView, LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
mPopupWindow.setOutsideTouchable(true);
mPopupWindow.setTouchable(true);
mPopupWindow.setBackgroundDrawable(new ColorDrawable(0));
mPopupWindow.setFocusable(true);
final AtomicBoolean isItemSelected = new AtomicBoolean(false);
for (int i = 0; i < mItems.length; ++i) {
final String item = mItems[i];
final int position = i;
View itemView = layoutInflater.inflate(android.R.layout.simple_list_item_1, linearLayout, false);
itemView.setBackgroundResource(R.drawable.listview_white_selector);
itemView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
((TextView) itemView.findViewById(android.R.id.text1)).setText(item);
linearLayout.addView(itemView, linearLayout.getChildCount() - 1);
itemView.setOnClickListener(new OnClickListener() {
#Override
public void onClick(final View v) {
isItemSelected.set(true);
mPopupWindow.dismiss();
mSelectedItemPosition = position;
setText(item);
if (mOnItemSelectedListener != null)
mOnItemSelectedListener.onItemClick(FullSizeFakeSpinner.this, v, position, item);
}
});
}
popupView.findViewById(android.R.id.empty).setOnClickListener(new OnClickListener() {
#Override
public void onClick(final View v) {
mPopupWindow.dismiss();
}
});
mPopupWindow.setOnDismissListener(new OnDismissListener() {
#Override
public void onDismiss() {
setViewBackgroundWithoutResettingPadding(FullSizeFakeSpinner.this, R.drawable.spinner_selector);
if (!isItemSelected.get() && mOnItemSelectedListener != null)
mOnItemSelectedListener.onNothingSelected(FullSizeFakeSpinner.this);
}
});
// optional: set animation style. look here for more info: http://stackoverflow.com/q/9648797/878126
mPopupWindow.showAsDropDown(v, 0, 0);
setViewBackgroundWithoutResettingPadding(FullSizeFakeSpinner.this, R.drawable.spinner_opened_selector);
}
});
}
public static void setViewBackgroundWithoutResettingPadding(final View v, final int backgroundResId) {
final int paddingBottom = v.getPaddingBottom(), paddingLeft = v.getPaddingLeft();
final int paddingRight = v.getPaddingRight(), paddingTop = v.getPaddingTop();
v.setBackgroundResource(backgroundResId);
v.setPadding(paddingLeft, paddingTop, paddingRight, paddingBottom);
}
//////////////////////////////////////
//SavedState//
//////////////
static class SavedState extends BaseSavedState {
private String[] mItems;
private int mSelectedItemPosition = -1;
SavedState(Parcelable superState) {
super(superState);
}
private SavedState(Parcel in) {
super(in);
this.mItems = in.createStringArray();
mSelectedItemPosition = in.readInt();
}
#Override
public void writeToParcel(Parcel out, int flags) {
super.writeToParcel(out, flags);
out.writeStringArray(mItems);
out.writeInt(mSelectedItemPosition);
}
//required field that makes Parcelables from a Parcel
public static final Parcelable.Creator<SavedState> CREATOR =
new Parcelable.Creator<SavedState>() {
public SavedState createFromParcel(Parcel in) {
return new SavedState(in);
}
public SavedState[] newArray(int size) {
return new SavedState[size];
}
};
}
}
That's it about the code, but there are also some drawable resources too:
There should be a "spinner" image file that's like "abc_spinner_mtrl_am_alpha" of the support library, and has the color that you wish to use. Not sure how to use tint for it on pre-Lollipop, so it's better to just create the file with the color that you use.
colors:
<color name="listview_pressed">#FFE2E2E2</color>
<color name="listview_focused">#FF7dbcd3</color>
<color name="listview_checked">#FFededed</color>
listview_white_selector.xml :
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"><shape>
<solid android:color="#color/listview_pressed" />
</shape></item>
<item android:state_focused="true"><shape>
<solid android:color="#color/listview_focused" />
</shape></item>
<item android:state_checked="true"><shape>
<solid android:color="#color/listview_checked" />
</shape></item>
<item android:state_selected="true"><shape>
<solid android:color="#color/listview_checked" />
</shape></item>
<item android:drawable="#android:color/white"/>
</selector>
listview_white_selector.xml v21 :
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="#color/listview_pressed">
<item android:id="#android:id/mask">
<color
android:id="#android:id/mask"
android:color="#color/listview_pressed"/>
</item>
<item android:drawable="#drawable/listview_ripple_white_background_selector"/>
</ripple>
spinner_selector.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true">
<shape>
<solid android:color="#color/listview_pressed"/>
</shape>
</item>
<item android:state_focused="true">
<shape>
<solid android:color="#color/listview_focused"/>
</shape>
</item>
<item android:state_checked="true">
<shape>
<solid android:color="#color/listview_checked"/>
</shape>
</item>
<item android:state_selected="true">
<shape>
<solid android:color="#color/listview_checked"/>
</shape>
</item>
<item android:drawable="#android:color/transparent"/>
</selector>
</item>
<item android:drawable="#drawable/spinner"/>
</layer-list>
spinner_selector.xml (v21)
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="#color/listview_pressed">
<item android:drawable="#drawable/spinner"/>
<item android:id="#android:id/mask">
<color
android:id="#android:id/mask"
android:color="#color/listview_pressed"/>
</item>
<item android:drawable="#drawable/listview_ripple_background_selector"/>
</ripple>
listview_ripple_white_background_selector:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="true"><shape>
<solid android:color="#color/listview_checked" />
</shape></item>
<item android:state_selected="true"><shape>
<solid android:color="#color/listview_checked" />
</shape></item>
<item android:drawable="#android:color/white"/>
</selector>
listview_ripple_background_selector:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="true"><shape>
<solid android:color="#color/listview_checked" />
</shape></item>
<item android:state_selected="true"><shape>
<solid android:color="#color/listview_checked" />
</shape></item>
<item android:drawable="#android:color/transparent"/>
</selector>
spinner_drop_down_popup
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">
<LinearLayout
android:id="#android:id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical">
<View
android:id="#android:id/empty"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#33000000"/>
</LinearLayout>
</ScrollView>

Android ListView does not gets selected when an OnClickListener is set

I am using Listview with custom Adapter and a selector which I have set as background of the listview row item parent layout. When I am not setting OnClick listener to the parent layout of the listview item, the selector is working fine and the row gets selected.
But as soon as I am setting OnClick listener to the parent layout of the listview item , the selector is not working. I don't want to use onItemClickListener as I have to take care of certain things from the ListView Adapter.
I have been searching for this for hours but didn't got any clue.
Please help.
Thanks
My Custom Adapter class
public class CustomAdapter extends BaseAdapter {
private final String[] mNotificationList;
private static LayoutInflater inflater = null;
private Activity mActivity;
public CustomAdapter(Activity activity,String[] data) {
mActivity = activity;
mNotificationList = data;
inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
if(mNotificationList == null){
return 0;
}
else{
return mNotificationList.length;
}
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int id) {
return id;
}
#Override
public View getView(final int position, View converterView, ViewGroup parent) {
if (converterView == null){
converterView = inflater.inflate(R.layout.notification_list_row, null);
}
NotificationListHolder listRowHolder = (NotificationListHolder)converterView.getTag();
if(listRowHolder==null) {
listRowHolder = new NotificationListHolder();
initializeView(listRowHolder,converterView);
}
bindView(listRowHolder,mNotificationList[position]);
return converterView;
}
private void bindView(NotificationListHolder listRowHolder, String notificationDetails) {
listRowHolder.articleName.setText(notificationDetails);
listRowHolder.parentLayout.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(mActivity, "TOAST",Toast.LENGTH_SHORT).show();
}
});
}
private void initializeView(NotificationListHolder listRowHolder,View converterView) {
listRowHolder.parentLayout = (LinearLayout) converterView.findViewById(R.id.notificationlist_row_layout);
listRowHolder.articleName = (TextView) converterView.findViewById(R.id.article_text);
converterView.setTag(listRowHolder);
}
public static class NotificationListHolder{
public LinearLayout parentLayout;
public TextView articleName;
}
}
list row item xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/notificationlist_row_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/list_selector" >
<TextView
android:id="#+id/article_text"
android:layout_width="wrap_content"
android:layout_height="50dp"
android:layout_alignParentLeft="true"
android:layout_marginRight="40dp"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="#android:color/black"
android:textStyle="bold" />
<TextView
android:id="#+id/text"
android:layout_width="wrap_content"
android:layout_height="50dp"
android:layout_alignParentLeft="true"
android:layout_marginRight="40dp"
android:text="second view"
android:layout_below="#+id/article_text"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="#android:color/black"
android:textStyle="bold" />
</RelativeLayout>
list selector xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_selected="true"
android:drawable="#color/msg_read_bg" />
<item
android:state_pressed="true"
android:drawable="#color/msg_read_bg" />
<item
android:state_activated="true"
android:drawable="#color/msg_read_bg" />
<item
android:state_active="true"
android:drawable="#color/msg_read_bg" />
<item
android:state_focused="true"
android:drawable="#color/msg_read_bg" />
<item android:drawable="#android:color/white" />
</selector>

HorizontalListview with image select and unselect

i am getting problem in image select/unselect in listiview.
in my case,
ByDefault->image color(Yellow)
First click->image color(Orange)
Second click->image color(Yellow)
If user click on over way then perfect,but when user first time click on first image and second time click on second image then both image color is orange(that's problem).
In my case only one image color is orange(means selected) at a time.
If you only support HoneyComb and above, it'll easy. Create a StateListDrawable and set it to list view item's background.
selector.xml
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_activated="true" android:drawable="#drawable/item_focus" />
<item android:drawable="#android:color/transparent" />
</selector>
listview item's layout
<ImageView
android:id="#+id/image"
android:layout_width="100dp"
android:layout_height="100dp"
android:padding="5dp" />
and the last, set your listview choice mode to SINGLE
list.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
2. If you manage to support pre HoneyComb, you will have to write your own layout implement checkable. You do this in order to work-out using checked state. Let take an example with LinearLayout(you can do the same with others).
package com.example.listviewactivestate;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.widget.Checkable;
import android.widget.LinearLayout;
public class CustomLinearLayout extends LinearLayout implements Checkable {
private static final int[] CHECKED_STATE_SET = { android.R.attr.state_checked };
private boolean checked = false;
public CustomLinearLayout (Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomLinearLayout (Context context) {
super(context);
}
#Override
public boolean isChecked() {
return checked;
}
#Override
public void setChecked(boolean checked) {
this.checked = checked;
refreshDrawableState();
// Propagate to childs
final int count = getChildCount();
for (int i = 0; i < count; i++) {
final View child = getChildAt(i);
if (child instanceof Checkable) {
((Checkable) child).setChecked(checked);
}
}
}
#Override
protected int[] onCreateDrawableState(int extraSpace) {
final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);
if (isChecked()) {
mergeDrawableStates(drawableState, CHECKED_STATE_SET);
}
return drawableState;
}
#Override
public void toggle() {
this.checked = !this.checked;
}
}
Use this custom view in xml
<?xml version="1.0" encoding="utf-8"?>
<com.example.listviewactivestate.CustomLinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#drawable/selector"
>
<ImageView
android:id="#+id/image"
android:layout_width="100dp"
android:layout_height="100dp"
android:padding="5dp" />
</com.example.listviewactivestate.CustomLinearLayout >
Change state_activated to state_checked
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="true" android:drawable="#drawable/item_focus" />
<item android:drawable="#android:color/transparent" />
</selector>
Also set listview choice mode to SINGLE. If it does not work, add onItemClickEvent like this
list.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// TODO Auto-generated method stub
list.setItemChecked(position, true);//make sure click item is set to checked.
}
});

Categories

Resources