现在的位置: 首页 > 综合 > 正文

ListView利用CheckedTextViewr实现条目单选效果

2017年02月19日 ⁄ 综合 ⁄ 共 3232字 ⁄ 字号 评论关闭

最近遇到的一个小需求,可以简化为该模型,因此写一个Demo以记录。其实比较简单,主要利用Selector,只是网上找了一番也没找到ListView在点击后背景色一直是checked的,大多数是pressed效果(点击瞬间变背景),或者是利用RadioButton or CheckBox之类,这些都不是我想要的。

先放效果图:

分析:

最简单的ListView,其中条目View继承了CheckedTextView。该类实现了Checkable接口,调用其setChecked方法可以匹配selector中android:state_checked="true"属性,做到点击后效果保持。因此也可以自定义View实现Checkable,实现setChecked()、isChecked()、toggle()三个方法即可:

    public void toggle() {
        setChecked(!mChecked);
    }

    public boolean isChecked() {
        return mChecked;
    }

    public void setChecked(boolean checked) {
        if (mChecked != checked) {
            mChecked = checked;
            refreshDrawableState();
            notifyAccessibilityStateChanged();
        }
    }

做到单选效果,本来我是想到用比较笨的方法,即点击时遍历ItemView,消除其他所有item 的checked状态;还想到了定义一个lastCheckedView变量记录上一次被点击的,再次点击时消除Checked状态。。后来发现只需要在Adapter中getView时判断position,然后notify刷新即可。

如果要实现多选效果,在点击时直接toggle即可,不需要考虑消除其他item状态。

代码如下:

MainActivity.java

public class MainActivity extends Activity {

	private ListView mListView;
	private ListViewAdapter<String> mAdapter;
	private static String[] strs = { "Felix", "Jane", "Tom", "Bob", "Jason",
			"Christina", "Susan", "Felix", "Jane", "Tom", "Bob", "Jason",
			"Christina", "Susan", "Felix", "Jane", "Tom", "Bob", "Jason",
			"Christina", "Susan" };

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

		mListView = (ListView) findViewById(R.id.lv);

		mAdapter = new ListViewAdapter<String>(this, Arrays.asList(strs));
		mListView.setAdapter(mAdapter);

		mListView.setOnItemClickListener(new OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView<?> parent, View view,
					int position, long id) {
				if (view instanceof CheckedTextView) {
					mAdapter.setCheckedAtPosition(position);
					mAdapter.notifyDataSetChanged();
				}
			}
		});
		// lv.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
	}
}

ListViewItemView.java

public class ListViewItemView extends CheckedTextView {
	
	public ListViewItemView(Context context) {
		super(context);
		initView();
	}

	public ListViewItemView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		initView();
	}

	public ListViewItemView(Context context, AttributeSet attrs) {
		super(context, attrs);
		initView();
	}
	
	private void initView(){
		this.setPadding(40, 10, 10, 10);
		this.setTextSize(30);
		this.setBackgroundResource(R.drawable.item_selector);
	}
	
	
}

ListViewAdapter.java

public class ListViewAdapter <T> extends BaseAdapter {

	private List<T> list;
	private Context context;
	private int checkedPos = -1;
	
	public ListViewAdapter(Context context, List<T> asList) {
		this.list = asList;
		this.context = context;
	}

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

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

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

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		
		if(convertView == null){
			convertView = new ListViewItemView(context);
		}
		((TextView)convertView).setText((CharSequence) getItem(position));
		
		if(checkedPos == position){
			//说明该位置需要checked
			((ListViewItemView)convertView).setChecked(true);
		}else{
			//不需要checked
			((ListViewItemView)convertView).setChecked(false);
		}
		
		return convertView;
	}
	
	/**
	 * 设置哪一个条目被选中
	 * @param pos
	 */
	public void setCheckedAtPosition(int pos){
		this.checkedPos = pos;
	}

}

xml文件

主要是selector

    <item android:drawable="@color/wheat" android:state_checked="true"/> <!-- 代表选中状态 -->
    <item android:state_pressed="true" android:drawable="@color/blanchedalmond"/> <!-- 代表点击状态 -->
    <item android:drawable="@color/blanchedalmond"></item> <!-- 默认背景 -->

抱歉!评论已关闭.