Question

So, I have a ListFragment with a custom layout which has a custom CursorAdapter that passes custom views to the ListView. The ListView has its choice mode set as MultiChoiceModal. However, selected items are never highlighted, whether I'm selecting one item in normal mode or several in Action Mode. To solve this, I tried a Selector.

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="@android:color/holo_blue_dark"
        android:state_pressed="true" />
    <item android:color="@android:color/holo_blue_light"
        android:state_checked="true" />
    <item android:color="@android:color/holo_blue_bright"
        android:state_selected="true" />
</selector>

Hoowever, applying this to the ListView as the list's List Selector just leads to the app crashing and this error when I try to run it:

04-04 15:01:41.196: E/AndroidRuntime(849): FATAL EXCEPTION: main
04-04 15:01:41.196: E/AndroidRuntime(849): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.mowdowndevelopments.vault/com.mowdowndevelopments.vault.AccountListActivity}: android.view.InflateException: Binary XML file line #9: Error inflating class android.widget.ListView
04-04 15:01:41.196: E/AndroidRuntime(849):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2180)
04-04 15:01:41.196: E/AndroidRuntime(849):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
04-04 15:01:41.196: E/AndroidRuntime(849):  at android.app.ActivityThread.access$600(ActivityThread.java:141)
04-04 15:01:41.196: E/AndroidRuntime(849):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
04-04 15:01:41.196: E/AndroidRuntime(849):  at android.os.Handler.dispatchMessage(Handler.java:99)
04-04 15:01:41.196: E/AndroidRuntime(849):  at android.os.Looper.loop(Looper.java:137)
04-04 15:01:41.196: E/AndroidRuntime(849):  at android.app.ActivityThread.main(ActivityThread.java:5041)
04-04 15:01:41.196: E/AndroidRuntime(849):  at java.lang.reflect.Method.invokeNative(Native Method)
04-04 15:01:41.196: E/AndroidRuntime(849):  at java.lang.reflect.Method.invoke(Method.java:511)
04-04 15:01:41.196: E/AndroidRuntime(849):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
04-04 15:01:41.196: E/AndroidRuntime(849):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
04-04 15:01:41.196: E/AndroidRuntime(849):  at dalvik.system.NativeStart.main(Native Method)
04-04 15:01:41.196: E/AndroidRuntime(849): Caused by: android.view.InflateException: Binary XML file line #9: Error inflating class android.widget.ListView
04-04 15:01:41.196: E/AndroidRuntime(849):  at android.view.LayoutInflater.createView(LayoutInflater.java:613)
04-04 15:01:41.196: E/AndroidRuntime(849):  at com.android.internal.policy.impl.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:56)
04-04 15:01:41.196: E/AndroidRuntime(849):  at android.view.LayoutInflater.onCreateView(LayoutInflater.java:660)
04-04 15:01:41.196: E/AndroidRuntime(849):  at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:685)
04-04 15:01:41.196: E/AndroidRuntime(849):  at android.view.LayoutInflater.rInflate(LayoutInflater.java:746)
04-04 15:01:41.196: E/AndroidRuntime(849):  at android.view.LayoutInflater.inflate(LayoutInflater.java:489)
04-04 15:01:41.196: E/AndroidRuntime(849):  at android.view.LayoutInflater.inflate(LayoutInflater.java:396)
04-04 15:01:41.196: E/AndroidRuntime(849):  at com.mowdowndevelopments.vault.AccountListFragment.onCreateView(AccountListFragment.java:121)
04-04 15:01:41.196: E/AndroidRuntime(849):  at android.app.Fragment.performCreateView(Fragment.java:1695)
04-04 15:01:41.196: E/AndroidRuntime(849):  at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:861)
04-04 15:01:41.196: E/AndroidRuntime(849):  at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1035)
04-04 15:01:41.196: E/AndroidRuntime(849):  at android.app.FragmentManagerImpl.addFragment(FragmentManager.java:1137)
04-04 15:01:41.196: E/AndroidRuntime(849):  at android.app.Activity.onCreateView(Activity.java:4717)
04-04 15:01:41.196: E/AndroidRuntime(849):  at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:680)
04-04 15:01:41.196: E/AndroidRuntime(849):  at android.view.LayoutInflater.inflate(LayoutInflater.java:466)
04-04 15:01:41.196: E/AndroidRuntime(849):  at android.view.LayoutInflater.inflate(LayoutInflater.java:396)
04-04 15:01:41.196: E/AndroidRuntime(849):  at android.view.LayoutInflater.inflate(LayoutInflater.java:352)
04-04 15:01:41.196: E/AndroidRuntime(849):  at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:270)
04-04 15:01:41.196: E/AndroidRuntime(849):  at android.app.Activity.setContentView(Activity.java:1881)
04-04 15:01:41.196: E/AndroidRuntime(849):  at com.mowdowndevelopments.vault.AccountListActivity.onCreate(AccountListActivity.java:45)
04-04 15:01:41.196: E/AndroidRuntime(849):  at android.app.Activity.performCreate(Activity.java:5104)
04-04 15:01:41.196: E/AndroidRuntime(849):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)
04-04 15:01:41.196: E/AndroidRuntime(849):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144)
04-04 15:01:41.196: E/AndroidRuntime(849):  ... 11 more
04-04 15:01:41.196: E/AndroidRuntime(849): Caused by: java.lang.reflect.InvocationTargetException
04-04 15:01:41.196: E/AndroidRuntime(849):  at java.lang.reflect.Constructor.constructNative(Native Method)
04-04 15:01:41.196: E/AndroidRuntime(849):  at java.lang.reflect.Constructor.newInstance(Constructor.java:417)
04-04 15:01:41.196: E/AndroidRuntime(849):  at android.view.LayoutInflater.createView(LayoutInflater.java:587)
04-04 15:01:41.196: E/AndroidRuntime(849):  ... 33 more
04-04 15:01:41.196: E/AndroidRuntime(849): Caused by: android.content.res.Resources$NotFoundException: File res/color/view_selector_background.xml from drawable resource ID #0x7f0a0000
04-04 15:01:41.196: E/AndroidRuntime(849):  at android.content.res.Resources.loadDrawable(Resources.java:1953)
04-04 15:01:41.196: E/AndroidRuntime(849):  at android.content.res.TypedArray.getDrawable(TypedArray.java:601)
04-04 15:01:41.196: E/AndroidRuntime(849):  at android.widget.AbsListView.<init>(AbsListView.java:772)
04-04 15:01:41.196: E/AndroidRuntime(849):  at android.widget.ListView.<init>(ListView.java:143)
04-04 15:01:41.196: E/AndroidRuntime(849):  at android.widget.ListView.<init>(ListView.java:139)
04-04 15:01:41.196: E/AndroidRuntime(849):  ... 36 more
04-04 15:01:41.196: E/AndroidRuntime(849): Caused by: org.xmlpull.v1.XmlPullParserException: Binary XML file line #4: <item> tag requires a 'drawable' attribute or child tag defining a drawable
04-04 15:01:41.196: E/AndroidRuntime(849):  at android.graphics.drawable.StateListDrawable.inflate(StateListDrawable.java:178)
04-04 15:01:41.196: E/AndroidRuntime(849):  at android.graphics.drawable.Drawable.createFromXmlInner(Drawable.java:885)
04-04 15:01:41.196: E/AndroidRuntime(849):  at android.graphics.drawable.Drawable.createFromXml(Drawable.java:822)
04-04 15:01:41.196: E/AndroidRuntime(849):  at android.content.res.Resources.loadDrawable(Resources.java:1950)
04-04 15:01:41.196: E/AndroidRuntime(849):  ... 40 more

It also causes Eclipse to complain:

org.xmlpull.v1.XmlPullParserException: Binary XML file line #3: <item> tag requires a 'drawable' attribute or child tag defining a drawable
    at android.graphics.drawable.StateListDrawable.inflate(StateListDrawable.java:178)
    at android.graphics.drawable.Drawable.createFromXmlInner(Drawable.java:885)
    at android.graphics.drawable.Drawable.createFromXml(Drawable.java:822)
    at com.android.layoutlib.bridge.impl.ResourceHelper.getDrawable(ResourceHelper.java:208)
    at android.content.res.BridgeTypedArray.getDrawable(BridgeTypedArray.java:782)
    at android.view.View.<init>(View.java:3330)
    at android.view.View.<init>(View.java:3259)
    at android.view.ViewGroup.<init>(ViewGroup.java:425)
    at android.widget.RelativeLayout.<init>(RelativeLayout.java:210)
    at sun.reflect.GeneratedConstructorAccessor64.newInstance(Unknown Source)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:525)
    at android.view.LayoutInflater.createView(LayoutInflater.java:587)
    at android.view.BridgeInflater.onCreateView(BridgeInflater.java:86)
    at android.view.LayoutInflater.onCreateView(LayoutInflater.java:660)
    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:685)
    at android.view.BridgeInflater.createViewFromTag(BridgeInflater.java:131)
    at android.view.LayoutInflater.inflate(LayoutInflater.java:466)
    at android.view.LayoutInflater.inflate(LayoutInflater.java:372)
    at com.android.layoutlib.bridge.impl.RenderSessionImpl.inflate(RenderSessionImpl.java:385)
    at com.android.layoutlib.bridge.Bridge.createSession(Bridge.java:332)
    at com.android.ide.common.rendering.LayoutLibrary.createSession(LayoutLibrary.java:325)
    at com.android.ide.eclipse.adt.internal.editors.layout.gle2.RenderService.createRenderSession(RenderService.java:440)
    at com.android.ide.eclipse.adt.internal.editors.layout.gle2.RenderPreview.renderSync(RenderPreview.java:560)
    at com.android.ide.eclipse.adt.internal.editors.layout.gle2.RenderPreview.access$5(RenderPreview.java:506)
    at com.android.ide.eclipse.adt.internal.editors.layout.gle2.RenderPreview$RenderJob.runInUIThread(RenderPreview.java:1230)
    at org.eclipse.ui.progress.UIJob$1.run(UIJob.java:95)
    at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:35)
    at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:135)
    at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:3529)
    at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3182)
    at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2701)
    at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2665)
    at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2499)
    at org.eclipse.ui.internal.Workbench$7.run(Workbench.java:679)
    at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
    at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:668)
    at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
    at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:124)
    at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
    at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
    at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
    at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:353)
    at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:180)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:629)
    at org.eclipse.equinox.launcher.Main.basicRun(Main.java:584)
    at org.eclipse.equinox.launcher.Main.run(Main.java:1438)
    at org.eclipse.equinox.launcher.Main.main(Main.java:1414)

I get the same complaints from Eclipse when applying the selector to the root layout of the custom view (specifically, as the background), so logic dictates I'd get a similar error. Is there something I'm doing wrong?

EDIT: Well, thanks to vArDo, there are no more crashes. But the selector doesn't actually do anything. Here's the xml for the list item's layout, for those who maybe can see how to actually get this to start working:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/itemLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <TextView
        android:id="@+id/NameView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:text="Name"
        android:textAppearance="?android:attr/textAppearanceLarge"
        tools:ignore="HardcodedText" />

    <TextView
        android:id="@+id/balanceView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_below="@+id/NameView"
        android:text="Balance"
        android:textAppearance="?android:attr/textAppearanceSmall"
        tools:ignore="HardcodedText" />

    <ImageView
        android:id="@+id/favStar"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:layout_marginRight="10dp"
        android:layout_marginTop="10dp"
        android:contentDescription="@string/accessFav"
        android:src="@android:drawable/btn_star_big_on"
        android:visibility="gone" />

</RelativeLayout>
Was it helpful?

Solution 2

Alright, clearly I should be digging through the source code more often. What I ended up doing was taking the root layout of my list item:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/itemLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

And added one attribute:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/itemLayout"
    android:background="?android:attr/activatedBackgroundIndicator"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

This added the behavior seen in android.R.layout.simple_list_item_activated_1 et al.

OTHER TIPS

In ListView the android:listSelector needs to be a drawable (see documentation), so each item tag in you XML selector file is required to have android:drawable in it. Simply change android:color to android:drawable (you can use the same values) and your current errors should be gone.

Your file after substitution should look like this:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@android:color/holo_blue_dark"
        android:state_pressed="true" />
    <item android:drawable="@android:color/holo_blue_light"
        android:state_checked="true" />
    <item android:drawable="@android:color/holo_blue_bright"
        android:state_selected="true" />
</selector>

One alternative but lengthier way of doing this is to manually set background color of listView's item in getView() method.

class CustomAdapter extends BaseAdapter{
...

int selectedID;

public void setSelectedId(int n)
{
selectedID = n;
}

public View getView(int position, View convertView, ViewGroup parent) {
....
if(position == selectedID)
convertView.setBackgroundColor(someColor);
return convertView;
}

And in listView's OnItemClickListener, add:

customAdapter.setSelectedId(position) 

Though this, method isn't that efficient, however it worked perfectly in my project. Also, avoid using static ViewHolder class or recycling views with this approach.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top