Java 单击更改gridview单元格的颜色

Java 单击更改gridview单元格的颜色,java,android,android-layout,gridview,Java,Android,Android Layout,Gridview,我有一个包含文本和图像的gridview。当用户触摸网格中的单元格时,它会更改颜色以显示已选中该单元格,再次选中时,它会返回默认颜色以显示不再选中该单元格。可以选择任意数量的单元格。问题是当用户必须在网格中滚动以查看所有图标时,选定的图标有时会变为未选定,并随机选择其他单元格。 我怀疑这与正在回收的gridview有关,但我不确定如何解决这个问题 public class Onboarding extends Activity { GridView grid; ArrayList selecte

我有一个包含文本和图像的gridview。当用户触摸网格中的单元格时,它会更改颜色以显示已选中该单元格,再次选中时,它会返回默认颜色以显示不再选中该单元格。可以选择任意数量的单元格。问题是当用户必须在网格中滚动以查看所有图标时,选定的图标有时会变为未选定,并随机选择其他单元格。 我怀疑这与正在回收的gridview有关,但我不确定如何解决这个问题

public class Onboarding extends Activity {
GridView grid;
ArrayList selectedCategories = new ArrayList<>();
CustomGrid adapter;
String[] dummyString = {
        "item 1",
        "item 2",
        "item 3",
        "item 4",
        "item 5",
        "item 6",
        "item 7",
        "item 8",
        "item 9",
        "item 10",
        "item 11",
        "item 12",
        "item 13",
        "item 14",
        "item 15",
        "item 16",
        "item 17",
        "item 18",
        "item 19"
};
int[] imageId = {
        R.drawable.1,
        R.drawable.2,
        R.drawable.3,
        R.drawable.4,
        R.drawable.5,
        R.drawable.6,
        R.drawable.7,
        R.drawable.8,
        R.drawable.9,
        R.drawable.10,
        R.drawable.11,
        R.drawable.12,
        R.drawable.13,
        R.drawable.14,
        R.drawable.15,
        R.drawable.16,
        R.drawable.17,
        R.drawable.18,
        R.drawable.19
};


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_onboarding);
    getWindow().setSoftInputMode(
            WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN
    ); //makes sure keyboard is hidden on this view as it is not needed
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT);

    grid = (GridView) findViewById(R.id.grid);

    //deals with settings the number of Columns
    DisplayMetrics displayMetrics = this.getResources().getDisplayMetrics();
    double dpWidth = displayMetrics.widthPixels / displayMetrics.density;
    if (dpWidth <= 400) {
        grid.setNumColumns(2);
    } else if (dpWidth > 400 && dpWidth < 500) {
        grid.setNumColumns(3);
    } else if (dpWidth >= 500 && dpWidth < 550) {
        grid.setNumColumns(4);
    } else {
        grid.setNumColumns(5);
    }

    adapter = new CustomGrid(Onboarding.this, dummyString, imageId);
    grid.setAdapter(adapter);
    grid.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view,
                                int position, long id) {
            //the position is the actual position that is pressed. but the getChildAt returns gets the relative position, ie what's being drawn
            //on the grid.
            //to fix this, the first visible position is obtained and the difference is subtracted
            int firstPos = grid.getFirstVisiblePosition();
            View tv = grid.getChildAt(position - firstPos);
            Toast.makeText(Onboarding.this, "You Clicked at position" + position + " " + dummyString[+position] + "firstPos " + firstPos, Toast.LENGTH_SHORT).show(); //debug

            if (tv == null) { //this shouldn't/doesn't happen
                Log.e("OnBoarding.java", "Issue with null view at line " + Thread.currentThread().getStackTrace()[2].getLineNumber() +
                        "grid is having a problem");
                return;
            }

            if (selectedCategories.contains(dummyString[+position]) == false) {//add the item if it doesn't exist
                selectedCategories.add(dummyString[+position]);
                tv.setBackgroundColor(Color.parseColor("#FFE5CD"));
            } else { //remove the item if it already exists, as the user is removing it by touching it again
                selectedCategories.remove(dummyString[+position]);
                tv.setBackgroundColor(Color.parseColor("#EEEEEE"));
            }
        }
    });

}

}单击gridview项更改颜色的步骤

1.在侧面可拉深的位置创建选择器,如


希望它能为您工作。

我最终解决这个问题的方法是在gridview上使用滚动监听器

        grid.setOnScrollListener(new AbsListView.OnScrollListener() {
        @Override
        public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
            //Log.d("Onboarding 7331", "onScroll: onScroll " + firstVisibleItem + " " + selectedPositions.toString());
            for (int i = 0; i < totalItemCount; i++) {
                View tv = grid.getChildAt(i - firstVisibleItem);
                if (tv == null) {
                    continue;
                }
                if (selectedPositions.contains(Integer.toString(i))) {
                    tv.setBackgroundColor(Color.parseColor("#FFE5CD"));
                } else {
                    tv.setBackgroundColor(Color.parseColor("#EEEEEE"));
                }
            }
        }

        @Override
        public void onScrollStateChanged(AbsListView view, int scrollState) {
            //     Log.d("Onboarding 7331", "onScroll: state changed "+selectedPositions.toString());
        }
    });

就用这个吧,希望这会有帮助

     gridview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        public void onItemClick(AdapterView<?> parent, View v,
                                int position, long id) {
            View currentPosition = gridview.getChildAt(position);
            if (previousSelectedPosition != -1) {
                View previousPos = gridview.getChildAt(previousSelectedPosition);
                previousPos.setBackgroundResource(R.drawable.calendar_cell);
            }
            currentPosition.setBackgroundResource(R.drawable.calendar_cel_selectl);
            previousSelectedPosition = position;
        }
    });

在GridView的XML文件中添加此元素 android:listSelector=@drawable/grid\u view\u selected drawable的代码可以是这样的:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="#E80335" />
    <corners
        android:bottomRightRadius="5dp"
        android:bottomLeftRadius="5dp"
        android:topLeftRadius="5dp"
        android:topRightRadius="5dp" />
    <stroke
        android:color="@color/material_grey_600"
        android:width="2dp" />
</shape>

就这样。无需添加或执行任何覆盖方法来更改gridview单元格的颜色。

来自Review:嗨,请不要仅用源代码回答。试着提供一个关于你的解决方案如何工作的很好的描述。请参阅:。谢谢
        grid.setOnScrollListener(new AbsListView.OnScrollListener() {
        @Override
        public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
            //Log.d("Onboarding 7331", "onScroll: onScroll " + firstVisibleItem + " " + selectedPositions.toString());
            for (int i = 0; i < totalItemCount; i++) {
                View tv = grid.getChildAt(i - firstVisibleItem);
                if (tv == null) {
                    continue;
                }
                if (selectedPositions.contains(Integer.toString(i))) {
                    tv.setBackgroundColor(Color.parseColor("#FFE5CD"));
                } else {
                    tv.setBackgroundColor(Color.parseColor("#EEEEEE"));
                }
            }
        }

        @Override
        public void onScrollStateChanged(AbsListView view, int scrollState) {
            //     Log.d("Onboarding 7331", "onScroll: state changed "+selectedPositions.toString());
        }
    });
     gridview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        public void onItemClick(AdapterView<?> parent, View v,
                                int position, long id) {
            View currentPosition = gridview.getChildAt(position);
            if (previousSelectedPosition != -1) {
                View previousPos = gridview.getChildAt(previousSelectedPosition);
                previousPos.setBackgroundResource(R.drawable.calendar_cell);
            }
            currentPosition.setBackgroundResource(R.drawable.calendar_cel_selectl);
            previousSelectedPosition = position;
        }
    });
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="#E80335" />
    <corners
        android:bottomRightRadius="5dp"
        android:bottomLeftRadius="5dp"
        android:topLeftRadius="5dp"
        android:topRightRadius="5dp" />
    <stroke
        android:color="@color/material_grey_600"
        android:width="2dp" />
</shape>