为什么我的ListView项目被选中,但点击后没有突出显示?

时间:2015-05-13 11:44:34

标签: android listview android-listfragment

我正在使用 Master-Detail Flow 并使用由BaseAdapter定义的自定义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="@android:color/background_dark" /> <!-- Default Item --> <item android:state_selected="false" android:drawable="@android:color/white" /> </selector>

来解决它
ListView

在我的<?xml version="1.0" encoding="utf-8"?> <ListView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@id/android:list" android:choiceMode="singleChoice" android:layout_width="fill_parent" android:background="@layout/list_selected" android:layout_height="fill_parent" /> 布局中:

list_item_layout

特此我的<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" > <ImageView android:id="@+id/imageView1" android:layout_width="48dp" android:layout_height="48dp" android:layout_gravity="center" android:layout_marginLeft="20dp" android:scaleType="fitCenter" android:src="@drawable/datahora" /> <TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_marginLeft="20dp" android:fontFamily="sans-serif-light" android:text="TextView" android:textSize="20dp" /> </LinearLayout> xml文件:

CustomAdapter

这是我的public class CustomAdapter extends BaseAdapter { Context context; List<RowItem> rowItem; CustomAdapter(Context context, List<RowItem> rowItem) { this.context = context; this.rowItem = rowItem; } @Override public int getCount() { return rowItem.size(); } @Override public Object getItem(int position) { return rowItem.get(position); } @Override public long getItemId(int position) { return rowItem.indexOf(getItem(position)); } @Override public View getView(int position, View convertView, ViewGroup parent) { if (convertView == null) { LayoutInflater mInflater = (LayoutInflater) context .getSystemService(Activity.LAYOUT_INFLATER_SERVICE); convertView = mInflater.inflate(R.layout.list_item_layout, null); } ImageView imgIcon = (ImageView) convertView.findViewById(R.id.imageView1); TextView txtTitle = (TextView) convertView.findViewById(R.id.textView1); RowItem row_pos = rowItem.get(position); // setting the image resource and title imgIcon.setImageResource(row_pos.getIcon()); txtTitle.setText(row_pos.getTitle()); return convertView; } } 班级

ListFragment

我的Callback课程,用户点击似乎由public class ParametroListFragment extends ListFragment { String[] menutitles; TypedArray menuIcons; CustomAdapter adapter; private List<RowItem> rowItems; /** * The serialization (saved instance state) Bundle key representing the * activated item position. Only used on tablets. */ private static final String STATE_ACTIVATED_POSITION = "activated_position"; /** * The fragment's current callback object, which is notified of list item * clicks. */ private Callbacks mCallbacks = sDummyCallbacks; /** * The current activated item position. Only used on tablets. */ private int mActivatedPosition = ListView.INVALID_POSITION; /** * A callback interface that all activities containing this fragment must * implement. This mechanism allows activities to be notified of item * selections. */ public interface Callbacks { /** * Callback for when an item has been selected. */ public void onItemSelected(String id); } /** * A dummy implementation of the {@link Callbacks} interface that does * nothing. Used only when this fragment is not attached to an activity. */ private static Callbacks sDummyCallbacks = new Callbacks() { @Override public void onItemSelected(String id) { } }; /** * Mandatory empty constructor for the fragment manager to instantiate the * fragment (e.g. upon screen orientation changes). */ public ParametroListFragment() { } @Override public void onActivityCreated(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onActivityCreated(savedInstanceState); menutitles = getResources().getStringArray(R.array.titles); menuIcons = getResources().obtainTypedArray(R.array.icons); rowItems = new ArrayList<RowItem>(); for (int i = 0; i < menutitles.length; i++) { RowItem items = new RowItem(menutitles[i], menuIcons.getResourceId( i, -1)); rowItems.add(items); } adapter = new CustomAdapter(getActivity(), rowItems); setListAdapter(adapter); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { ListView listView = (ListView) inflater.inflate(R.layout.list_layout, null); return listView; } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } @Override public void onViewCreated(View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); // Restore the previously serialized activated item position. if (savedInstanceState != null && savedInstanceState.containsKey(STATE_ACTIVATED_POSITION)) { setActivatedPosition(savedInstanceState .getInt(STATE_ACTIVATED_POSITION)); } } @Override public void onAttach(Activity activity) { super.onAttach(activity); // Activities containing this fragment must implement its callbacks. if (!(activity instanceof Callbacks)) { throw new IllegalStateException( "Activity must implement fragment's callbacks."); } mCallbacks = (Callbacks) activity; } @Override public void onDetach() { super.onDetach(); // Reset the active callbacks interface to the dummy implementation. mCallbacks = sDummyCallbacks; } @Override public void onListItemClick(ListView listView, View view, int position, long id) { super.onListItemClick(listView, view, position, id); view.setSelected(true); // Notify the active callbacks interface (the activity, if the // fragment is attached to one) that an item has been selected. mCallbacks.onItemSelected(DummyContent.ITEMS.get(position).id); } @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); if (mActivatedPosition != ListView.INVALID_POSITION) { // Serialize and persist the activated item position. outState.putInt(STATE_ACTIVATED_POSITION, mActivatedPosition); } } /** * Turns on activate-on-click mode. When this mode is on, list items will be * given the 'activated' state when touched. */ public void setActivateOnItemClick(boolean activateOnItemClick) { // When setting CHOICE_MODE_SINGLE, ListView will automatically // give items the 'activated' state when touched. getListView().setChoiceMode( activateOnItemClick ? ListView.CHOICE_MODE_SINGLE : ListView.CHOICE_MODE_NONE); } private void setActivatedPosition(int position) { if (position == ListView.INVALID_POSITION) { getListView().setItemChecked(mActivatedPosition, false); } else { getListView().setItemChecked(position, true); } mActivatedPosition = position; } } 处理:

 <ControlTemplate.Triggers>
                            <Trigger Property="IsPressed" Value="true">
                                <Setter Property="Background" Value="Gray" TargetName="panel" />
                            </Trigger>
                            <Trigger Property="IsMouseOver" Value="true">
                                <Setter Property="Background" Value="LightGray" />
                            </Trigger>
                        </ControlTemplate.Triggers>

我认为这已经足够了,但我不知道为什么毕竟没有突出显示。有人可以帮忙吗?

2 个答案:

答案 0 :(得分:2)

在listview xml中添加以下行。

  android:drawSelectorOnTop="false"
  android:divider="@null"
  android:dividerHeight="0.0sp"
  android:listSelector="@android:color/darker_gray"

答案 1 :(得分:1)

尽管@jyomin为我的问题提供了解决方案,但它可能会产生一些错误:

  • 当用户滚动(向下或向上)足以隐藏所选项目时,它将返回未选择的状态。
  • 如果用户触摸屏幕(在任何地方),它将删除 ListView项目焦点。

即便如此(并测试),我决定为我的旧代码找到另一种解决方法,因为我不仅希望突出显示,而且激活 ListView项。

我发现我将背景行为设置在错误的位置。它应该在LinearLayout list_item_layout内的<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" android:background="@layout/list_selected" > <ImageView android:id="@+id/imageView1" android:layout_width="48dp" android:layout_height="48dp" android:layout_gravity="center" android:layout_marginLeft="20dp" android:scaleType="fitCenter" android:src="@drawable/datahora" /> <TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_marginLeft="20dp" android:layout_marginRight="10dp" android:fontFamily="sans-serif-light" android:text="TextView" android:textColor="@layout/text_selected" android:textSize="22dp" /> </LinearLayout> 之前设置:

View

只需将已激活的状态添加到@Override public void onListItemClick(ListView listView, View view, int position, long id) { super.onListItemClick(listView, view, position, id); view.setSelected(true); view.setActivated(true); // Notify the active callbacks interface (the activity, if the // fragment is attached to one) that an item has been selected. mCallbacks.onItemSelected(DummyContent.ITEMS.get(position).id); }

<?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="@android:color/holo_blue_light" />
    <item android:state_activated="true"
        android:drawable="@android:color/holo_blue_light" />

    <!-- Default Item -->
    <item android:state_selected="false"
        android:drawable="@android:color/white" />
</selector>

并定义了一个新的选择器:

LIKE

要走的路,马查多。 :)