【问题标题】:Multiple checkboxes get (de)selected when one is checked in Gridview - Android在 Gridview 中选中一个复选框时,多个复选框会被(取消)选中 - Android
【发布时间】:2015-06-19 09:44:49
【问题描述】:

所以我有一个 Gridview,其中每个网格项由一个 ImageView 和一个 Checkbox 组成。它调用图像适配器来动态填充网格。现在,当我选择一个复选框时,比如说数字 5,另一个复选框(例如数字 12)会自动被选中。类似的取消选择。我无法弄清楚为什么会这样。任何帮助将不胜感激。谢谢!

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

}

【问题讨论】:

    标签: android gridview checkbox android-adapter


    【解决方案1】:

    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) 运行代码并检查结果。

    【讨论】:

      【解决方案2】:

      您在thumbnailsselection 中保存复选框被单击时的状态,但您没有使用getView() 中的状态来设置复选框的初始外观。所以你可能会从回收的视图中得到随机的复选框状态。

      使用来自thumbnailsselection 的状态调用holder.checkbox.setState() 以创建具有正确复选框外观的GridView 项。

      【讨论】:

      • 谢谢。当我添加 holder.checkbox.setChecked(thumbnailsS​​election[position]);在 getView() 中的 if-else 条件之后。
      猜你喜欢
      • 1970-01-01
      • 2018-04-15
      • 2021-12-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多