标签:
通用系列 ListView

/*** 特色功能:* ★ 通用(使用ListView和GridView的地方都可以用此类来简化)* ★ 简单,不需要重写BaseAdapter;* ★ 删除伴随着动画(不突兀);* ★ 数据和ListView都托管给了LouAdapter;* ★ 强制使用ViewHolder缓存;* ★ 局部刷新;* ★ 多选模式/单选模式的控制;(需要给Item布局设置selector才可以在视觉上区分是否为选中模式)* ★ 绑定ListView到this(即在使用的时候不用给ListView 设置Adapter);* ★ 以前在使用ListView的时候需要做这些处理:* {@code* // 查找ListView;* // 设置Adapter;* // 如果布局复杂的话还需要重新Adapter;* // 绑定数据;* }* ★ 现在只需要简单分配参数,即使是复杂的布局也可以很快实现出来:* {@code* ListView listView = new ListView(mContext);* int layoutId = android.R.layout.simple_list_item_1;* // <> 中的内容是你的Bean元素;* // 第一个参数(listView):被托管的ListView;* // 第二个参数(layoutId):ListView的Item布局;* // 方法assign:用来分配Bean和Item布局里视图的对应关系;* LouAdapter<String> adapter = new LouAdapter<String>(listView, layoutId) { @Override protected void assign(ViewHolder holder, String s) {holder.putText(android.R.id.text1, s);}};* }*/
「效果图的代码」
package com.lou.as.lou;import android.app.Activity;import android.os.Bundle;import android.view.View;import android.widget.AdapterView;import android.widget.ListView;import com.lyloou.android.activity.LouActivity;import com.lyloou.android.adapter.LouAdapter;import com.lyloou.android.util.Utoast;import java.util.Arrays;public class DemoAdapterActivity extends LouActivity {private Activity mContext;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);mContext = this;setContentView(initListView());}private View initListView() {final LouAdapter<String> adapter = new LouAdapter<String>(new ListView(mContext), android.R.layout.simple_list_item_1) {@Overrideprotected void assign(ViewHolder holder, String s) {// 用视图显示数据holder.putText(android.R.id.text1, s);}};// 初始化列表adapter.initList(Arrays.asList("添加元素", "长按更新元素"));// 添加点击事件adapter.getBindView().setOnItemClickListener(new AdapterView.OnItemClickListener() {@Overridepublic void onItemClick(AdapterView<?> parent, View view, int position, long id) {if (adapter.getItem(position).equals("添加元素")) {// 添加元素adapter.addItem("我是新元素" + adapter.getCount());} else if (adapter.getItem(position).equals("删除我呀")) {// 删除元素(有删除动画)adapter.deleteItemWithAnim(position);} else if (adapter.getItem(position).contains("我是新元素")) {adapter.getList().set(position, "删除我呀");adapter.updateView(position);} else if (adapter.getItem(position).equals("好吧,我投降")) {adapter.deleteItemWithAnim(position);}}});adapter.getBindView().setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {@Overridepublic boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {if (adapter.getItem(position).equals("长按更新元素")) {adapter.getList().set(position, "已被更新的元素");adapter.updateView(position); // 局部更新} else if (adapter.getItem(position).equals("已被更新的元素")) {adapter.getList().set(position, "都更新过了,还按我做啥");adapter.updateView(position);} else if (adapter.getItem(position).equals("都更新过了,还按我做啥")) {adapter.getList().set(position, "再按我,我就消失");adapter.updateView(position);} else if (adapter.getItem(position).equals("再按我,我就消失")) {adapter.getList().set(position, "好吧,我投降");adapter.updateView(position);} else if (adapter.getItem(position).equals("添加元素")) {Utoast.show(mContext, "滚犊子,连我也想删?\n活得不耐烦了!");return true;}return false;}});return adapter.getBindView();}}
「通用源代码」
package com.lyloou.android.adapter;import android.content.Context;import android.graphics.Bitmap;import android.graphics.Color;import android.graphics.PorterDuff;import android.graphics.drawable.Drawable;import android.util.SparseArray;import android.util.SparseBooleanArray;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.view.animation.Animation;import android.view.animation.Transformation;import android.widget.AbsListView;import android.widget.BaseAdapter;import android.widget.CheckBox;import android.widget.CompoundButton;import android.widget.ImageView;import android.widget.TextView;import com.lyloou.android.util.Uscreen;import com.lyloou.android.util.Uview;import java.util.ArrayList;import java.util.List;/*** Created by Lou on 2016/3/23.* Updated By Lou on 2016/05/07.*//*** 特色功能:* ★ 通用(使用ListView和GridView的地方都可以用此类来简化)* ★ 简单,不需要重写BaseAdapter;* ★ 删除伴随着动画(不突兀);* ★ 动态添加元素;* ★ 强制使用ViewHolder缓存;* ★ 局部刷新;* ★ 多选模式/单选模式的控制;* ★ 绑定ListView到this(即在使用的时候不用给ListView 设置Adapter);* ★ 以前在使用ListView的时候需要做这些处理:* {@code* // 查找ListView;* // 设置Adapter;* // 如果布局复杂的话还需要重新Adapter;* // 绑定数据;* }* ★ 现在只需要简单分配参数,即使是复杂的布局也可以很快实现出来:* {@code* ListView listView = new ListView(mContext);* int layoutId = android.R.layout.simple_list_item_1;* // <> 中的内容是你的Bean元素;* // 第一个参数(listView):被托管的ListView;* // 第二个参数(layoutId):ListView的Item布局;* // 方法assign:用来分配Bean和Item布局里视图的对应关系;* LouAdapter<String> adapter = new LouAdapter<String>(listView, layoutId) { @Override protected void assign(ViewHolder holder, String s) {holder.putText(android.R.id.text1, s);}};* }*/public abstract class LouAdapter<T> extends BaseAdapter {private ArrayList<T> mLists;private Context mContext;private AbsListView mListView;private int mLayoutId;public LouAdapter(AbsListView listView, int layoutId) {mContext = listView.getContext();mListView = listView;mLayoutId = layoutId;mLists = new ArrayList<T>();mListView.setAdapter(this);}@Overridepublic int getCount() {return mLists.size();}@Overridepublic T getItem(int position) {return mLists.get(position);}@Overridepublic long getItemId(int position) {return position;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {return updateView(position, convertView);}public AbsListView getBindView() {return mListView;}// -------- 添加 choice调用(2016.03.25)public void clearChoice() {mListView.clearChoices();updateChange();// selectAllChoice(false);mListView.postDelayed(new Runnable() {@Overridepublic void run() {// 注意需要使用Runnable才能生效;// 参考资料[ListView selection remains persistent after exiting choice mode]// (http://stackoverflow.com/questions/9754170/listview-selection-remains-persistent-after-exiting-choice-mode)mListView.setChoiceMode(AbsListView.CHOICE_MODE_NONE);}}, 160);}public void setChoiceMode(int mode) {mListView.setChoiceMode(mode);}public int getChoiceMode() {return mListView.getChoiceMode();}public void deleteChoicedItem() {if (mListView.getChoiceMode() != AbsListView.CHOICE_MODE_NONE) {// 获取被选中的ITEM;SparseBooleanArray sparseBooleanArray = mListView.getCheckedItemPositions();ArrayList<T> deleteLists = new ArrayList<T>();for (int i = 0; i < sparseBooleanArray.size(); i++) {if (sparseBooleanArray.valueAt(i)) {deleteLists.add(mLists.get(sparseBooleanArray.keyAt(i)));}}mLists.removeAll(deleteLists);mListView.clearChoices();updateChange();}}public void selectAllChoice(boolean selectAll) {for (int i = 0; i < mListView.getCount(); i++) {mListView.setItemChecked(i, selectAll);}updateChange();}// ~~~~~~~~~~~~/*** contain 来表示是否已经包含元素;(可能需要重写,如果允许重复的话,就不必要重写了);** @param o 要判断的元素* @return 返回的结果*/protected boolean contain(T o) {if (mLists.contains(o)) {return true;}return false;}/*** 用数据来更新视图;** @param position* @param convertView* @return*/private View updateView(int position, View convertView) {ViewHolder holder = ViewHolder.getInstance(mContext, mLayoutId, convertView, position);assign(holder, getItem(position));return holder.getConvertView();}/*** 当更改了某一个Item之后,可以通过updateView(position);的方式只更新这一个Item;** @param position*/public void updateView(int position) {View convertView = getIndexView(position);updateView(position, convertView);}/*** @param holder* @param t*/protected abstract void assign(ViewHolder holder, T t);/*** 获取可见元素的View;** @param position* @return*/public View getIndexView(int position) {int currentIndex = position - mListView.getFirstVisiblePosition();if (currentIndex < 0 || currentIndex >= mLists.size()) {return null;}return mListView.getChildAt(currentIndex);}public void addItem(T o, boolean filter) {if (filter && contain(o)) {return;}mLists.add(o);updateChange();}/*** 默认过滤添加的元素;** @param o*/public void addItem(T o) {addItem(o, true);}public List<T> getList() {return mLists;}/*** 初始化元素** @param list*/public void initList(List<T> list) {mLists.clear();mLists.addAll(list);updateChange();}public void deleteItem(T o) {mLists.remove(o);updateChange();}public void deleteItem(int position) {mLists.remove(position);updateChange();}/*** 高度变为0后删除元素;** @param position*/public void deleteItemWithAnim(final int position) {final View view = getIndexView(position);final int initHeight = view.getMeasuredHeight();Animation anim = new Animation() {@Overrideprotected void applyTransformation(float interpolatedTime,Transformation t) {if (mLists.size() > 0 && interpolatedTime == 1) {// 高度为0时删除元素,并更新 adapterif (view.getTag() instanceof ViewHolder) {((ViewHolder) view.getTag()).mark = ViewHolder.MARK.DELETE;deleteItem(position);}} else {// 不断的改变高度,直到高度为0;view.getLayoutParams().height = initHeight- (int) (initHeight * interpolatedTime);view.requestLayout();}}};anim.setDuration(300);view.startAnimation(anim);}public void updateChange() {notifyDataSetChanged();}public void clear() {mLists.clear();updateChange();}/*** Created by Lou on 2016/3/23.*/public static class ViewHolder {private SparseArray<View> mViews;private View mConvertView;private int mPosition;MARK mark;enum MARK {NORMAL, DELETE}private ViewHolder(Context context, int layoutId, int position) {mPosition = position;mViews = new SparseArray<View>();mConvertView = LayoutInflater.from(context).inflate(layoutId, null);mConvertView.setTag(this);}// 权限:default 包级私有static ViewHolder getInstance(Context context, int layoutId, View convertView, int position) {boolean needInflate = convertView == null || ((ViewHolder) convertView.getTag()).mark == MARK.DELETE;if (needInflate) {return new ViewHolder(context, layoutId, position);}return (ViewHolder) convertView.getTag();}public int getPosition() {return mPosition;}public View getConvertView() {return mConvertView;}@SuppressWarnings("unchecked")public <T extends View> T getView(int viewId) {View view = mViews.get(viewId);if (view == null) {view = mConvertView.findViewById(viewId);mViews.put(viewId, view);}return (T) view;}public ViewHolder putText(int viewId, String text) {View v = getView(viewId);if (v instanceof TextView) {((TextView) v).setText(text);}return this;}public ViewHolder putText(int viewId, int resId) {View v = getView(viewId);if (v instanceof TextView) {((TextView) v).setText(resId);}return this;}public ViewHolder putImg(int viewId, int resId) {View v = getView(viewId);if (v instanceof ImageView) {((ImageView) v).setImageResource(resId);}return this;}/*** @param viewId 视图Id* @param resId 图片资源Id* @param roundShape 是否是圆角图片* @return*/public ViewHolder putImg(int viewId, int resId, boolean roundShape) {if (roundShape) {View v = getView(viewId);if (v instanceof ImageView) {Bitmap bitmap = Uview.getBitmapByXfermode(v.getContext(),resId,Color.parseColor("#993382"),Uscreen.dp2Px(v.getContext(), 48),Uscreen.dp2Px(v.getContext(), 48),PorterDuff.Mode.SRC_IN);((ImageView) v).setImageBitmap(bitmap);}} else {return putImg(viewId, resId);}return this;}public ViewHolder putImg(int viewId, Bitmap bitmap) {View v = getView(viewId);if (v instanceof ImageView) {((ImageView) v).setImageBitmap(bitmap);}return this;}public ViewHolder putImg(int viewId, Drawable drawable) {View v = getView(viewId);if (v instanceof ImageView) {((ImageView) v).setImageDrawable(drawable);}return this;}public void putCbtn(int viewId, int status, boolean clickable) {View v = getView(viewId);if (v instanceof CompoundButton) {CompoundButton cb = (CheckBox) v;if (status != 0) {cb.setChecked(true);} else {cb.setChecked(false);}cb.setClickable(clickable);}}}}
【Android】通用系列 —— 用简单通用的方式操作ListView
标签:
原文地址:http://blog.csdn.net/ly1414725328/article/details/51337043