【问题标题】:How to set a background drawable on a clicked GridView item in Android?如何在 Android 中单击的 GridView 项目上设置背景可绘制对象?
【发布时间】:2011-11-23 17:04:12
【问题描述】:

我有一个带有一堆图标的GridView,我需要选择一个。选择我的意思是:

  • 我需要将可绘制的 id 存储到数据库中(这样我以后可以访问它)
  • 我需要在网格上绘制某种视觉提示,让用户知道当前选择了哪个图标

我发现了这个:
http://groups.google.com/group/android-developers/browse_thread/thread/f08a58167dbaa8c8

所以我猜setSelection 不在图片中,我不能用它来选择图标本身,也不能绘制视觉提示。我知道onItemClickListener 中的网格项位置,我可以将其保存为私有类变量。我最大的问题是绘制视觉提示。

我怎样才能做到这一点?如何在单击的项目上绘制视觉提示,如果用户单击不同的项目,以“取消绘制”该视觉提示并在新项目中重新绘制它?

【问题讨论】:

  • 我想看看这个问题的答案。我相信,如果你想要某种选择提示,你需要一个可聚焦的对象。但是,对于可聚焦对象,将 OnItemClickListener 附加到 GridView 不起作用。相反,您必须在适配器中的 getView() 处将 OnClickListener 单独附加到每个项目。
  • 我认为将OnClickListener 附加到每个项目实际上并不可行,不是吗?这可能是一个可能的解决方案,所以如果你能做到,你可以在下面做一个正确的答案。我不介意。

标签: android selecteditem android-gridview onitemclicklistener


【解决方案1】:

我相信,如果你想要某种选择提示,你需要一个可聚焦的对象。但是,对于可聚焦对象(例如按钮),将 OnItemClickListener 附加到 GridView 不起作用(如果我没记错的话)。相反,您必须在适配器的 getView() 中将 OnClickListener 单独附加到每个项目。

适配器:

// create a new ImageView for each item referenced by the Adapter
    public View getView(int position, View convertView, ViewGroup parent) {
        Button button;
        if (convertView == null) {  // if it's not recycled, initialize some attributes
            button = new Button(mContext);
            // set layout params (make sure its GridView.layoutParams)
            // and other stuff

        } 
        else {
            button = (Button) convertView;
        }

        button.setBackgroundResource(mThumbIds[position]); // mThumbIds hold Resource Ids
        button.setOnClickListener(new OnClickListener() {
           onClick(View v) {
             // store directly to database here, or send it with the activity with sharedPreferences (below)

             // We need an Editor object to make preference changes.
             // All objects are from android.context.Context
             SharedPreferences settings = getSharedPreferences("MY_PREFERENCE", 0);
             SharedPreferences.Editor editor = settings.edit();
             editor.putInt("button_id", mThumbIds[position]);

             // Commit the edits!
             editor.commit();
           } 
        });
        return button;
    }
}

在 Activity 端,保存按钮 onClickListener:

onClick(View v) {
// Restore preferences
       SharedPreferences settings = getSharedPreferences("MY_PREFERENCE", 0);
       int id = settings.getInt("button_id", -1);

       // now safe all stuff to database
}

可能缺少细节,因为 Button 是可聚焦的,但我认为应该这样做。此外,您将通过使用 .xml 定义的选择器资源来实现选择。然而,这应该在一个单独的问题中解决。

编辑 1: 实际上,现在我考虑一下,我不确定可绘制的 .xml(选择器)是否可以具有 ID。稍后我将不得不在家里实现它并尝试一下。

编辑 2: 我添加了 sharedPreference 部分

编辑 3: 添加了 sharedPreference 的活动端查询。

【讨论】:

  • 我明白你的意思知道,我只是不确定一件事。 GridView 只是我的 Activity 的一个元素,我还有其他东西,比如 EditText 小部件。然后是一个按钮,它负责将所有数据存储到数据库中,包括来自 GridView 项的 id。我不确定如何处理。
  • 所以您只想使用“保存”按钮存储信息?我相信,这将使答案超出问题的范围。也许您可以使用 sharedPreference 来保存项目 id,然后在活动中查询偏好。
  • “存储信息”部分根本不相关,我的意思是我需要将单击的 GridView 项目的位置存储在持有该 GridView 的 Activity 中的某个变量中。如果我有,那么保存就很简单了(我假设我正在学习 Android,但还没有达到那个部分)。但是您之前的回答(在第二次编辑之前)给了我一些我过去几个小时一直在研究的想法。我想我已经找到了解决问题的方法,我会在一个小时左右有机会时发布我自己的答案。
  • 那么只需在您的活动中查询 sharedPreference 即可。这很容易。
  • 我不喜欢做我不懂的事情。老实说,仅仅存储一个整数似乎太多了。
【解决方案2】:

在解决这个问题几个小时后,我想我终于找到了我正在寻找的解决方案。虽然答案几乎没有相关性,但对 Ian 解决方案的初步编辑帮助我找到了这个解决方案 :)

我不会解释我所做的一切,我认为这很不言自明。简单说几句:

  • 首先我尝试了view.Invalidate()view.postInvalidate() 而不是iconAdapter.notifyDataSetChanged(),但都没有成功。该文档指出,无效方法仅“要求”“在可能的情况下”重绘视图。

  • 我一直在寻找比合并两个可绘制对象更简单的解决方案。例如,在ImageView 背景上绘制图标,并将视觉提示作为图像。出于某种奇怪的原因,当滚动GridView 时,视觉提示开始随机显示在其他图标上。我不明白为什么,但是在背景图像之上的视觉提示对我来说非常有意义,ImageView 允许这样做,不需要额外的合并方法。但是,没有它我无法让它工作......

MyActivity.java

public class MyActivity extends Activity {
    private GridView mGridViewIcon;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        mGridViewIcon = (GridView)findViewById(R.id.gridview_icon);
        mGridViewIcon.setAdapter(new IconAdapter(this));

        mGridViewIcon.setOnItemClickListener(new GridView.OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                IconAdapter iconAdapter = (IconAdapter)parent.getAdapter();

                iconAdapter.setSelectedItemPosition(position);
                iconAdapter.notifyDataSetChanged();
            }

        });
    }

}

IconAdapter.java

public class IconAdapter extends BaseAdapter {

    private int mSelectedPosition;
    private Integer[] mThumbIds;
    private int mIconSize;
    private Context mContext;

    public IconAdapter(Context context) {
        mThumbIds = AppHelper.ICON_SET.keySet().iterator().next();
        mIconSize = context.getResources().getDimensionPixelSize(R.dimen.default_icon_size);
        mContext = context;
    }

    @Override
    public int getCount() {
        return mThumbIds.length;
    }

    @Override
    public Object getItem(int position) {
        return mContext.getResources().getDrawable(mThumbIds[position]);
    }

    @Override
    public long getItemId(int position) {
        return mThumbIds[position];
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ImageView imageView;

        if(convertView == null) {
            imageView = new ImageView(mContext);
            imageView.setLayoutParams(new GridView.LayoutParams(mIconSize, mIconSize));
        } else {
            imageView = (ImageView)convertView;
        }

        if(mSelectedPosition == position) {
            imageView.setImageDrawable(mergeDrawableLayers(mThumbIds[position],
                    R.drawable.ic_note_selected_mark));
        } else {
            imageView.setImageResource(mThumbIds[position]);
        }

        return imageView;
    }

    public void setSelectedItemPosition(int position) {
        mSelectedPosition = position;
    }

    private Drawable mergeDrawableLayers(int background, int overlay) {
        Drawable[] drawableLayers = new Drawable[2];

        drawableLayers[0] = mContext.getResources().getDrawable(background);
        drawableLayers[1] = mContext.getResources().getDrawable(overlay);

        return new LayerDrawable(drawableLayers);
    }

}

【讨论】:

    猜你喜欢
    • 2012-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多