Java Android drawSelectorOnTop与GridView

Java Android drawSelectorOnTop与GridView,java,android,android-gridview,android-selector,Java,Android,Android Gridview,Android Selector,我正在开发一个选项卡式应用程序,其中一个片段CollectionsFragment包含一个GridView,每个插槽中都有一个ImageView。我希望在用户单击其中一个图像时使用选择器向用户提供反馈 我已经成功地实现了选择器,但是,我的问题是选择器只是在图像的背景中绘制,但是我希望选择器能够绘制整个图像。我在别处看到过这个问题,但是,许多人选择的解决方案,设置GridView的drawSelectorOnTop属性,对我不起作用 包含相关适配器代码的相关片段: public class Col

我正在开发一个选项卡式应用程序,其中一个片段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>

谢谢你的帮助

  • 尝试在
    activity\u collections.xml
    文件中设置xml
    属性android:drawSelectorOnTop

  • 查看是否放置
    gridView.setDrawSelectorOnTop(true)
    gridView.setAdapter()之后帮助。有时,顺序很重要(奇怪)

  • 如果所有其他操作都失败,您可能必须将GridView切换到其他视图,在该视图中,setDrawSelectorOnTop()已被证明可以持续工作


  • HTH

    我认为您对
    setDrawSelectorOnTop(布尔值)
    的理解是错误的。此处引用的
    选择器
    可绘制是GridView的内部
    选择器
    可绘制

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

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

    解决方案:

    不要在适配器内的每个ImageView上设置选择器,而是让GridView使用选择器可绘制:

    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;
    }
    

    不幸的是,这对我不起作用。现在,即使没有跨越整个网格槽的图像也不会发生任何变化。@Zuko,这应该可以。我能想到的唯一一件事是,您可能犯了错误,那就是您应该使用
    gridView.setSelector(R.color.buttonhighlight))而不是示例代码
    gridView.setSelector(getResources().getDrawable(R.drawable.selector))在这个答案中完全正确。对不起,我错了。。我看到您的问题中现在有一个selector.xml。我建议您尝试使用
    R.color.buttonhighlight
    ,因为您的选择器只适用于故障排除,我想:)@Zuko我自己使用它,它可以正常工作。你试过遵循乔的建议吗?@Zuko我在回答中添加了一个变通方法。请参阅上面的
    Edit
    部分。不幸的是,1和2不起作用,您对替代视图有什么建议吗?经证明,替代视图一直有效?@Zuko查看Gallery应用程序的源代码-它有一个GridView,完全满足您的需要。在Gallery应用程序中,当您尝试从相册中选择多张图片时,您看到的效果与您尝试实现的效果相似,对吗?这是他们在那里使用的GridView,源代码是开放的和可用的。