在 Gridview 中选中一个时,多个复选框被(取消)选中 - Android
Multiple checkboxes get (de)selected when one is checked in Gridview - Android
所以我有一个 Gridview,其中每个网格项都由一个 ImageView 和一个 Checkbox 组成。它调用图像适配器来动态填充网格。现在,当我 select 一个复选框时,比方说数字 5,另一个像数字 12 这样的复选框会自动 selected。 deselection 类似。我不明白为什么会这样。任何帮助将不胜感激。谢谢!
public class SignupFarmerCrop extends ActionBarActivity implements View.OnClickListener {
GridView gridView;
private ImageAdapter adpt;
private List<DistrictCommodity> localResponse;
private MediaPlayer mp;
private boolean[] thumbnailsselection;
private int count;
private PreferencesHelper oldSignup;
private String district;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_signup_farmer_crop);
setVolumeControlStream(AudioManager.STREAM_MUSIC);
ImageButton sound = (ImageButton) findViewById(R.id.button);
sound.setOnClickListener(this);
oldSignup = new PreferencesHelper(this);
district = oldSignup.getStringPreferences("districtId");
String language = Locale.getDefault().getLanguage();
if (language.equals("en"))
language = "L001";
else
language = "L002";
// Exec async load task
new EndpointsDistrictCropAsyncTask().execute(new Pair<Context, String>(this, district),
new Pair<Context, String>(this, language));
gridView = (GridView) findViewById(R.id.gridView1);
adpt = new ImageAdapter(this, localResponse);
gridView.setAdapter(adpt);
public void onClick(View v) {
if (mp != null) mp.release();
mp = MediaPlayer.create(this, R.raw.fname);
mp.start();
}
/** Called when the user clicks a crop button */
public void goConfirm(View view) {
// Do something in response to button
Intent intent = new Intent(this, SignupConfirmActivity.class);
startActivity(intent);
}
@Override
protected void onDestroy() {
if(null!=mp){
mp.release();
}
super.onDestroy();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
// Inflate the menu items for use in the action bar
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_signup_farmer_crop, menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
return super.onOptionsItemSelected(item);
}
public class ImageAdapter extends BaseAdapter {
private Context context;
private List<DistrictCommodity> crops;
private final Logger logger = Logger.getLogger(ImageAdapter.class.getName());
public ImageAdapter(Context context, List<DistrictCommodity> activeResponses) {
this.context = context;
this.crops = activeResponses;
}
public View getView(int position, View convertView, ViewGroup parent) {
View gridView = convertView;
ViewHolder holder;
if (gridView == null) {
holder = new ViewHolder();
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
gridView = inflater.inflate(R.layout.activity_signup_crop_grid, null);
holder.checkbox = (CheckBox) gridView.findViewById(R.id.grid_item_label);
holder.imageview = (ImageView) gridView.findViewById(R.id.grid_item_image);
gridView.setTag(holder);
}
else {
holder = (ViewHolder) gridView.getTag();
}
holder.checkbox.setId(position);
holder.imageview.setId(position);
holder.checkbox.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
CheckBox cb = (CheckBox) v;
int id = cb.getId();
logger.warning("Id of checkbox is: " + id);
if (thumbnailsselection[id]) {
cb.setChecked(false);
thumbnailsselection[id] = false;
} else {
cb.setChecked(true);
thumbnailsselection[id] = true;
}
}
});
holder.checkbox.setText(crops.get(position).getCommodity());
String crop = crops.get(position).getType();
logger.warning("Image file called is @drawable/" + crop + ".png and context is: " + context.getPackageName());
Drawable drawable = context.getResources().getDrawable(context.getResources()
.getIdentifier("@drawable/potato", null, context.getPackageName()));
holder.imageview.setImageDrawable(drawable);
holder.id = position;
return gridView;
}
@Override
public int getCount() {
return count;
}
@Override
public Object getItem(int position) {
return position;
}
@Override
public long getItemId(int position) {
return position;
}
public void setActiveDeals(List<DistrictCommodity> activeResponses) {
this.crops = activeResponses;
}
}
class ViewHolder {
ImageView imageview;
CheckBox checkbox;
int id;
}
}
您在 thumbnailsselection
中保存复选框在被单击时的状态,但您没有在 getView()
中使用该状态来设置复选框的初始外观。因此,您可能会从回收视图中获取随机复选框状态。
使用 thumbnailsselection
中的状态调用 holder.checkbox.setState()
以创建具有正确复选框外观的 GridView
项。
MainActivity.java
private void enterEditMode() {
try {
listView.setAdapter(null);
listView.setOnItemClickListener(null);
db = new MySQLiteHelper(this);
//call the note object which hold all note object
List<note> note = db.getAllNotes();
int total = note.size();
//declare the values with specific number
String[] values = new String[total];
//add all the note innto the values
int counter = 0;
for (note note1 : note) {
values[counter] = note1.getSubject();
counter++;
}
db.close();
cbAdapter = new checkboxListviewAdapter(this,values);
// Assign adapter to ListView
listView.setAdapter(cbAdapter);
cbAdapter.notifyDataSetChanged();
} catch (Exception e) {
//tell user to send report
showMessage("Error!");
}
}
checkboxListviewAdapter.java
public class checkboxListviewAdapter extends BaseAdapter{
Context context;
String[] subjectList;
Boolean[] selectedList;
private LayoutInflater inflater;
public checkboxListviewAdapter (Context context, String[] subjectList ) {
this.context = context;
this.subjectList = subjectList;
selectedList = new Boolean[subjectList.length];
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
for (int i = 0; i < selectedList.length; i++){
selectedList[i] = false;
}
}
@Override
public int getCount() {
return subjectList.length;
}
@Override
public Object getItem(int position) {
return subjectList[position];
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
Holder holder = null;
if (convertView == null) {
holder = new Holder();
convertView = inflater.inflate(R.layout.checkbox_listview_text_black, null);
holder.tv = (TextView) convertView.findViewById(R.id.textview1);
holder.cb = (CheckBox) convertView.findViewById(R.id.checkBox1);
convertView.setTag(holder);
} else {
holder = (Holder) convertView.getTag();
}
holder.cb.setChecked(selectedList[position]);
holder.tv.setText(subjectList[position]);
holder.cb.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(selectedList[position] == false) {
selectedList[position] = true;
} else {
selectedList[position] = false;
}
}
});
return convertView;
}
static class Holder {
TextView tv;
CheckBox cb;
}
}
解释:
在checkboxListviewAdapter.java
1) 假设您的列表视图中有 10 个复选框。因此,创建一个 boolean[] 来保存所有复选框的布尔值。
private boolean[] booleanList = new boolean[10];
2) 在您的构造函数中,使用 for 循环将 booleanList 设置为 false。
public checkboxListviewAdapter (Context context, String[] subjectList ) {
//this.context = context;
//this.subjectList = subjectList;
//selectedList = new Boolean[subjectList.length];
//inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
for (int i = 0; i < selectedList.length; i++){
selectedList[i] = false;
}
}
3) 现在,在您的 getView 中,添加以下代码以从 booleanList 获取布尔值,并在每次滚动列表视图时设置布尔值。
holder.cb.setChecked(selectedList[position]);
4) 最后,要向您的复选框添加一个侦听器,请使用 OnClickListener。
holder.cb.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(selectedList[position] == false) {
selectedList[position] = true;
} else {
selectedList[position] = false;
}
}
});
5) 运行 代码并检查结果。
所以我有一个 Gridview,其中每个网格项都由一个 ImageView 和一个 Checkbox 组成。它调用图像适配器来动态填充网格。现在,当我 select 一个复选框时,比方说数字 5,另一个像数字 12 这样的复选框会自动 selected。 deselection 类似。我不明白为什么会这样。任何帮助将不胜感激。谢谢!
public class SignupFarmerCrop extends ActionBarActivity implements View.OnClickListener {
GridView gridView;
private ImageAdapter adpt;
private List<DistrictCommodity> localResponse;
private MediaPlayer mp;
private boolean[] thumbnailsselection;
private int count;
private PreferencesHelper oldSignup;
private String district;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_signup_farmer_crop);
setVolumeControlStream(AudioManager.STREAM_MUSIC);
ImageButton sound = (ImageButton) findViewById(R.id.button);
sound.setOnClickListener(this);
oldSignup = new PreferencesHelper(this);
district = oldSignup.getStringPreferences("districtId");
String language = Locale.getDefault().getLanguage();
if (language.equals("en"))
language = "L001";
else
language = "L002";
// Exec async load task
new EndpointsDistrictCropAsyncTask().execute(new Pair<Context, String>(this, district),
new Pair<Context, String>(this, language));
gridView = (GridView) findViewById(R.id.gridView1);
adpt = new ImageAdapter(this, localResponse);
gridView.setAdapter(adpt);
public void onClick(View v) {
if (mp != null) mp.release();
mp = MediaPlayer.create(this, R.raw.fname);
mp.start();
}
/** Called when the user clicks a crop button */
public void goConfirm(View view) {
// Do something in response to button
Intent intent = new Intent(this, SignupConfirmActivity.class);
startActivity(intent);
}
@Override
protected void onDestroy() {
if(null!=mp){
mp.release();
}
super.onDestroy();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
// Inflate the menu items for use in the action bar
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_signup_farmer_crop, menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
return super.onOptionsItemSelected(item);
}
public class ImageAdapter extends BaseAdapter {
private Context context;
private List<DistrictCommodity> crops;
private final Logger logger = Logger.getLogger(ImageAdapter.class.getName());
public ImageAdapter(Context context, List<DistrictCommodity> activeResponses) {
this.context = context;
this.crops = activeResponses;
}
public View getView(int position, View convertView, ViewGroup parent) {
View gridView = convertView;
ViewHolder holder;
if (gridView == null) {
holder = new ViewHolder();
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
gridView = inflater.inflate(R.layout.activity_signup_crop_grid, null);
holder.checkbox = (CheckBox) gridView.findViewById(R.id.grid_item_label);
holder.imageview = (ImageView) gridView.findViewById(R.id.grid_item_image);
gridView.setTag(holder);
}
else {
holder = (ViewHolder) gridView.getTag();
}
holder.checkbox.setId(position);
holder.imageview.setId(position);
holder.checkbox.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
CheckBox cb = (CheckBox) v;
int id = cb.getId();
logger.warning("Id of checkbox is: " + id);
if (thumbnailsselection[id]) {
cb.setChecked(false);
thumbnailsselection[id] = false;
} else {
cb.setChecked(true);
thumbnailsselection[id] = true;
}
}
});
holder.checkbox.setText(crops.get(position).getCommodity());
String crop = crops.get(position).getType();
logger.warning("Image file called is @drawable/" + crop + ".png and context is: " + context.getPackageName());
Drawable drawable = context.getResources().getDrawable(context.getResources()
.getIdentifier("@drawable/potato", null, context.getPackageName()));
holder.imageview.setImageDrawable(drawable);
holder.id = position;
return gridView;
}
@Override
public int getCount() {
return count;
}
@Override
public Object getItem(int position) {
return position;
}
@Override
public long getItemId(int position) {
return position;
}
public void setActiveDeals(List<DistrictCommodity> activeResponses) {
this.crops = activeResponses;
}
}
class ViewHolder {
ImageView imageview;
CheckBox checkbox;
int id;
}
}
您在 thumbnailsselection
中保存复选框在被单击时的状态,但您没有在 getView()
中使用该状态来设置复选框的初始外观。因此,您可能会从回收视图中获取随机复选框状态。
使用 thumbnailsselection
中的状态调用 holder.checkbox.setState()
以创建具有正确复选框外观的 GridView
项。
MainActivity.java
private void enterEditMode() {
try {
listView.setAdapter(null);
listView.setOnItemClickListener(null);
db = new MySQLiteHelper(this);
//call the note object which hold all note object
List<note> note = db.getAllNotes();
int total = note.size();
//declare the values with specific number
String[] values = new String[total];
//add all the note innto the values
int counter = 0;
for (note note1 : note) {
values[counter] = note1.getSubject();
counter++;
}
db.close();
cbAdapter = new checkboxListviewAdapter(this,values);
// Assign adapter to ListView
listView.setAdapter(cbAdapter);
cbAdapter.notifyDataSetChanged();
} catch (Exception e) {
//tell user to send report
showMessage("Error!");
}
}
checkboxListviewAdapter.java
public class checkboxListviewAdapter extends BaseAdapter{
Context context;
String[] subjectList;
Boolean[] selectedList;
private LayoutInflater inflater;
public checkboxListviewAdapter (Context context, String[] subjectList ) {
this.context = context;
this.subjectList = subjectList;
selectedList = new Boolean[subjectList.length];
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
for (int i = 0; i < selectedList.length; i++){
selectedList[i] = false;
}
}
@Override
public int getCount() {
return subjectList.length;
}
@Override
public Object getItem(int position) {
return subjectList[position];
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
Holder holder = null;
if (convertView == null) {
holder = new Holder();
convertView = inflater.inflate(R.layout.checkbox_listview_text_black, null);
holder.tv = (TextView) convertView.findViewById(R.id.textview1);
holder.cb = (CheckBox) convertView.findViewById(R.id.checkBox1);
convertView.setTag(holder);
} else {
holder = (Holder) convertView.getTag();
}
holder.cb.setChecked(selectedList[position]);
holder.tv.setText(subjectList[position]);
holder.cb.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(selectedList[position] == false) {
selectedList[position] = true;
} else {
selectedList[position] = false;
}
}
});
return convertView;
}
static class Holder {
TextView tv;
CheckBox cb;
}
}
解释:
在checkboxListviewAdapter.java
1) 假设您的列表视图中有 10 个复选框。因此,创建一个 boolean[] 来保存所有复选框的布尔值。
private boolean[] booleanList = new boolean[10];
2) 在您的构造函数中,使用 for 循环将 booleanList 设置为 false。
public checkboxListviewAdapter (Context context, String[] subjectList ) {
//this.context = context;
//this.subjectList = subjectList;
//selectedList = new Boolean[subjectList.length];
//inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
for (int i = 0; i < selectedList.length; i++){
selectedList[i] = false;
}
}
3) 现在,在您的 getView 中,添加以下代码以从 booleanList 获取布尔值,并在每次滚动列表视图时设置布尔值。
holder.cb.setChecked(selectedList[position]);
4) 最后,要向您的复选框添加一个侦听器,请使用 OnClickListener。
holder.cb.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(selectedList[position] == false) {
selectedList[position] = true;
} else {
selectedList[position] = false;
}
}
});
5) 运行 代码并检查结果。