Can't add custom selector to ListView

爷,独闯天下 提交于 2019-12-24 06:36:03

问题


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>

回答1:


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>



回答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.




回答3:


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.



来源:https://stackoverflow.com/questions/15815328/cant-add-custom-selector-to-listview

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!