问题
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