編輯:關於Android編程
package com.scott.uidemo.adapter; import android.content.Context; import android.graphics.Bitmap; import android.media.Image; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.AbsListView; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.List; /** * author: scott * Created at scott on 2016/8/9. */ public abstract class ListViewBaseAdapterextends BaseAdapter { protected List mDatas; protected Context mContext; protected LayoutInflater mInflater; private final String TAG = "ListViewBaseAdapter"; public ListViewBaseAdapter(List datas, Context context) { mDatas = datas; mContext = context; mInflater = LayoutInflater.from(context); } @Override public int getCount() { return mDatas.size(); } @Override public Object getItem(int position) { return mDatas.get(position); } @Override public long getItemId(int position) { return position; } @Override public int getViewTypeCount() { return super.getViewTypeCount(); } @Override public int getItemViewType(int position) { return super.getItemViewType(position); } @Override public View getView(int position, View convertView, ViewGroup parent) { BaseViewHolder bVh;
/由於parent為AbsListView實例,而如果我們inflate itemView,那們itemview的 //layoutparams為GroupParams,這樣會丟失itemview根布局的margin屬性,所以 //在外部添加一個Linearlayout相當於加載後itemview的layoutparams為marginparams LinearLayout ll = new LinearLayout(mContext); ll.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));if (convertView == null) {
convertView = mInflater.inflate(onInflateItemView(getItemViewType(position)), ll, true);
bVh = onCreateViewHolder(convertView);
//保存當前itemview對應的type
bVh.viewType = getItemViewType(position);
convertView.setTag(bVh);
} else {
bVh = (BaseViewHolder) convertView.getTag();
//當當前可復用的convertview的viewtype類型和當前需要的的view的viewtype類型
//不相等時,那麼無法復用該view,需要重新加載一個
if (bVh.viewType != getItemViewType(position)) {
convertView = mInflater.inflate(onInflateItemView(getItemViewType(position)), ll, true);
bVh = onCreateViewHolder(convertView);
bVh.viewType = getItemViewType(position);
convertView.setTag(bVh);
}
}
onBindViewHolder(bVh, position);
return convertView;
}
/***
* 當初始化ViewHolder會調用該方法,我們需要返回一個繼承自BaseViewHolder
* 的類的對象,該對象應該包含了itemView中我們需要的控件的實例,並且這些
* 實例已經被初始化
*
* @param itemView
* @return
*/
protected abstract BaseViewHolder onCreateViewHolder(View itemView);
/***
* 當我們需要為ViewHolder中的空件設置值的時候會調用該方法,該方法中我們需要根據position為
* ViewHolder中的控件設置值
*
* @param vh
* @param position
*/
protected abstract void onBindViewHolder(BaseViewHolder vh, int position);
/**
* 當我們需要加載item的布局文件時會調用該方法,我們需要返回一個布局的資源ID
*
* @return
*/
protected abstract int onInflateItemView(int viewType);
/***
* 所有的子類都該有一個內部的ViewHolder類繼承自該類
* 繼承自該類的viewholder只需將其中的view變量和對應的resId用
* BindView注解綁定即可
*
* @BindView TextView tv;
* 這樣在onCreateViewHolder時只需new一個ViewHolder並返回即可
*/
abstract class BaseViewHolder {
private int viewType;
View itemView;
protected BaseViewHolder(View v) {
itemView = v;
bindView();
}
/***
* 把viewholder中的view變量綁定到對應的view
*/
private void bindView() {
//this 是runntime變量,只有在運行時才能確定
Class cls = this.getClass();
Field[] fields = cls.getDeclaredFields();
for (Field f : fields) {
BindView bv = f.getAnnotation(BindView.class);
if (bv == null) {
continue;
}
f.setAccessible(true);
View v = itemView.findViewById(bv.value());
try {
f.set(this, v);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
/***
* 將當前的數據和控件綁定,但是傳入的數據的類必須在類上面標識
* BindData注解,元素值可以為空
* 而類中的字段必須標識@BindData(resId)注解
* 相當於將字段值和控件綁定
* @param data
*/
protected void bindData(Object data) {
Class cls = data.getClass();
BindData bd = (BindData) cls.getAnnotation(BindData.class);
//當前傳入的data沒有標識BindData注解,則無法進行數據綁定
if (bd == null) {
return;
}
Field[] fields = cls.getFields();
for (Field f : fields) {
BindData bData = f.getAnnotation(BindData.class);
//當前字段沒有標識BindData注解則無法綁定數據
if (bData == null) {
continue;
}
Class vCls = getClass();
Field[] vFields = vCls.getDeclaredFields();
for (Field vf : vFields) {
//如果當前ViewHolder中的控件字段沒有綁定資源id,
//相當於沒有初始化則無法綁定數據
BindView bv = vf.getAnnotation(BindView.class);
if (bv == null) {
continue;
}
f.setAccessible(true);
//綁定數據
setValue(vf, f, data, bv, bData);
}
}
}
/***
* 綁定當前數據
* @param vf viewholder 中的字段
* @param f data 中的字段
* @param data 數據
* @param bv viewholder 中view字段的BindView注解對象
* @param bData Data 中的 值字段的BindData 注解對象
*/
private void setValue(Field vf, Field f, Object data
, BindView bv, BindData bData) {
//當字段的resId 和 控件的resId 相同則進行數據綁定
//當前只支持TextView 綁定String 數據
//ImageView 綁定 Bitmap 數據
if (bv.value() == bData.value()) {
if (vf.getType() == TextView.class) {
try {
Object o = vf.get(this);
TextView tv = (TextView) o;
tv.setText((String) f.get(data));
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
if (vf.getType() == ImageView.class) {
try {
Object o = vf.get(this);
ImageView iv = (ImageView) o;
iv.setImageBitmap((Bitmap) f.get(data));
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
}
/***
* 用於標識將資源id和控件進行綁定,元素不可為空
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
protected @interface BindView {
int value();
}
/***
* 用於標識將數據Moudle 和 指定的資源id對應的控件進行綁定,
* 元素可為空,默認為 -1, 當標識moudle類時可以為空,但標識
* 字段時不能為空,否則無法綁定
*/
@Target({ElementType.FIELD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface BindData {
int value() default -1;
}
}
用法:
moudle
package com.scott.uidemo.moudle;
import android.graphics.Bitmap;
import com.scott.uidemo.R;
import com.scott.uidemo.adapter.ListViewBaseAdapter;
/**
* author: scott
* Created at scott on 2016/8/9.
*/
@ListViewBaseAdapter.BindData
public class TestMoudle {
@ListViewBaseAdapter.BindData(R.id.tv_content)
public String data;
@ListViewBaseAdapter.BindData(R.id.iv_content)
public Bitmap bmp;
}
package com.scott.uidemo.adapter; import android.content.Context; import android.view.View; import android.widget.ImageView; import android.widget.TextView; import com.scott.uidemo.R; import com.scott.uidemo.moudle.TestMoudle; import java.util.List; /** * author: scott * Created at scott on 2016/8/9. */ public class MyTestAdapter extends ListViewBaseAdapter{ public MyTestAdapter(List datas, Context context) { super(datas, context); } @Override protected BaseViewHolder onCreateViewHolder(View itemView) { MyHolder holder = new MyHolder(itemView); return holder; } @Override protected void onBindViewHolder(BaseViewHolder vh, int position) { TestMoudle moudle = mDatas.get(position); vh.bindData(moudle); } @Override protected int onInflateItemView(int viewType) { return R.layout.list_test_item; } final class MyHolder extends BaseViewHolder { protected MyHolder(View v) { super(v); } @BindView(R.id.tv_content) TextView tvName; @BindView(R.id.iv_content) ImageView ivName; } }
xml文件
android圖片處理之圖像模糊
這篇文章將給大家介紹android圖片處理的高效做法,大家有需求的時候可以參考一下。首先我要說明一下本實例中實現的效果(我還不會制作gif圖,如果誰會的話,希望可以教一下
手把手教你做視頻播放器(六)(完)
第8節 橫屏的播放界面在設備旋轉成橫屏的時候,視頻將自動進行全屏播放。8.1 播放器橫屏布局我們要為全屏播放界面設置一個新的布局,這個布局裡面只用來播放視頻,不需要顯示任
Android自定義View之圖形圖像工具類Path的特殊用法
概述:沒什麼好說的。Demo新建一個自定義Viewpublic class MyPathView extends View { private int width;
Android--應用開發之所有動畫使用詳解
1 背景不能只分析源碼呀,分析的同時也要整理歸納基礎知識,剛好有人微博私信讓全面說說Android的動畫,所以今天來一發Android應用的各種Animation大集合。