无法将自定义listSelector应用于ListView

时间:2014-06-23 02:37:41

标签: android android-listview

我现在已经完成了几个SO答案 Android listselector not visible in custom listview
ListView item background via custom selector

甚至遵循这一点(目前使用这种方法)
http://cyrilmottier.com/2011/08/08/listview-tips-tricks-3-create-fancy-listviews/

我甚至将drawSelectorOnTop设置为true

但是,我无法让listSelector工作。基本上,我在我的智慧结束。我想这与我的列表项目的制作方式有关?这是XML:

list_entry.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="5dp">

    <ImageButton android:id="@+id/contextMenuIcon"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/ic_action_overflow"
        android:background="@null"/>

    <TextView android:id="@+id/noteTitle"
        android:layout_alignParentLeft="true"
        android:layout_toLeftOf="@id/contextMenuIcon"
        android:layout_alignBottom="@id/contextMenuIcon"
        android:layout_height="wrap_content"
        android:layout_width="match_parent"
        android:layout_alignParentTop="true"
        android:textIsSelectable="false"
        android:ellipsize="end"
        android:singleLine="true"
        android:textSize="20sp"
        android:textColor="@android:color/black"/>

    <TextView android:id="@+id/noteCreationDate"
        android:layout_alignParentLeft="true"
        android:layout_alignParentBottom="true"
        android:layout_below="@id/noteTitle" 
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="18sp"
        android:textColor="#808080"/>

    <TextView android:id="@+id/notePrivacy"
        android:layout_alignParentRight="true"
        android:layout_alignParentBottom="true"
        android:layout_below="@id/contextMenuIcon"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="18sp"
        android:textColor="#808080" />

</RelativeLayout>    

list_selector_pressed.xml

<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
    <gradient android:endColor="#ffc579" android:startColor="#fb9d23" android:angle="90"></gradient>
</shape>  

list_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:endColor="#f7ddb8" android:startColor="#f5c98c" android:angle="90"></gradient>

</shape>  

list_selector.xml

<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:state_pressed="true" android:drawable="@drawable/list_selector_pressed" />
    <item android:state_focused="true" android:drawable="@drawable/list_selector_focused" />
    <item android:drawable="@android:color/transparent" />

</selector>

请告诉我如何使列表选择器正常工作!

3 个答案:

答案 0 :(得分:2)

您在列表项中使用ImageButton。因此,当您单击该项时,ImageButton将获得焦点。

但在你的情况下你设置ImageButton背景是

  android:background="@null"

它让你看不到焦点。如果删除此行,则可以看到问题。

要从列表项中获得焦点,可以在xml的根视图中使用此代码。

android:descendantFocusability="blocksDescendants"   

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:descendantFocusability="blocksDescendants" 
    android:padding="5dp">

    <ImageButton android:id="@+id/contextMenuIcon"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/ic_action_overflow"
        android:background="@null"/>

    <TextView android:id="@+id/noteTitle"
        android:layout_alignParentLeft="true"
        android:layout_toLeftOf="@id/contextMenuIcon"
        android:layout_alignBottom="@id/contextMenuIcon"
        android:layout_height="wrap_content"
        android:layout_width="match_parent"
        android:layout_alignParentTop="true"
        android:textIsSelectable="false"
        android:ellipsize="end"
        android:singleLine="true"
        android:textSize="20sp"
        android:textColor="@android:color/black"/>

    <TextView android:id="@+id/noteCreationDate"
        android:layout_alignParentLeft="true"
        android:layout_alignParentBottom="true"
        android:layout_below="@id/noteTitle" 
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="18sp"
        android:textColor="#808080"/>

    <TextView android:id="@+id/notePrivacy"
        android:layout_alignParentRight="true"
        android:layout_alignParentBottom="true"
        android:layout_below="@id/contextMenuIcon"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="18sp"
        android:textColor="#808080" />

</RelativeLayout>  

我使用你的xml创建一个快速测试,它正常工作。

public class MainActivity extends ActionBarActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if (savedInstanceState == null) {
            getSupportFragmentManager().beginTransaction().add(R.id.container, new PlaceholderFragment()).commit();
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {

        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    /**
     * A placeholder fragment containing a simple view.
     */
    public class PlaceholderFragment extends Fragment {

        public PlaceholderFragment() {
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            View rootView = inflater.inflate(R.layout.fragment_main, container, false);

            ListView list = (ListView)rootView.findViewById(R.id.list);

            ArrayList<MyItem> listItem = genListItem(20);
            MyAdapter adapter = new MyAdapter(MainActivity.this, android.R.layout.simple_list_item_1, listItem);
            list.setAdapter(adapter);


            return rootView;
        }

        private ArrayList<MyItem> genListItem(int size) {
            ArrayList<MyItem> listItem = new ArrayList<MainActivity.MyItem>();
            for (int i = 0; i < size; i++) {
                MyItem item = new MyItem();
                item.setName("item " + i);
                listItem.add(item);
            }

            return listItem;
        }
    }

    public static class MyItem{
        String Name;
        /**
         * @return the name
         */
        public String getName() {
            return Name;
        }
        /**
         * @param name the name to set
         */
        public void setName(String name) {
            Name = name;
        }


    }

    public class MyAdapter extends ArrayAdapter<MyItem>{

        private LayoutInflater inflator;
        private Context mContext;
        public MyAdapter(Context context, int resource, List<MyItem> objects) {
            super(context, resource, objects);
            mContext = context;
            inflator = ((Activity) context).getLayoutInflater();
        }

        @Override
        public View getView(final int position, View convertView, ViewGroup parent) {

            final ViewHolder holder;
            if (convertView == null) {
                convertView = inflator.inflate(R.layout.list_entry, null);
                holder = new ViewHolder();
                holder.Name = (TextView) convertView.findViewById(R.id.noteTitle);
                convertView.setTag(holder);
            } else {
                holder = (ViewHolder) convertView.getTag();
            }

            MyItem item = getItem(position);
            holder.Name.setText(item.getName());


            return convertView;
        }

        class ViewHolder {
            public TextView Name;
        }


    }

}

答案 1 :(得分:0)

根据我的经验,要使listSelector工作,您必须使用CheckedTextView作为List Item的根元素。

<?xml version="1.0" encoding="utf-8"?>
<!-- Added this view purposefully -->
<CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/text"
    android:layout_width="match_parent"
    android:layout_height="@dimen/_48dp"
    android:layout_centerVertical="true"
    android:background="@drawable/selector_liquidation"
    android:gravity="center_vertical|left"
    android:paddingBottom="@dimen/_15dp"
    android:paddingLeft="@dimen/_40dp"
    android:paddingRight="@dimen/_10dp"
    android:paddingTop="@dimen/_15dp"
    android:singleLine="true"
    android:textColor="@color/gray_999999"
    android:textSize="@dimen/font_18sp" />

我建议您首先尝试使用单个CheckedTextView,然后如果它有效,请使用列表项中Dummy按钮上的选择器,并设置要在getView中选择的按钮状态。

<强>更新

列表项

<?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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".ui.video.VideoPlayerActivity" >

    <RelativeLayout
        android:id="@+id/dummy"
        android:layout_width="match_parent"
        android:layout_height="@dimen/_100dp"
        android:gravity="center_vertical" >

        <Button
            android:id="@+id/bg_selector"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@drawable/selector_item"
            android:clickable="false"
            android:focusable="false" />

        <ImageButton
            android:id="@+id/contextMenuIcon"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_alignParentTop="true"
            android:background="@null"
            android:src="@drawable/ic_action_overflow" />

        <TextView
            android:id="@+id/noteTitle"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignBottom="@id/contextMenuIcon"
            android:layout_alignParentLeft="true"
            android:layout_alignParentTop="true"
            android:layout_toLeftOf="@id/contextMenuIcon"
            android:ellipsize="end"
            android:singleLine="true"
            android:textColor="@android:color/black"
            android:textIsSelectable="false"
            android:textSize="20sp" />

        <TextView
            android:id="@+id/noteCreationDate"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_alignParentLeft="true"
            android:layout_below="@id/noteTitle"
            android:textColor="#808080"
            android:textSize="18sp" />

        <TextView
            android:id="@+id/notePrivacy"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_alignParentRight="true"
            android:layout_below="@id/contextMenuIcon"
            android:textColor="#808080"
            android:textSize="18sp" />
    </RelativeLayout>

</RelativeLayout>

选择器就像这样

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_selected="true" android:drawable="@drawable/list_selector_pressed" />
    <item android:state_pressed="true" android:drawable="@drawable/list_selector_pressed" />
    <item android:state_focused="true" android:drawable="@drawable/list_selector_focused" />
    <item android:drawable="@android:color/transparent" />

</selector>

getView 中添加此代码。

@Override
        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder viewHolder;

            if (convertView == null) {
        ...

                convertView.setTag(viewHolder);
            }
            else {
                viewHolder = (ViewHolder) convertView.getTag();
            }

            if (mSelectedIndex == position) {
                viewHolder.bgSelector.setSelected(true);
            }
            else {
                viewHolder.bgSelector.setSelected(false);
            }


        ...

            return convertView;
        }

mSelectedIndex 是一个用于跟踪所选位置的int。它将始终具有所选索引。

答案 2 :(得分:0)

我不知道为什么,但随机的反复试验导致我这样做:

<?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/translucent_50_grey" />
    <item android:state_pressed="false" android:drawable="@android:color/transparent" />

    <item android:state_focused="true" android:drawable="@android:color/transparent" />
    <item android:state_focused="false" android:drawable="@android:color/transparent" />

    <item android:drawable="@android:color/transparent" />
</selector> 
瞧,瞧!这是工作。全屏和标题栏主题。