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

时间:2016-08-25 05:08:39

标签: java android android-layout 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"));
            }
        }
    });

}

}

public class CustomGrid extends BaseAdapter {
private Context mContext;
private final String[] genreString;
private final int[] Imageid;

public CustomGrid(Context c, String[] genreString, int[] Imageid) {
    mContext = c;
    this.Imageid = Imageid;
    this.genreString = genreString;
}

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

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

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

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View grid;
    LayoutInflater inflater = (LayoutInflater) mContext
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    TextView textView;
    ImageView imageView;
    if (convertView == null) {
        grid = inflater.inflate(R.layout.grid_single, null);
    } else {
        grid = convertView;
    }
    textView  = (TextView) grid.findViewById(R.id.grid_text);
    imageView = (ImageView) grid.findViewById(R.id.grid_image);
    textView.setText(genreString[position]);
    imageView.setImageResource(Imageid[position]);

    return grid;
}

}

4 个答案:

答案 0 :(得分:1)

更改单击gridview项目上的颜色的步骤

1)创建一个侧面可绘制的选择器,如

<item android:drawable="@color/blue" android:state_pressed="true" />
<item android:drawable="@color/blue" android:state_selected="true" />
<item android:drawable="@color/white" />

2)将背景设置为网格视图的项目布局,如

android:background="@drawable/grid_color_selector"
希望它对你有用。

答案 1 :(得分: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());
        }
    });

答案 2 :(得分:0)

只需使用此希望对您有帮助

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

答案 3 :(得分:0)

在 GridView 的 XML 文件中添加这个元素 async def initialize(): await client.wait_until_ready() client.db = await aiosqlite.connect("expData.db") await client.db.execute("CREATE TABLE IF NOT EXISTS guildInvites (guild_id int, user_id int, exp int, PRIMARY KEY (guild_id, user_id))") @client.event async def on_message(message): if not message.author.bot: cursor = await client.db.execute("INSERT OR IGNORE INTO guildData (guild_id, user_id, exp) VALUES (?,?,?)", (message.guild.id, message.author.id, 1)) if cursor.rowcount == 0: await client.db.execute("UPDATE guildData SET exp = exp + 1 WHERE guild_id = ? AND user_id = ?", (message.guild.id, message.author.id)) cur = await client.db.execute("SELECT exp FROM guildData WHERE guild_id = ? AND user_id = ?", (message.guild.id, message.author.id)) data = await cur.fetchone() exp = data[0] lvl = math.sqrt(exp) / client.multiplier if lvl.is_integer(): await message.channel.send(f"{message.author.mention} well done! You're now level: {int(lvl)}.") await client.db.commit() await client.process_commands(message) @client.command(aliases=['rank']) async def stats(ctx, member: discord.Member=None): if member is None: member = ctx.author # get user exp async with client.db.execute("SELECT exp FROM guildData WHERE guild_id = ? AND user_id = ?", (ctx.guild.id, member.id)) as cursor: data = await cursor.fetchone() exp = data[0] # calculate rank async with client.db.execute("SELECT exp FROM guildData WHERE guild_id = ?", (ctx.guild.id,)) as cursor: rank = 1 async for value in cursor: if exp < value[0]: rank += 1 lvl = int(math.sqrt(exp)//client.multiplier) current_lvl_exp = (client.multiplier*(lvl))**2 next_lvl_exp = (client.multiplier*((lvl+1)))**2 lvl_percentage = ((exp-current_lvl_exp) / (next_lvl_exp-current_lvl_exp)) * 100 embed = discord.Embed(title=f"Stats for {member.name}", colour=discord.Colour.blue()) embed.add_field(name="Level", value=str(lvl)) embed.add_field(name="Exp", value=f"{exp}/{next_lvl_exp}") embed.add_field(name="Rank", value=f"{rank}/{ctx.guild.member_count}") embed.add_field(name="Level Progress", value=f"{round(lvl_percentage, 2)}%") await ctx.send(embed=embed) drawable 的代码可能是这样的:

android:listSelector="@drawable/grid_view_selected"

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