Android中GridView的drawSelectorOnTop是什么意思?

8
我正在开发一个选项卡应用程序,其中的一个片段CollectionsFragment包含一个GridView,在每个插槽中都有一个ImageView。我想使用选择器来在用户点击其中一张图片时给出反馈。
我已经成功地实现了选择器,但是我的问题是选择器仅在图像的背景中绘制,我希望它能覆盖整个图像。我已经看到其他地方提到这个问题,但是被许多人选择的解决方案设置GridView的drawSelectorOnTop属性对我不起作用。
相关片段和适配器代码如下:
public class CollectionsFragment extends Fragment {
    @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
             View view = inflater.inflate(R.layout.activity_collections, container, false);
             // Grid view is inside the xml view inflated above
             GridView gridView = (GridView)view.findViewById(R.id.gridview);
             gridView.setDrawSelectorOnTop(true);
             ((GridView) gridView).setAdapter(new CustomGridViewAdapter(getActivity()));
             return view;
        }

        private class CustomGridViewAdapter extends BaseAdapter {
            @Override
            public View getView(int i, View view, ViewGroup viewGroup) {
                View v = view;
                ImageView picture;
                TextView name;

                if(v == null) {
                    v = inflater.inflate(R.layout.collections_item, viewGroup, false);
                    v.setTag(R.id.picture, v.findViewById(R.id.picture));
                    v.setTag(R.id.text, v.findViewById(R.id.text));
                }

                picture = (ImageView)v.getTag(R.id.picture);

                name = (TextView)v.getTag(R.id.text);

                Item item = (Item)getItem(i);
                name.setText(item.name);

                picture.setImageResource(item.drawableId);
                picture.setBackgroundResource(R.drawable.selector);

                return v;
            }
        }
}

完整的选择器如下:

<?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/buttonhighlight"/> <!-- pressed state -->
<item android:state_focused="true" 
      android:drawable="@color/buttonhighlight"/> <!-- focused state -->
<item android:drawable="@android:color/transparent"/> <!-- default state --> 
</selector>

感谢您的帮助。
2个回答

15

我认为你对setDrawSelectorOnTop(boolean)存在误解。这里提到的selector drawable是GridView内部使用的selector drawable。

即使在最简单的GridView实现中,当点击网格项时,会在其周围绘制蓝色边框。这是因为默认情况下,gridview自己的选择器被绘制在项目behind后面。如果调用setDrawSelectorOnTop(true),则选择器(蓝色)将在项目上方绘制。

但是,setDrawSelectorOnTop(boolean)与您在适配器中设置的选择器无关。无论您传递true还是false,ImageView的选择器行为都不会改变。

解决方案:

不要在适配器内设置每个ImageView的选择器,而是让GridView使用您的选择器drawable:

GridView gridView = (GridView)view.findViewById(R.id.gridview);
gridView.setDrawSelectorOnTop(true);

// Make GridView use your custom selector drawable
gridView.setSelector(getResources().getDrawable(R.drawable.selector));

现在,不再需要:
picture.setBackgroundResource(R.drawable.selector);

编辑:

虽然我不建议这样做(明显的开销),但它应该可以工作:

@Override
public View getView(int i, View view, ViewGroup viewGroup) {
    View v = view;
    ImageView picture;

    ....
    ....

    LayerDrawable ld = new LayerDrawable(new Drawable[] 

                           // Drawable from item
                           { getResources().getDrawable(item.drawableId), 

                           // Selector
                           getResources().getDrawable(R.drawable.selector)});

    // Set the LayerDrawable
    picture.setImageDrawable(ld);

    // Don't need this
    // picture.setBackgroundResource(R.drawable.selector);

    return v;
}

很不幸,这对我来说不起作用。现在,即使是没有跨越整个网格插槽的图像,也什么都不会发生。 - lbrendanl
@Zuko,这应该可以工作。我能想到的唯一错误可能是你应该使用gridView.setSelector(R.color.buttonhighlight));而不是在这个答案中的示例代码gridView.setSelector(getResources().getDrawable(R.drawable.selector)); - Joe
抱歉,我的错误..我现在看到你的问题中有一个selector.xml。我建议尝试使用R.color.buttonhighlight作为您的选择器只适用于故障排除,我猜 :) - Joe
@Zuko 我自己使用这个,它按预期工作。你试过遵循 Joe 的建议吗? - Vikram
@Zuko,我已经在我的答案中添加了一个解决方法,请参见上面的“编辑”部分。 - Vikram

2
  1. 尝试在activity_collections.xml文件中设置xml属性android:drawSelectorOnTop

  2. 尝试将gridView.setDrawSelectorOnTop(true);放置在gridView.setAdapter();之后,看看是否有帮助。有时候顺序很重要(奇怪)。

  3. 如果以上方法都无效,您可能需要将GridView更换为其他视图,在该视图中已经证明setDrawSelectorOnTop()能够始终正常工作。


1和2不幸没有起作用,你有什么替代方案建议吗?最好是一个已经被证明可以持续运行的视图。 - lbrendanl
@Zuko 看一下Gallery App的源代码 - 它有一个GridView,并且恰好可以满足你的需求。在Gallery App中,当你尝试从相册选择多张图片时,你看到的效果类似于你要实现的效果,对吗?那是他们在使用的GridView,源代码是公开并可用的。 - VJ Vélan Solutions

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接