編輯:關於Android編程
大家看到這個標題是不是覺得很詫異呢?什麼叫終極適配器,其實就是這種適配器是萬能的,所有需要使用適配器的組件,都可用這一個適配器就行。
既然這樣,就來講講吧。
效果:
當然這是個簡單的布局,用普通的適配器也可以實現,這裡只是用它來做個例子,用終極適配器的話,以後你換其他布局,適配器是不用變的,減少了很多代碼。
首先普通的適配器的寫法是:<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxwcmUgY2xhc3M9"brush:java;">
public class MyAdapter extends BaseAdapter{
private Context mContext;
private List
制作終極適配器的步驟:
首先我們得分析哪些代碼是不變的,哪些是可變的,這樣才能確定哪些代碼能夠減少。
這三個重寫的方法應該是不變的。
@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;
}
還有這些代碼
ViewHolder holder;
if (convertView == null) {
convertView= mLayoutInflater.inflate(R.layout.myitem, parent, false);
holder = new ViewHolder();
holder.title_Tv = (TextView) convertView.findViewById(R.id.title_Tv);
holder.desc_Tv = (TextView) convertView.findViewById(R.id.desc_Tv);
holder.time_Tv = (TextView) convertView.findViewById(R.id.time_Tv);
holder.phone_Tv = (TextView) convertView.findViewById(R.id.phone_Tv);
convertView.setTag(holder);
}else {
holder = (ViewHolder) convertView.getTag();
}
只不過findViewById我們需要處理一下。所以我們應該把這些不變的代碼抽取出來,不應該讓用戶重復寫這些代碼。
把這些代碼抽取出來,當然這些代碼都應該放在ViewHolder中
ViewHolder holder;
if (convertView == null) {
convertView= mLayoutInflater.inflate(R.layout.myitem, parent, false);
holder = new ViewHolder();
}else {
holder = (ViewHolder) convertView.getTag();
}
新建一個類 ViewHolder.java
public class ViewHolder {
private View mConvertView;
//ViewHolder構造函數,只有當convertView為空的時候才創建
public ViewHolder(Context context,View convertView, ViewGroup parent, int layouId) {
convertView = LayoutInflater.from(context).inflate(layouId,parent,false);
convertView.setTag(this); //將其setTag()
mConvertView = convertView;
}
//返回一個ViewHolder對象
public static ViewHolder getHolder(Context context, View convertView, ViewGroup parent, int layoutId) {
if (convertView == null) {
return new ViewHolder(context,convertView,parent,layoutId);
}else {
return (ViewHolder) convertView.getTag();
}
}
}
傳過來的參數包括:Context context, View convertView, ViewGroup parent, int layoutId,這些參數都是加載布局文件所需要的。
然後就是這些代碼需要抽取了:
holder.title_Tv = (TextView) convertView.findViewById(R.id.title_Tv);
holder.desc_Tv = (TextView) convertView.findViewById(R.id.desc_Tv);
holder.time_Tv = (TextView) convertView.findViewById(R.id.time_Tv);
holder.phone_Tv = (TextView) convertView.findViewById(R.id.phone_Tv);
新建方法:
public class ViewHolder {
//用來存布局中的各個組件,以鍵值對形式
private SparseArray mViews = new SparseArray<>();
//返回一個View的子類對象,因為不確定用戶布局有什麼組件,相當於findViewById
//這裡返回一個泛型,也可以返回一個View或Object
public T getView(int resId) {
View view = mViews.get(resId); //從集合中取出這個組件
if (view == null) { //如果為空,說明為第一屏
view = mConvertView.findViewById(resId); //從convertView中找
mViews.put(resId,view); //再將其以鍵值對存進去
}
return (T) view;
}
}
接下裡的這個返回值就容易了,直接返回就行了
public class ViewHolder {
/**
* @return 返回convertView
*/
public View getConvertView() {
return mConvertView;
}
}
這部分工作都完了,就只留下了為組件設置數據的那段代碼了,這段代碼由於是可變的,應該讓用戶來做,所以設置為抽象方法。
新建一個類 CommonAdapter.java 繼承BaseAdapter:
public abstract class CommonAdapter extends BaseAdapter {
//需要顯示的數據,List中的類型為泛型,因為不知道用戶的封裝Bean
private List mDatas;
//上下文
private Context mContext;
//布局文件Id
private int mLayoutId;
public CommonAdapter(Context context,List data,int layoutId) {
mDatas = data;
mContext = context;
mLayoutId = layoutId;
}
@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 View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = ViewHolder.getHolder(mContext,convertView, parent, mLayoutId);
setDatas(holder,getItem(position));
return holder.getConvertView();
}
/**
* 為各個item中的控件設置數據
* @param holder ViewHolder
* @param object 從集合中所取的一個對象
*/
public abstract void setDatas(ViewHolder holder, Object object);
}
到這裡就把剛才那段代碼全部抽取出來了,那再來看一下如何使用吧。
使用步驟:
①添加ListView, 找ListView 這些步驟是一樣的。
②新建一個 Adapter 繼承 CommonAdapter
public class MagicAdapter extends CommonAdapter {
public MagicAdapter(Context context, List data, int layoutId) {
super(context, data, layoutId);
}
@Override
public void setDatas(ViewHolder holder, Object object) {
Bean bean = (Bean) object;
((TextView)holder.getView(R.id.title_Tv)).setText(bean.getTitle());
((TextView)holder.getView(R.id.desc_Tv)).setText(bean.getDesc());
((TextView)holder.getView(R.id.time_Tv)).setText(bean.getTime());
((TextView)holder.getView(R.id.phone_Tv)).setText(bean.getPhone());
}
}
注:
③為ListView設置適配器
//為listView設置適配器
mListView.setAdapter(new MagicAdapter(this,mDatas,R.layout.listview_item));
到這裡就實現了萬能的適配器了,是不是減少了很多代碼。我們知道java三大特性是封裝、繼承、多態。這篇例子可以鍛煉一下大家的封裝能力。大家試試吧
核心代碼:
activity_main.xml
listview_item.xml
MainActivity.java
public class MainActivity extends AppCompatActivity {
private ListView mListView;
private List mDatas;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initData();
initView();
//為listView設置適配器
mListView.setAdapter(new MagicAdapter(this,mDatas,R.layout.listview_item));
}
/**
* 初始化組件
*/
private void initView() {
mListView = (ListView) findViewById(R.id.listView);
}
/**
* 初始化數據
*/
private void initData() {
mDatas = new ArrayList<>();
//模擬數據
for (int i=0; i < 6; i++) {
Bean bean = new Bean("新技能" +i,"打造萬能適配器"+ i,"2016-5-22","10086");
mDatas.add(bean);
}
}
}
ViewHolder.java
public class ViewHolder {
private View mConvertView;
//用來存布局中的各個組件,以鍵值對形式
private SparseArray mViews = new SparseArray<>();
//ViewHolder構造函數,只有當convertView為空的時候才創建
public ViewHolder(Context context,View convertView, ViewGroup parent, int layouId) {
convertView = LayoutInflater.from(context).inflate(layouId,parent,false);
convertView.setTag(this); //將其setTag()
mConvertView = convertView;
}
//返回一個ViewHolder對象
public static ViewHolder getHolder(Context context, View convertView, ViewGroup parent, int layoutId) {
if (convertView == null) {
return new ViewHolder(context,convertView,parent,layoutId);
}else {
return (ViewHolder) convertView.getTag();
}
}
//返回一個View的子類對象,因為不確定用戶布局有什麼組件,相當於findViewById
//這裡返回一個泛型,也可以返回一個View或Object
public T getView(int resId) {
View view = mViews.get(resId); //從集合中取出這個組件
if (view == null) { //如果為空,說明為第一屏
view = mConvertView.findViewById(resId); //從convertView中找
mViews.put(resId,view); //再將其以鍵值對存進去
}
return (T) view;
}
/**
* @return 返回convertView
*/
public View getConvertView() {
return mConvertView;
}
}
CommonAdapter.java
public abstract class CommonAdapter extends BaseAdapter {
//需要顯示的數據,List中的類型為泛型,因為不知道用戶的封裝Bean
private List mDatas;
//上下文
private Context mContext;
//布局文件Id
private int mLayoutId;
public CommonAdapter(Context context,List data,int layoutId) {
mDatas = data;
mContext = context;
mLayoutId = layoutId;
}
@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 View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = ViewHolder.getHolder(mContext,convertView, parent, mLayoutId);
setDatas(holder,getItem(position));
return holder.getConvertView();
}
/**
* 為各個item中的控件設置數據
* @param holder ViewHolder
* @param object 從集合中所取的一個對象
*/
public abstract void setDatas(ViewHolder holder, Object object);
}
Bean.java
public class Bean {
private String title; //標題
private String desc; //簡介
private String time; //時間
private String phone; //電話
public Bean(String title, String desc, String time, String phone) {
this.title = title;
this.desc = desc;
this.time = time;
this.phone = phone;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
public String getTime() {
return time;
}
public void setTime(String time) {
this.time = time;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
}
MagicAdapter.java
public class MagicAdapter extends CommonAdapter {
public MagicAdapter(Context context, List data, int layoutId) {
super(context, data, layoutId);
}
@Override
public void setDatas(ViewHolder holder, Object object) {
Bean bean = (Bean) object;
((TextView)holder.getView(R.id.title_Tv)).setText(bean.getTitle());
((TextView)holder.getView(R.id.desc_Tv)).setText(bean.getDesc());
((TextView)holder.getView(R.id.time_Tv)).setText(bean.getTime());
((TextView)holder.getView(R.id.phone_Tv)).setText(bean.getPhone());
}
}
1 背景Android系統提供了很多豐富的API去實現UI的2D與3D動畫,最主要的劃分可以分為如下幾類:View Animation: 視圖動畫在古老的Android版
android檢查更新、下載、安裝前言:由於友盟更新即將下線,我們就修改了更新邏輯,自己檢查更新、下載、安裝,但是檢查更新還是要依賴於友盟中的在線參數:1.MainAct
一 、 虛擬機的安裝常見的虛擬機產品有 VMware 公司的 VMware Workstation、Oracle 公司的 VirtualBox。因為 VMware 體積相
Android是一種基於Linux的自由及開放源代碼的操作系統,主要使用於移動設備,如智能手機和平板電腦,由Google公司和開放手機聯盟領導及開發,從語言上來看,And