带有复选框、单选按钮、文本视图和按钮的列表视图在 android 中无法正常工作 [英] Listview with Checkbox,RadioButton,Textview and button not working correctly in android

查看:21
本文介绍了带有复选框、单选按钮、文本视图和按钮的列表视图在 android 中无法正常工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在创建一个 Android 应用程序,我的应用程序的 UI 如下所示.

I am creating a android app the UI of my application is below given.

点击提交按钮时,我需要选中的复选框和单选按钮值.

示例 Linux 未选中,cc(radio button) 选中.

Example Linux is not checked, cc(radio button) is checked.

记录在列表视图中动态填充,但我无法使其工作.很多问题就在那里.

Records are populated dynamically in list view, but I am not able to make it work. A lot of problems are there.

  1. 当我滚动列表视图单选按钮时,自动选择或取消选择无法保持单选按钮的状态.
  2. 单击按钮时未获得选定的单选按钮和复选框.

下面是我的布局以及java程序.建议我获取正确的值.

Below is my layout as well as java program. Suggest me to get the correct values.

Main.xml

<ListView
    android:id="@+id/my_list"
    android:layout_width="fill_parent"
    android:layout_height="199dp" />

<Button
    android:id="@+id/submit"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Submit"
    />

row.xml

<TextView
    android:id="@+id/label"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@+id/label"
    android:layout_toRightOf="@+id/check"
    android:textSize="20sp" >
</TextView>

<CheckBox
    android:id="@+id/check"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentLeft="true"
    android:layout_marginLeft="4dip"
    android:layout_marginRight="10dip"
    android:focusable="false"

    android:focusableInTouchMode="false" >
</CheckBox>

 <RadioGroup
     android:id="@+id/radioSex"
     android:layout_width="wrap_content"
     android:layout_height="fill_parent"
     android:layout_alignParentRight="true"
     android:layout_alignParentTop="true"
     android:orientation="horizontal" >

     <RadioButton
         android:id="@+id/to"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_marginLeft="10dip"
         android:checked="true"
         android:text="To" />

     <RadioButton
         android:id="@+id/cc"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_marginLeft="10dip"
         android:text="CC" />
 </RadioGroup>

MyAdaptor.java

public class MyAdapter extends ArrayAdapter<Model> {

    private final List<Model> list;
    private final Activity context;
    boolean checkAll_flag = false;
    boolean checkItem_flag = false;

    public MyAdapter(Activity context, List<Model> list) {
        super(context, R.layout.row, list);
        this.context = context;
        this.list = list;
    }

    static class ViewHolder {
        protected TextView text;
        protected CheckBox checkbox;

    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        ViewHolder viewHolder = null;
        if (convertView == null) {
            LayoutInflater inflator = context.getLayoutInflater();
            convertView = inflator.inflate(R.layout.row, null);
            viewHolder = new ViewHolder();
            viewHolder.text = (TextView) convertView.findViewById(R.id.label);
            viewHolder.checkbox = (CheckBox) convertView
                    .findViewById(R.id.check);

            viewHolder.checkbox
                    .setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {

                        @Override
                        public void onCheckedChanged(CompoundButton buttonView,
                                boolean isChecked) {
                            int getPosition = (Integer) buttonView.getTag();
                            list.get(getPosition).setSelected(
                                    buttonView.isChecked());
                        }
                    });
            convertView.setTag(viewHolder);
            convertView.setTag(R.id.label, viewHolder.text);
            convertView.setTag(R.id.check, viewHolder.checkbox);

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

        viewHolder.text.setText(list.get(position).getName());
        viewHolder.checkbox.setChecked(list.get(position).isSelected());

        return convertView;
    }

MainActivity.java

public class MainActivity extends Activity implements OnItemClickListener {

    ListView listView;
    ArrayAdapter<Model> adapter;
    List<Model> list = new ArrayList<Model>();

    private RadioGroup radioCcToGroup;
    private RadioButton radioTypeButton;
    private Button btn;

    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        setContentView(R.layout.main);

        listView = (ListView) findViewById(R.id.my_list);

        btn = (Button) findViewById(R.id.submit);

        btn.setOnClickListener(new View.OnClickListener() {
            int count = 0;

            @Override
            public void onClick(View view) {


                count = listView.getAdapter().getCount();
                for (int i = 0; i < count; i++) {
                    // here i am not able to get the records as getting on onItemClick of the listview
                }
            }
        });

        adapter = new MyAdapter(this, getModel());
        listView.setAdapter(adapter);
        listView.setOnItemClickListener(this);
    }

    @Override
    public void onItemClick(AdapterView<?> arg0, View v, int position, long arg3) {
        TextView label = (TextView) v.getTag(R.id.label);
        CheckBox checkbox = (CheckBox) v.getTag(R.id.check);
        Toast.makeText(v.getContext(),
                label.getText().toString() + " " + isCheckedOrNot(checkbox),
                Toast.LENGTH_LONG).show();

    }

    private String isCheckedOrNot(CheckBox checkbox) {
        if (checkbox.isChecked())
            return "is checked";
        else
            return "is not checked";
    }

    private List<Model> getModel() {
        list.add(new Model("Linux"));
        list.add(new Model("Windows7"));
        list.add(new Model("Suse"));
        list.add(new Model("Eclipse"));
        list.add(new Model("Ubuntu"));
        list.add(new Model("Solaris"));
        list.add(new Model("Android"));
        list.add(new Model("iPhone"));
        list.add(new Model("Java"));
        list.add(new Model(".Net"));
        list.add(new Model("PHP"));
        return list;
    }

Model.java

private String name;
    private boolean selected;

    public Model(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public boolean isSelected() {
        return selected;
    }

    public void setSelected(boolean selected) {
        this.selected = selected;
    }

推荐答案

您在 MyAdaptor.java 上有两个错误:

You got 2 mistakes here both on your MyAdaptor.java :

  1. 当您附加 onCheckedChangeListener 时,您只在需要创建新视图并且忘记列表视图重用视图的情况下才这样做.你应该在 if (convertView == null) 之外 setOnCheckedChangeListener.

  1. When you attach the onCheckedChangeListener you do it only when a new view needs to be created and you forget the case where the list view reuses the view. You should setOnCheckedChangeListener outside if (convertView == null).

似乎在滚动完成时也会调用 onCheckedChangeListener(因为 viewHolder.checkbox.setChecked(list.get(position).isSelected());).您可以通过在 viewHolder.checkbox 上使用 OnClickListener 或不调用 viewHolder.checkbox.setChecked() 来避免这种情况.

It seems that onCheckedChangeListener is called also when the scroll is done (because of viewHolder.checkbox.setChecked(list.get(position).isSelected());). You can avoid this by using OnClickListener over viewHolder.checkbox or not calling viewHolder.checkbox.setChecked().

这是我的代码:

private class ViewHolder {
    protected TextView text;
    protected CheckBox checkbox;
    protected RadioGroup radioGroup;
}

public class MyAdapter extends ArrayAdapter<Model> {

    private final List<Model> list;
    private final Activity context;
    boolean checkAll_flag = false;
    boolean checkItem_flag = false;

    public MyAdapter(Activity context, List<Model> list) {
        super(context, R.layout.row, list);
        this.context = context;
        this.list = list;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        ViewHolder viewHolder = null;
        if (convertView == null) {
            LayoutInflater inflator = context.getLayoutInflater();
            convertView = inflator.inflate(R.layout.row, null);

            viewHolder = new ViewHolder();
            viewHolder.text = (TextView) convertView.findViewById(R.id.label);
            viewHolder.checkbox = (CheckBox) convertView.findViewById(R.id.check);
            viewHolder.checkbox.setTag(position);
            viewHolder.radioGroup = (RadioGroup) convertView.findViewById(R.id.radioSex);
            viewHolder.radioGroup.setTag(position);

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

        viewHolder.text.setText(list.get(position).getName());
        viewHolder.checkbox.setChecked(list.get(position).isSelected());
        viewHolder.checkbox.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                CheckBox checkbox = (CheckBox) v;
                int getPosition = (Integer) checkbox.getTag();
                list.get(getPosition).setSelected(checkbox.isChecked());
            }
        });

        viewHolder.radioGroup.setOnCheckedChangeListener(new OnCheckedChangeListener() {

            @Override
            public void onCheckedChanged(RadioGroup group, int checkedId) {
                boolean isCcOrIsTo = (checkedId == R.id.cc);
                int getPosition = (Integer) group.getTag();
                list.get(getPosition).setCcOrIsTo(isCcOrIsTo);
            }
        });

        return convertView;
    }
}

请注意,我也添加了对无线电组的一些控制,因此 Model.java 已更改:

Notice i've added some control over the radiogroup too, so Model.java has changed:

public class Model {

    private String name;
    private boolean selected;
    private boolean isCcOrIsTo;

    public Model(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public boolean isSelected() {
        return selected;
    }

    public void setSelected(boolean selected) {
        this.selected = selected;
    }

    public boolean isCcOrIsTo() {
        return isCcOrIsTo;
    }

    public void setCcOrIsTo(boolean isCcOrIsTo) {
        this.isCcOrIsTo = isCcOrIsTo;
    }

    @Override
    public String toString() {
        String selectedString = selected ? "selected" : "not selected";
        String value = isCcOrIsTo ? "CC" : "To";
        return name+" -> "+selectedString+ " with value "+value;
    }
}

最后,您不需要 MainActivity.java 上的 onItemClick 来检查单击峰会按钮时的值是否正确:

Finally you don't need onItemClick on MainActivity.java, to check if the values are correct when you click the summit button :

public void onCreate(Bundle icicle) {
    super.onCreate(icicle);
    setContentView(R.layout.activity_main);

    listView = (ListView) findViewById(R.id.my_list);

    btn = (Button) findViewById(R.id.submit);

    btn.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View view) {
            for (Model m : list) {
                Log.i("Stack1", m.toString());
            }
        }
    });

    ArrayAdapter<Model> adapter = new MyAdapter(this, getModel());
    listView.setAdapter(adapter);
}

希望有帮助;)

这篇关于带有复选框、单选按钮、文本视图和按钮的列表视图在 android 中无法正常工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆