带有微调器和单选按钮的Android Listview

时间:2015-09-05 20:29:45

标签: android android-listview

我有一个自定义数组适配器,它在列表的每一行中使用微调器和单选按钮实现列表视图。选择单选按钮时,每个列表单选按钮都会被选中。如何通过单选列表行进行选择。

如何使用单选按钮仅选择单个列表。

抱歉英文不好。

这是代码。

getView():

@Override
public View getView(int position, View convertView, ViewGroup parent)
{
    View view = null;

    if (convertView == null)
    {
        LayoutInflater inflator = myContext.getLayoutInflater();
        view = inflator.inflate(R.layout.single_list_row, null);

        final ViewHolder viewHolder = new ViewHolder();
        viewHolder.data = new DataModel(myContext);
        viewHolder.spin = (Spinner) view.findViewById(R.id.spinner1);
        viewHolder.spin.setAdapter(viewHolder.data.getAdapter());
        viewHolder.radioBtn = (RadioButton) view.findViewById(R.id.choice);
        viewHolder.radioBtn.setTag(position);
        //viewHolder.radioBtn.setChecked(selectedPos == position);

        viewHolder.spin.setOnItemSelectedListener(new OnItemSelectedListener()
        {
            @Override
            public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3)
            {
                viewHolder.data.setSelected(arg2);
            }

            @Override
            public void onNothingSelected(AdapterView<?> arg0) {
            }
        });

        viewHolder.radioBtn.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View view)
            {
                selectedPos = (Integer)view.getTag();
            }
        });

        view.setTag(viewHolder);
    }
    else
    {
        view = convertView;
    }

    ViewHolder holder = (ViewHolder) view.getTag();
    holder.spin.setSelection(getItem(position).getSelected());
    holder.radioBtn.setChecked(selectedPos == position);
    return view;
}

main_activity.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <EditText android:id="@+id/inputSearch"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:hint="Search list.."
        android:inputType="textVisiblePassword"/>

    <ListView
        android:id="@+id/listview1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:cacheColorHint="#f8f8ff"
        android:divider="#000000"
        android:fadeScrollbars="true"
        android:choiceMode="singleChoice"
        android:descendantFocusability="beforeDescendants"
        android:fastScrollEnabled="true"
        android:footerDividersEnabled="true"
        android:textFilterEnabled="true"
        android:textStyle="normal" />
</LinearLayout>

single_row_list.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout android:id="@+id/relativeLayout1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
xmlns:android="http://schemas.android.com/apk/res/android">

<LinearLayout
    android:layout_centerVertical="true"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentLeft="true"
    android:orientation="vertical"
    android:gravity="center_vertical">

    <Spinner
        android:id="@+id/spinner1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:entries="@array/options"
        android:prompt="@string/spinner_prompt" />

    <RadioButton
        android:layout_height="wrap_content"
        android:id="@+id/choice"
        android:layout_width="wrap_content"
        android:layout_centerVertical="true"
        android:layout_alignParentRight="true"
        android:gravity="center_vertical"
        android:checked="false"/>
   </LinearLayout>
   </RelativeLayout>

MainActivity.java:

@Override
protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    lv = (ListView) this.findViewById(R.id.listview1);
    lv.setChoiceMode(ListView.CHOICE_MODE_SINGLE);

    DataModel data = new DataModel(this);
    DataModel data1 = new DataModel(this);
    DataModel data2 = new DataModel(this);
    DataModel data3 = new DataModel(this);
    DataModel data4 = new DataModel(this);

    d = new ListAdapter(this, R.layout.single_list_row, new DataModel[] { data, data1, data2, data3, data4 });
    lv.setAdapter(d);
}

DataModel Class

 public class DataModel { 

    private int selected; 
    private ArrayAdapter<CharSequence> adapter; 

    public DataModel(Context parent){ 
           adapter = ArrayAdapter.createFromResource(parent, R.array.options, android.R.layout.simple_spinner_item); 
           sadapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
     }

    public ArrayAdapter<CharSequence> getAdapter() { return adapter; } 

    public int getSelected() { return selected; } 

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

完整适配器类:

public class ListAdapter extends ArrayAdapter<DataModel>
{
private Activity myContext;
int selectedPos = 0;
int flag = 0;
int pos = 0;

public ListAdapter(Activity context, int textViewResourceId, DataModel[] objects)
{
    super(context, textViewResourceId, objects);
    myContext = context;
}

static class ViewHolder
{
    protected DataModel data;
    protected Spinner spin;
    protected RadioButton radioBtn;
}

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

    if (view == null)
    {
        LayoutInflater inflator = myContext.getLayoutInflater();
        view = inflator.inflate(R.layout.single_list_row, null);

        viewHolder = new ViewHolder();
        viewHolder.data = new DataModel(myContext);

        viewHolder.spin = (Spinner) view.findViewById(R.id.spinner1);
        viewHolder.spin.setAdapter(viewHolder.data.getAdapter());
        viewHolder.radioBtn = (RadioButton) view.findViewById(R.id.choice);
        viewHolder.radioBtn.setTag(position);

        if(selectedPos == position)
        {
            viewHolder.radioBtn.setChecked(true);
        }
        else
        {
            viewHolder.radioBtn.setChecked(false);
        }

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

    //viewHolder.data = new DataModel(myContext);
    //viewHolder.spin.setAdapter(viewHolder.data.getAdapter());

    viewHolder.spin.setOnItemSelectedListener(new OnItemSelectedListener()
    {
        @Override
        public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3)
        {
            viewHolder.data.setSelected(arg2);
        }

        @Override
        public void onNothingSelected(AdapterView<?> arg0) {
        }
    });

    viewHolder.radioBtn.setOnClickListener(new View.OnClickListener()
    {
        @Override
        public void onClick(View view)
        {
            selectedPos = (Integer)view.getTag();
        }
    });

    viewHolder.spin.setSelection(getItem(position).getSelected());
    viewHolder.radioBtn.setChecked(selectedPos == position);
    view.setTag(viewHolder);
    return view;
}
}

2 个答案:

答案 0 :(得分:0)

首先,

RadioButtons被视为有效元素,

你可以添加吗,

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout android:id="@+id/relativeLayout1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:descendantFocusability="blocksDescendants"
xmlns:android="http://schemas.android.com/apk/res/android">

并添加,

            android:clickable="false"
            android:focusable="false"
            android:focusableInTouchMode="false"

到您的RadioButton元素,否则您将无法获得这些点击事件。

我在你的代码中看到了一些问题,试试看

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

    if (view == null)
    {
        LayoutInflater inflator = myContext.getLayoutInflater();
        view = inflator.inflate(R.layout.single_list_row, null);

        viewHolder = new ViewHolder();

        viewHolder.spin = (Spinner) view.findViewById(R.id.spinner1);
        viewHolder.radioBtn = (RadioButton) view.findViewById(R.id.choice);

        view.setTag(viewHolder);

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


        viewHolder.data = new DataModel(myContext);
        viewHolder.spin.setAdapter(viewHolder.data.getAdapter());
        viewHolder.radioBtn.setTag(position);

        viewHolder.spin.setOnItemSelectedListener(new OnItemSelectedListener()
        {
            @Override
            public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3)
            {
                viewHolder.data.setSelected(arg2);
            }

            @Override
            public void onNothingSelected(AdapterView<?> arg0) {
            }
        });

        viewHolder.radioBtn.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View view)
            {
                selectedPos = (Integer)view.getTag();
            }
        });


    viewHolder.spin.setSelection(getItem(position).getSelected());
    viewHolder.radioBtn.setChecked(selectedPos == position);
    view.setTag(viewHolder);
    return view;
}

问题在于此代码,

viewHolder.radioBtn.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View view)
            {
                selectedPos = (Integer)view.getTag();
            }
        });

这个(Integer)view.getTag()给出了位置,所以if语句都是真的。

我建议你在DataModel中保持所选状态形成一个布尔值,并使用它来维护所选的单选按钮。

请发布完整的适配器类,看看你在那里做了什么。

答案 1 :(得分:0)

我得到了解决方案。

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

    if (view == null)
    {
        LayoutInflater inflator = myContext.getLayoutInflater();
        view = inflator.inflate(R.layout.single_list_row, null);

        viewHolder = new ViewHolder();
        viewHolder.data = new DataModel(myContext);

        viewHolder.selectedText = (TextView) view.findViewById(R.id.singleitem);
        viewHolder.spin = (Spinner) view.findViewById(R.id.spinner1);
        viewHolder.spin.setAdapter(viewHolder.data.getAdapter());
        viewHolder.radioBtn = (RadioButton) view.findViewById(R.id.choice);

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

    viewHolder.spin.setOnItemSelectedListener(new OnItemSelectedListener()
    {
        @Override
        public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3)
        {
            viewHolder.data.setSelected(arg2);
            viewHolder.selectedText.setText(viewHolder.data.getText());
            //Log.v("", String.valueOf(viewHolder.spin.getSelectedItemPosition()));
        }

        @Override
        public void onNothingSelected(AdapterView<?> arg0)
        {
        }
    });

    if(flag != 1)
    {
        if (selectedPos == position)
        {
            viewHolder.radioBtn.setChecked(true);
        }
        else
        {
            viewHolder.radioBtn.setChecked(false);
        }
    }
    else
    {
        viewHolder.radioBtn.setChecked(true);
    }

    viewHolder.radioBtn.setOnClickListener(new View.OnClickListener()
    {
        @Override
        public void onClick(View view)
        {
            if(flag != 1)
            {
                if (((RadioButton) view).isChecked())
                {
                    selectedPos = position;
                }
                else
                {
                    selectedPos = -1;
                }
            }
            else
            {
                ((RadioButton) view).setChecked(true);
            }
            notifyDataSetChanged();
        }
    });

    //viewHolder.spin.setSelection(getItem(position).getSelected());
    viewHolder.selectedText.setText(viewHolder.data.getText());
    view.setTag(viewHolder);
    return view;
}