編輯:關於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圖片處理的高效做法,大家有需求的時候可以參考一下。首先我要說明一下本實例中實現的效果(我還不會制作gif圖,如果誰會的話,希望可以教一下
第8節 橫屏的播放界面在設備旋轉成橫屏的時候,視頻將自動進行全屏播放。8.1 播放器橫屏布局我們要為全屏播放界面設置一個新的布局,這個布局裡面只用來播放視頻,不需要顯示任
概述:沒什麼好說的。Demo新建一個自定義Viewpublic class MyPathView extends View { private int width;
1 背景不能只分析源碼呀,分析的同時也要整理歸納基礎知識,剛好有人微博私信讓全面說說Android的動畫,所以今天來一發Android應用的各種Animation大集合。