最近遇到的一个小需求,可以简化为该模型,因此写一个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 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(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);
}
}
public class ListViewAdapter extends BaseAdapter {
private List list;
private Context context;
private int checkedPos = -1;
public ListViewAdapter(Context context, List 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;
}
}
主要是selector