Android drawSelectorOnTop 与 GridView

Posted

技术标签:

【中文标题】Android drawSelectorOnTop 与 GridView【英文标题】:Android drawSelectorOnTop with GridView 【发布时间】:2013-12-13 18:56:31 【问题描述】:

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

感谢您的帮助,

【问题讨论】:

【参考方案1】:

我认为你对setDrawSelectorOnTop(boolean) 有误解。这里引用的selectordrawable 是GridView 内部的selectordrawable。

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

setDrawSelectorOnTop(boolean) 与您在适配器中设置的选择器无关。无论你传递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 我自己使用它,它按预期工作。您是否尝试过遵循Joe's 的建议? @Zuko 我已经为我的答案添加了一个解决方法。请参阅上面的Edit 部分。【参考方案2】:

    尝试在 activity_collections.xml 文件中设置 xml attribute android:drawSelectorOnTop

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

    如果所有其他方法都失败了,您可能必须将 GridView 切换到其他视图,其中 setDrawSelectorOnTop() 被证明可以始终如一地工作。

【讨论】:

很遗憾,1 和 2 不起作用,您对已证明始终有效的替代视图有什么建议吗? @Zuko 查看 Gallery App 的源代码 - 它有一个 GridView 并完全满足您的需求。在 Gallery App 中,当您尝试从相册中选择多张图片时,您看到的效果与您想要达到的效果相似,对吧?那是他们在那里使用的 GridView,源代码是开放且可用的。

以上是关于Android drawSelectorOnTop 与 GridView的主要内容,如果未能解决你的问题,请参考以下文章

Android ListView常见配置说明

Android逆向系列文章— Android基础逆向

Android 逆向Android 权限 ( Android 逆向中使用的 android.permission 权限 | Android 系统中的 Linux 用户权限 )

Android 逆向Android 权限 ( Android 逆向中使用的 android.permission 权限 | Android 系统中的 Linux 用户权限 )

android 21 是啥版本

Android逆向-Android基础逆向(2-2)