如何设置单个gridview单元格的背景颜色

10

我有一个GridView,每个单元格都包含一些文本,我希望能够设置单个单元格的背景颜色。

我的GridView的XML如下:

<GridView android:id="@+id/students_grid"
          android:layout_width="fill_parent"
          android:layout_height="fill_parent"
          android:numColumns="6"
          android:gravity="center"
          android:stretchMode="columnWidth">
</GridView>

我这里的 GridView 代码是:

GridView gridView = (GridView) findViewById(R.id.students_grid);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, student_array);
gridView.setAdapter(adapter);

我曾希望能够使用以下代码设置单个单元格的背景颜色:

gridView.getChildAt(random_student).setBackgroundColor(Color.parseColor("#18A608"));

但是,这会抛出一个空指针异常,进一步检查发现gridview.getChildCount()返回0。我已经看到gridview.getCount正确返回网格视图中项目的数量,但这不能帮助我设置单个单元格的背景颜色。

有任何想法我接下来该怎么做?

3个回答

10
解决这个问题的关键是先理解 ListViewGridView 的工作原理。 GridView 会在你向上或向下滚动时创建和销毁子视图。如果在 GridView 中看不到一个项目,那就意味着它没有子视图,当用户实际滚动到它时才会创建。 GridView 使用适配器来创建视图,当滑出屏幕时,GridView 回收视图并要求适配器将这些被回收的视图重用于新的进入屏幕的视图。适配器通常会填充资源布局以创建新视图。

这意味着 GridView 每次想在屏幕上显示子视图时都会调用适配器的 getView(...)方法,可能会传递一个名为 convertView 的回收视图。

解决方案是覆盖 getView(...) 方法,调用 super 方法让适配器按照正常方式创建并填充数据源字符串数组的视图,但在我们将视图返回给 GridView 之前,在结尾处添加一些代码以设置视图的颜色。

new ArrayAdapter<String>(context, android.R.layout.simple_list_item_1, student_array) {
  @Override
  public View getView(int position, View convertView, ViewGroup parent) {
    View view = super.getView(position, convertView, parent);

    int color = 0x00FFFFFF; // Transparent
    if (someCondition) {
      color = 0xFF0000FF; // Opaque Blue
    }

    view.setBackgroundColor(color);

    return view;
  }
};

5
主要活动中,您需要创建十六进制颜色代码数组并将其传递给自定义适配器类。
public class MainActivity extends Activity {
GridView gridView;


    String[] gridColor ={

            "#008B8B",
            "#00FF00",
            "#48D1CC",
            "#556B2F",
            "#696969",
            "#6B8E23",
            "#8FBC8F",
            "#AFEEEE",
            "#B8860B",
            "#BDB76B",
            "#D8BFD8",
            "#DEB887",
            "#FFFF00",
            "#FFF0F5",
            "#EE82EE",
            "#DC143C",
            "#C0C0C0"
    };


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Grid adapter = new Grid(MainActivity.this,gridColor);
        gridView=(GridView)findViewById(R.id.grid_view);

        gridView.setAdapter(adapter);


        gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> parent, View view,
                                    int position, long id)
            {
                Toast.makeText(MainActivity.this, "You Clicked On " +gridcolor[+ position], Toast.LENGTH_SHORT).show();

            }
        });

    }

}

在自定义适配器代码中,代码将会像这样,其中颜色代码将被解析。
public class Grid extends BaseAdapter {

    private Context mContext;
    private final String[] menu;
    private final int[] Imageid;
    private final String[] gridcolor;

    public Grid(Context context,String[] menu,int[] Imageid,String[] gridcolor)
    {
        mContext=context;

        this.gridcolor=gridcolor;
    }

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

    @Override
    public Object getItem(int i) {
        return null;
    }

    @Override
    public long getItemId(int i) {
        return 0;
    }

    @Override
    public View getView(int i, View view, ViewGroup viewGroup) {
        View grid;
        LayoutInflater inflater = (LayoutInflater) mContext
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        if (view == null) {

            grid = new View(mContext);
            grid = inflater.inflate(R.layout.grid_layout, null);

            grid.setBackgroundColor(Color.parseColor(gridcolor[i]));

        } else
        {
            grid =  view;
        }

        return grid;
    }
}

-1
你需要创建一个自定义布局并在适配器中使用它,而不是使用android.R.layout.simple_list_item_1。例如:
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/text1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:textAppearance="?android:attr/textAppearanceListItemSmall"
    android:gravity="center_vertical"
    android:paddingLeft="?android:attr/listPreferredItemPaddingLeft"
    android:paddingRight="?android:attr/listPreferredItemPaddingRight"
    android:minHeight="?android:attr/listPreferredItemHeightSmall"
    android:background="#18A608"
     />

我只是复制了最新版本的simple_list_item_1.xml,并在末尾添加了新的背景颜色。

将此保存为grid_layout.xmlres/layout中,并更改您的适配器构造函数为:

ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.grid_layout, student_array);

谢谢。这对于在屏幕创建时初始化所有单元格非常有效。但我还需要动态访问和更改单元格。有没有办法在运行时引用单个单元格以更改它们的颜色? - Mark__C
抱歉,我刚刚看到你的回复。是的,但是你想要突出显示一个单元格还是符合某个条件的每个单元格(比如每三个单元格或每个不及格的学生)? - Sam
@Mark__C 是的,按照SDK中的建议覆盖BaseAdapter。 - dcow

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