草庐IT

android - 带有复选框的自定义 ListView 检查未选中的项目

coder 2023-12-28 原文

我的 ListView 在一个看起来像这样的 fragment 中有一个 BaseAdapter:

public class SelectionMucListAdapter extends BaseAdapter {

    private LayoutInflater inflater = null;
    Typeface titleFace;
    ArrayList<UsersData> innerList = new ArrayList<UsersData>();

    public SelectionMucListAdapter(ArrayList<UsersData> users) {
        inflater = (LayoutInflater) mainActivity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        titleFace = Typeface.createFromAsset(mainActivity.getAssets(), "fonts/bradybun.ttf");
        innerList = users;
    }

    @Override
    public int getCount() {
        return innerList.size();
    }

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

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

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        ViewHolder viewHolder;

        if (convertView == null) {
            convertView = inflater.inflate(R.layout.muc_list_item, null);
            viewHolder = new ViewHolder();
            viewHolder.image = (ImageView)convertView.findViewById(R.id.item_image);
            viewHolder.check = (CheckBox)convertView.findViewById(R.id.cb_choose_user);
            viewHolder.title = (TextView)convertView.findViewById(R.id.item_text_1);
            viewHolder.rating=(RatingBar)convertView.findViewById(R.id.item_text_2);
            convertView.setTag(viewHolder);

        }else{
            viewHolder = (ViewHolder)convertView.getTag();
        }         

        viewHolder.title.setTypeface(titleFace);

        Bitmap avatar = innerList.get(position).getUserAvatar();//UsersManager.getInstance().getUsers().get(position).getUserAvatar();

        if(avatar != null)
            viewHolder.image.setImageBitmap(avatar);

        viewHolder.title.setText(innerList.get(position).getUserName());
        viewHolder.rating.setRating((float)Double.parseDouble(innerList.get(position).getRating()));
        viewHolder.check.setOnCheckedChangeListener(new OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton cb, boolean isChecked) {
                if(cb.isChecked()) {// if this item is checked then add to list
                    Log.v("CheckBox", "pos: "+position+" checked");
                    if(!choices.contains(innerList.get(position))) {
                        choices.add(innerList.get(position));
                    }
                } else {// if its unchecked then remove from list if exist
                    Log.v("CheckBox", "pos: "+position+" checked");
                    if(choices.contains(innerList.get(position))) {
                        choices.remove(innerList.get(position));
                    }
                }
                isChecked = cb.isChecked();
            }
        });
        viewHolder.check.setTag(position);

        return convertView;
    }
}

static class ViewHolder{
    ImageView image;
    CheckBox check;
    TextView title;
    RatingBar rating;
}

class CheckState{
    boolean isChecked;
    UsersData usersData;

    public UsersData getUsersData() {
        return usersData;
    }

    public void setUsersData(UsersData usersData) {
        this.usersData = usersData;
    }

    public boolean isChecked() {
        return isChecked;
    }

    public void setChecked(boolean isChecked) {
        this.isChecked = isChecked;
    }

}

我有 20 个列表项,问题是当我检查前 2 个项目时,例如在索引 [0] 和 [1] 处,不知何故它也会自动检查索引 [9] 和 [10] 处的其他项目,当我向下滚动列表。如果我检查其他项目也会发生同样的情况,并且每次我向下滚动列表时它都会以相同的模式重复检查。

我真的不知道发生了什么,所以我想问问这里是否有人可以阻止这种困惑。谢谢!

最佳答案

您的自定义适配器必须实现 CompoundButton.OnCheckedChangeListener。使用 SparseBooleanArray。

然后

 cb.setChecked(mCheckStates.get(position, false)); // cb is checkbox
 cb.setOnCheckedChangeListener(this);

然后使用选中状态设置文本到复选框

  public boolean isChecked(int position) {
    return mCheckStates.get(position, false);
}

public void setChecked(int position, boolean isChecked) {
    mCheckStates.put(position, isChecked);

}

public void toggle(int position) {
    setChecked(position, !isChecked(position));
}
@Override
public void onCheckedChanged(CompoundButton buttonView,
    boolean isChecked) {
 mCheckStates.put((Integer) buttonView.getTag(), isChecked);    

}

话题讨论@

https://groups.google.com/forum/?fromgroups#!topic/android-developers/No0LrgJ6q2M

例子:

使用 ViewHolder。下面的例子没有使用 View Holder。

屏幕底部有一个按钮。当您选中复选框时,当您单击底部的按钮时,选中行的项目将显示在 toast 中。

使用以下内容并根据您的要求进行修改。

public class MainActivity extends Activity implements
AdapterView.OnItemClickListener {
    int count;
private CheckBoxAdapter mCheckBoxAdapter;

String[] GENRES = new String[] {
    "Action", "Adventure", "Animation", "Children", "Comedy",
"Documentary", "Drama",
    "Foreign", "History", "Independent", "Romance", "Sci-Fi",
"Television", "Thriller"
};

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    final ListView listView = (ListView) findViewById(R.id.lv);

    listView.setItemsCanFocus(false);
    listView.setTextFilterEnabled(true);
    listView.setOnItemClickListener(this);
    mCheckBoxAdapter = new CheckBoxAdapter(this, GENRES);
           listView.setAdapter(mCheckBoxAdapter);
    Button b= (Button) findViewById(R.id.button1);
    b.setOnClickListener(new OnClickListener()
    {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            StringBuilder result = new StringBuilder();
            for(int i=0;i<mCheckBoxAdapter.mCheckStates.size();i++)
            {
                if(mCheckBoxAdapter.mCheckStates.get(i)==true)
                {
                    result.append(GENRES[i]);
                    result.append("\n");
                }

            }
            Toast.makeText(MainActivity.this, result, 1000).show();
        }

    });
   }

public void onItemClick(AdapterView parent, View view, int
position, long id) {
    mCheckBoxAdapter.toggle(position);
}

class CheckBoxAdapter extends ArrayAdapter implements CompoundButton.OnCheckedChangeListener
{  private SparseBooleanArray mCheckStates;
   LayoutInflater mInflater;
    TextView tv1,tv;
    CheckBox cb;
    String[] gen;
    CheckBoxAdapter(MainActivity context, String[] genres)
    {
        super(context,0,genres);
        mCheckStates = new SparseBooleanArray(genres.length);
        mInflater = (LayoutInflater)MainActivity.this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        gen= genres;
    }
    @Override
    public int getCount() {
        // TODO Auto-generated method stub
        return gen.length;
    }

    @Override
    public Object getItem(int position) {
        // TODO Auto-generated method stub
        return position;
    }

    @Override
    public long getItemId(int position) {
        // TODO Auto-generated method stub

        return 0;
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        // TODO Auto-generated method stub
        View vi=convertView;
        if(convertView==null)
         vi = mInflater.inflate(R.layout.checkbox, null); 
         tv= (TextView) vi.findViewById(R.id.textView1);

         cb = (CheckBox) vi.findViewById(R.id.checkBox1);
         tv.setText("Name :"+ gen [position]);
         cb.setTag(position);
         cb.setChecked(mCheckStates.get(position, false));
        cb.setOnCheckedChangeListener(this);
        return vi;
    }
     public boolean isChecked(int position) {
            return mCheckStates.get(position, false);
        }

        public void setChecked(int position, boolean isChecked) {
            mCheckStates.put(position, isChecked);

        }

        public void toggle(int position) {
            setChecked(position, !isChecked(position));

        }
    @Override
    public void onCheckedChanged(CompoundButton buttonView,
            boolean isChecked) {

         mCheckStates.put((Integer) buttonView.getTag(), isChecked);    

    }

}

}

关于android - 带有复选框的自定义 ListView 检查未选中的项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18524733/

有关android - 带有复选框的自定义 ListView 检查未选中的项目的更多相关文章

  1. ruby - Facter::Util::Uptime:Module 的未定义方法 get_uptime (NoMethodError) - 2

    我正在尝试设置一个puppet节点,但ruby​​gems似乎不正常。如果我通过它自己的二进制文件(/usr/lib/ruby/gems/1.8/gems/facter-1.5.8/bin/facter)在cli上运行facter,它工作正常,但如果我通过由ruby​​gems(/usr/bin/facter)安装的二进制文件,它抛出:/usr/lib/ruby/1.8/facter/uptime.rb:11:undefinedmethod`get_uptime'forFacter::Util::Uptime:Module(NoMethodError)from/usr/lib/ruby

  2. ruby - 检查 "command"的输出应该包含 NilClass 的意外崩溃 - 2

    为了将Cucumber用于命令行脚本,我按照提供的说明安装了arubagem。它在我的Gemfile中,我可以验证是否安装了正确的版本并且我已经包含了require'aruba/cucumber'在'features/env.rb'中为了确保它能正常工作,我写了以下场景:@announceScenario:Testingcucumber/arubaGivenablankslateThentheoutputfrom"ls-la"shouldcontain"drw"假设事情应该失败。它确实失败了,但失败的原因是错误的:@announceScenario:Testingcucumber/ar

  3. ruby-on-rails - Rails 3.2.1 中 ActionMailer 中的未定义方法 'default_content_type=' - 2

    我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer

  4. ruby-on-rails - form_for 中不在模型中的自定义字段 - 2

    我想向我的Controller传递一个参数,它是一个简单的复选框,但我不知道如何在模型的form_for中引入它,这是我的观点:{:id=>'go_finance'}do|f|%>Transferirde:para:Entrada:"input",:placeholder=>"Quantofoiganho?"%>Saída:"output",:placeholder=>"Quantofoigasto?"%>Nota:我想做一个额外的复选框,但我该怎么做,模型中没有一个对象,而是一个要检查的对象,以便在Controller中创建一个ifelse,如果没有检查,请帮助我,非常感谢,谢谢

  5. ruby - 主要 :Object when running build from sublime 的未定义方法 `require_relative' - 2

    我已经从我的命令行中获得了一切,所以我可以运行rubymyfile并且它可以正常工作。但是当我尝试从sublime中运行它时,我得到了undefinedmethod`require_relative'formain:Object有人知道我的sublime设置中缺少什么吗?我正在使用OSX并安装了rvm。 最佳答案 或者,您可以只使用“require”,它应该可以正常工作。我认为“require_relative”仅适用于ruby​​1.9+ 关于ruby-主要:Objectwhenrun

  6. ruby - 检查数组是否在增加 - 2

    这个问题在这里已经有了答案:Checktoseeifanarrayisalreadysorted?(8个答案)关闭9年前。我只是想知道是否有办法检查数组是否在增加?这是我的解决方案,但我正在寻找更漂亮的方法:n=-1@arr.flatten.each{|e|returnfalseife

  7. ruby - 检查方法参数的类型 - 2

    我不确定传递给方法的对象的类型是否正确。我可能会将一个字符串传递给一个只能处理整数的函数。某种运行时保证怎么样?我看不到比以下更好的选择:defsomeFixNumMangler(input)raise"wrongtype:integerrequired"unlessinput.class==FixNumother_stuffend有更好的选择吗? 最佳答案 使用Kernel#Integer在使用之前转换输入的方法。当无法以任何合理的方式将输入转换为整数时,它将引发ArgumentError。defmy_method(number)

  8. ruby - 检查字符串是否包含散列中的任何键并返回它包含的键的值 - 2

    我有一个包含多个键的散列和一个字符串,该字符串不包含散列中的任何键或包含一个键。h={"k1"=>"v1","k2"=>"v2","k3"=>"v3"}s="thisisanexamplestringthatmightoccurwithakeysomewhereinthestringk1(withspecialcharacterslike(^&*$#@!^&&*))"检查s是否包含h中的任何键的最佳方法是什么,如果包含,则返回它包含的键的值?例如,对于上面的h和s的例子,输出应该是v1。编辑:只有字符串是用户定义的。哈希将始终相同。 最佳答案

  9. ruby-on-rails - Ruby 检查日期时间是否为 iso8601 并保存 - 2

    我需要检查DateTime是否采用有效的ISO8601格式。喜欢:#iso8601?我检查了ruby​​是否有特定方法,但没有找到。目前我正在使用date.iso8601==date来检查这个。有什么好的方法吗?编辑解释我的环境,并改变问题的范围。因此,我的项目将使用jsapiFullCalendar,这就是我需要iso8601字符串格式的原因。我想知道更好或正确的方法是什么,以正确的格式将日期保存在数据库中,或者让ActiveRecord完成它们的工作并在我需要时间信息时对其进行操作。 最佳答案 我不太明白你的问题。我假设您想检查

  10. ruby - 检查日期是否在过去 7 天内 - 2

    我的日期格式如下:"%d-%m-%Y"(例如,今天的日期为07-09-2015),我想看看是不是在过去的七天内。谁能推荐一种方法? 最佳答案 你可以这样做:require"date"Date.today-7 关于ruby-检查日期是否在过去7天内,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/32438063/

随机推荐