1. 程式人生 > >ListView與RadioButton組合——自定義單選列表

ListView與RadioButton組合——自定義單選列表

Android自帶的RadioButton單選框只支援新增文字,我們自己寫Adapter實現自定義的RadioButton

首先item的XML原始碼

search_user_item.xml (現在只是文字+單選按鈕+自定義背景,可以根據需要隨意擴充套件)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/search_user_list_item"
    android:layout_width="fill_parent"
    android:layout_height="30dp"
    android:layout_marginBottom="10dp"
    android:layout_marginTop="10dp"
    android:background="@drawable/more_item_press"
    android:gravity="center_vertical"
    android:orientation="horizontal" >

    <TextView
        android:id="@+id/search_user_name"
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:layout_marginLeft="30dp"
        android:gravity="left"
        android:textColor="@android:color/black"
        android:textSize="16sp" />

    <RadioButton
        android:id="@+id/radio_btn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp" />

</LinearLayout>

Listview就是用系統自帶的

    <ListView
        android:id="@+id/search_user_list"
        android:layout_width="fill_parent"
        android:layout_height="200dp"
        android:layout_marginLeft="5dp"
        android:layout_marginRight="5dp"
        android:paddingBottom="5dp"
        android:cacheColorHint="@android:color/transparent"
        android:divider="@null"
        android:listSelector="@android:color/transparent"
        android:visibility="gone" >
    </ListView>

再來是Adapter程式碼

SearchUserAdapter.java (具體改動寫在程式碼註釋裡面)

package ouc.sei.suxin.android.ui.adapter;

import java.util.HashMap;
import java.util.List;

import ouc.sei.suxin.R;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.LinearLayout;
import android.widget.RadioButton;
import android.widget.TextView;

public class SearchUserAdapter extends BaseAdapter {
	
	private Context context;
	private List<String> userList;
	HashMap<String,Boolean> states=new HashMap<String,Boolean>();//用於記錄每個RadioButton的狀態,並保證只可選一個
	
	public SearchUserAdapter(Context context, List<String> userList)
	{
		this.context = context;
		this.userList= userList;
	}
	
	@Override
	public int getCount() {
		return userList.size();
	}

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

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

	@Override
	public View getView(final int position, View convertView, ViewGroup parent) {
		ViewHolder holder;
		if (convertView == null) {
			convertView = LayoutInflater.from(context).inflate(R.layout.search_user_item, null);
			holder = new ViewHolder();
			holder.background = (LinearLayout) convertView.findViewById(R.id.search_user_list_item);
			holder.userName = (TextView) convertView.findViewById(R.id.search_user_name);
			convertView.setTag(holder);
		}else{
			holder=(ViewHolder) convertView.getTag();
		}
        final RadioButton radio=(RadioButton) convertView.findViewById(R.id.radio_btn);
		holder.rdBtn = radio;
		
		holder.userName.setText(userList.get(position));
		//根據Item位置分配不同背景		
		if(userList.size() > 0)
		{
			if(userList.size() == 1)
			{
				holder.background.setBackgroundResource(R.drawable.more_item_press);
			}
			else{
				if(position == 0){
					holder.background.setBackgroundResource(R.drawable.more_itemtop_press);
				}
				else if(position == userList.size()-1){
					holder.background.setBackgroundResource(R.drawable.more_itembottom_press);
				}
				else{
					holder.background.setBackgroundResource(R.drawable.more_itemmiddle_press);
				}
			}
		}
	//當RadioButton被選中時,將其狀態記錄進States中,並更新其他RadioButton的狀態使它們不被選中	
        holder.rdBtn.setOnClickListener(new View.OnClickListener() {
            
            public void onClick(View v) {
              
                //重置,確保最多隻有一項被選中
                for(String key:states.keySet()){
                    states.put(key, false);
                    
                }
                states.put(String.valueOf(position), radio.isChecked());
                SearchUserAdapter.this.notifyDataSetChanged();
            }
        });
		
        boolean res=false;
        if(states.get(String.valueOf(position)) == null || states.get(String.valueOf(position))== false){
            res=false;
            states.put(String.valueOf(position), false);
        }
        else
            res = true;
        
        holder.rdBtn.setChecked(res);

		return convertView;
	}
	
	static class ViewHolder {
	   LinearLayout background;
           TextView userName;
           RadioButton rdBtn;
	}

}

List適配程式碼(與一般無異):
	adapter = new SearchUserAdapter(this, searchUserList);
	searchUserLV.setAdapter(adapter);
	searchUserLV.setVisibility(View.VISIBLE);
	setListViewHeightBasedOnChildren(searchUserLV);

這裡還根據內容動態設定了一下,具體函式如下:
	public void setListViewHeightBasedOnChildren(ListView listView) {

		Adapter listAdapter = listView.getAdapter();

		if (listAdapter == null) {
			return;
		}

		int totalHeight = 0;
		int viewCount = listAdapter.getCount();
		for (int i = 0; i < viewCount; i++) {
			View listItem = listAdapter.getView(i, null, listView);
			listItem.measure(0, 0);
			totalHeight += listItem.getMeasuredHeight();
		}

		ViewGroup.LayoutParams params = listView.getLayoutParams();

		params.height = totalHeight
				+ (listView.getDividerHeight() * (listAdapter.getCount()-1)) + 10;//加10是為了適配自定義背景

		listView.setLayoutParams(params);
	}

當需要獲取ListView中RadioButton的選擇狀態時,可以直接看Adapter中的states,具體如下:
	// 根據RadioButton的選擇情況確定使用者名稱
	for (int i = 0, j = searchUserLV.getCount(); i < j; i++) {
		View child = searchUserLV.getChildAt(i);
		RadioButton rdoBtn = (RadioButton) child
				.findViewById(R.id.radio_btn);
		if (rdoBtn.isChecked())
			searchUser = searchUserList.get(i);
	}

這裡的searchUserList是呼叫後臺服務獲取的使用者名稱列表,通過states獲取選中使用者名稱進行後續操作

效果圖: