標籤:
做項目中遇到的,折磨了我將近兩天,今天把經驗分享出來,讓大家以後少走點彎路,好了,簡單來說一下什麼是android的適配器,如何定義,如何增加適配器的重用性,如何去降低程式的耦合性
適配器顧名思義是用來做適配的,但是他是如何做適配的,機制是什麼,作用是什麼,好,相信寫java的都是知道什麼是物件導向編程吧,這裡用物件導向來解釋很好理解,其實適配器是把每個對象放在其空間上然後在andorid頁面顯示,現在再來理解,對象其實就是資料的抽象體吧,而頁面顯示一般是xml也就是視圖吧,那麼資料以視圖的形式來顯示,那麼這就是adapter起的作用,而且他可以讓其按照相應的順序顯示,可以根據相應的操作來進行資料或者頁面的操作,那麼來看一下我的適配器,上代碼
這個是bean實體
package com.example.fanyafeng.laugh.bean;import com.example.fanyafeng.laugh.util.S;/** * Created by fanyafeng on 2015/6/30. */public class IndexListViewBean extends BaseBean { private String Title; private String LeftTopImg; private String LeftTopTitle; private String LeftTopTimes; private String LeftTopUrl; private String RightTopImg; private String RightTopTitle; private String RightTopTimes; private String RightTopUrl; private String LeftBottomImg; private String LeftBottomTitle; private String LeftBottomTimes; private String LeftBottonUrl; private String RightBottomImg; private String RightBottomTitle; private String RightBottomTimes; private String RightBottonUrl; public IndexListViewBean(String title, String leftTopImg, String leftTopTitle, String leftTopTimes, String leftTopUrl, String rightTopImg, String rightTopTitle, String rightTopTimes, String rightTopUrl, String leftBottomImg, String leftBottomTitle, String leftBottomTimes, String leftBottonUrl, String rightBottomImg, String rightBottomTitle, String rightBottomTimes, String rightBottonUrl) { Title = title; LeftTopImg = leftTopImg; LeftTopTitle = leftTopTitle; LeftTopTimes = leftTopTimes; LeftTopUrl = leftTopUrl; RightTopImg = rightTopImg; RightTopTitle = rightTopTitle; RightTopTimes = rightTopTimes; RightTopUrl = rightTopUrl; LeftBottomImg = leftBottomImg; LeftBottomTitle = leftBottomTitle; LeftBottomTimes = leftBottomTimes; LeftBottonUrl = leftBottonUrl; RightBottomImg = rightBottomImg; RightBottomTitle = rightBottomTitle; RightBottomTimes = rightBottomTimes; RightBottonUrl = rightBottonUrl; } public String getTitle() { return Title; } public void setTitle(String title) { Title = title; } public String getLeftTopImg() { return LeftTopImg; } public void setLeftTopImg(String leftTopImg) { LeftTopImg = leftTopImg; } public String getLeftTopTitle() { return LeftTopTitle; } public void setLeftTopTitle(String leftTopTitle) { LeftTopTitle = leftTopTitle; } public String getLeftTopTimes() { return LeftTopTimes; } public void setLeftTopTimes(String leftTopTimes) { LeftTopTimes = leftTopTimes; } public String getLeftTopUrl() { return LeftTopUrl; } public void setLeftTopUrl(String leftTopUrl) { LeftTopUrl = leftTopUrl; } public String getRightTopImg() { return RightTopImg; } public void setRightTopImg(String rightTopImg) { RightTopImg = rightTopImg; } public String getRightTopTitle() { return RightTopTitle; } public void setRightTopTitle(String rightTopTitle) { RightTopTitle = rightTopTitle; } public String getRightTopTimes() { return RightTopTimes; } public void setRightTopTimes(String rightTopTimes) { RightTopTimes = rightTopTimes; } public String getRightTopUrl() { return RightTopUrl; } public void setRightTopUrl(String rightTopUrl) { RightTopUrl = rightTopUrl; } public String getLeftBottomImg() { return LeftBottomImg; } public void setLeftBottomImg(String leftBottomImg) { LeftBottomImg = leftBottomImg; } public String getLeftBottomTitle() { return LeftBottomTitle; } public void setLeftBottomTitle(String leftBottomTitle) { LeftBottomTitle = leftBottomTitle; } public String getLeftBottomTimes() { return LeftBottomTimes; } public void setLeftBottomTimes(String leftBottomTimes) { LeftBottomTimes = leftBottomTimes; } public String getLeftBottonUrl() { return LeftBottonUrl; } public void setLeftBottonUrl(String leftBottonUrl) { LeftBottonUrl = leftBottonUrl; } public String getRightBottomImg() { return RightBottomImg; } public void setRightBottomImg(String rightBottomImg) { RightBottomImg = rightBottomImg; } public String getRightBottomTitle() { return RightBottomTitle; } public void setRightBottomTitle(String rightBottomTitle) { RightBottomTitle = rightBottomTitle; } public String getRightBottomTimes() { return RightBottomTimes; } public void setRightBottomTimes(String rightBottomTimes) { RightBottomTimes = rightBottomTimes; } public String getRightBottonUrl() { return RightBottonUrl; } public void setRightBottonUrl(String rightBottonUrl) { RightBottonUrl = rightBottonUrl; } @Override public String toString() { return "IndexListViewBean{" + "Title='" + Title + '\'' + ", LeftTopImg='" + LeftTopImg + '\'' + ", LeftTopTitle='" + LeftTopTitle + '\'' + ", LeftTopTimes='" + LeftTopTimes + '\'' + ", LeftTopUrl='" + LeftTopUrl + '\'' + ", RightTopImg='" + RightTopImg + '\'' + ", RightTopTitle='" + RightTopTitle + '\'' + ", RightTopTimes='" + RightTopTimes + '\'' + ", RightTopUrl='" + RightTopUrl + '\'' + ", LeftBottomImg='" + LeftBottomImg + '\'' + ", LeftBottomTitle='" + LeftBottomTitle + '\'' + ", LeftBottomTimes='" + LeftBottomTimes + '\'' + ", LeftBottonUrl='" + LeftBottonUrl + '\'' + ", RightBottomImg='" + RightBottomImg + '\'' + ", RightBottomTitle='" + RightBottomTitle + '\'' + ", RightBottomTimes='" + RightBottomTimes + '\'' + ", RightBottonUrl='" + RightBottonUrl + '\'' + '}'; }}
這個是適配器
package com.example.fanyafeng.laugh.adapter;import android.app.Activity;import android.content.Context;import android.content.Intent;import android.graphics.Bitmap;import android.graphics.drawable.Drawable;import android.net.Uri;import android.support.v4.util.LruCache;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.Button;import android.widget.ImageView;import android.widget.ListView;import android.widget.TextView;import android.widget.Toast;import com.example.fanyafeng.laugh.R;import com.example.fanyafeng.laugh.activity.VideoDisplayActivity;import com.example.fanyafeng.laugh.activity.VideoListActivity;import com.example.fanyafeng.laugh.activity.VideoViewPlayingActivity;import com.example.fanyafeng.laugh.bean.IndexListViewBean;import com.example.fanyafeng.laugh.bean.IndexUrlBean;import com.example.fanyafeng.laugh.util.ImageLoaderCache;import com.example.fanyafeng.laugh.util.L;import com.example.fanyafeng.laugh.util.ListViewImageTaskUtil;import com.example.fanyafeng.laugh.util.StringTools;import com.example.fanyafeng.laugh.util.SyncImageLoader;import java.util.List;/** * Created by fanyafeng on 2015/7/1. */public class IndexListViewAdapter extends BaseAdapter { private Context context; private List<IndexListViewBean> indexListViewBeans; private ListView listView; //緩衝到本地sd卡,並且可以更新ListView圖片 private ImageLoaderCache mImageLoader; // 擷取當前應用程式所分配的最大記憶體 private final int maxMemory = (int) Runtime.getRuntime().maxMemory(); // 只用五分之一用來做圖片緩衝 private final int cacheSize = maxMemory / 5; private LruCache<String, Bitmap> mLruCache = new LruCache<String, Bitmap>( cacheSize) { // 重寫sizeof()方法 @Override protected int sizeOf(String key, Bitmap bitmap) { // TODO Auto-generated method stub // 這裡用多少kb來計算 return bitmap.getRowBytes() * bitmap.getHeight() / 1024; } }; public IndexListViewAdapter(Context context, List<IndexListViewBean> indexListViewBeans) { this.context = context; this.indexListViewBeans = indexListViewBeans; mImageLoader = new ImageLoaderCache(context); } public ImageLoaderCache getImagerLoader() { return mImageLoader; } public void update() { notifyDataSetChanged(); } @Override public int getCount() { return indexListViewBeans.size(); } @Override public Object getItem(int position) { return indexListViewBeans.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(final int position, View convertView, final ViewGroup parent) { View view = convertView; ViewHolder holder = null; if (view == null) { view = LayoutInflater.from(context).inflate(R.layout.item_fragment_homepage, null); holder = new ViewHolder(); view.setTag(holder); holder.Title = (TextView) view.findViewById(R.id.index_title); holder.LeftTopImg = (ImageView) view.findViewById(R.id.index_left_up_iv); holder.LeftTopTitle = (TextView) view.findViewById(R.id.index_left_up_tv); holder.LeftTopTimes = (TextView) view.findViewById(R.id.index_left_up_time); holder.RightTopImg = (ImageView) view.findViewById(R.id.index_right_up_iv); holder.RightTopTitle = (TextView) view.findViewById(R.id.index_right_up_tv); holder.RightTopTimes = (TextView) view.findViewById(R.id.index_right_up_time); holder.LeftBottomImg = (ImageView) view.findViewById(R.id.index_left_down_iv); holder.LeftBottomTitle = (TextView) view.findViewById(R.id.index_left_down_tv); holder.LeftBottomTimes = (TextView) view.findViewById(R.id.index_left_down_time); holder.RightBottomImg = (ImageView) view.findViewById(R.id.index_right_down_iv); holder.RightBottomTitle = (TextView) view.findViewById(R.id.index_right_down_tv); holder.RightBottomTimes = (TextView) view.findViewById(R.id.index_right_down_time); } else { holder = (ViewHolder) view.getTag(); } holder.LeftTopImg.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(Intent.ACTION_CALL); intent.setClass(context, VideoViewPlayingActivity.class); intent.putExtra("url_info", indexListViewBeans.get(position).getLeftTopUrl()); L.d("leftTopUrl", indexListViewBeans.get(position).getLeftTopUrl()); L.d("點擊擷取的位置", position); context.startActivity(intent); } }); holder.RightTopImg.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(Intent.ACTION_CALL); intent.setClass(context, VideoViewPlayingActivity.class); intent.putExtra("url_info", indexListViewBeans.get(position).getRightTopUrl()); context.startActivity(intent); } }); holder.LeftBottomImg.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(Intent.ACTION_CALL); intent.setClass(context, VideoViewPlayingActivity.class); intent.putExtra("url_info", indexListViewBeans.get(position).getLeftBottonUrl()); context.startActivity(intent); } }); holder.RightBottomImg.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(Intent.ACTION_CALL); intent.setClass(context, VideoViewPlayingActivity.class); intent.putExtra("url_info", indexListViewBeans.get(position).getRightBottonUrl()); context.startActivity(intent); } }); holder.Title.setText(indexListViewBeans.get(position).getTitle()); holder.LeftTopTitle.setText(indexListViewBeans.get(position).getLeftTopTitle()); holder.LeftTopTimes.setText(indexListViewBeans.get(position).getLeftTopTimes()); holder.RightTopTitle.setText(indexListViewBeans.get(position).getRightTopTitle()); holder.RightTopTimes.setText(indexListViewBeans.get(position).getRightTopTimes()); holder.LeftBottomTitle.setText(indexListViewBeans.get(position).getLeftBottomTitle()); holder.LeftBottomTimes.setText(indexListViewBeans.get(position).getLeftBottomTimes()); holder.RightBottomTitle.setText(indexListViewBeans.get(position).getRightBottomTitle()); holder.RightBottomTimes.setText(indexListViewBeans.get(position).getRightBottomTimes()); loadBitmap(indexListViewBeans.get(position).getLeftTopImg(), holder.LeftTopImg); loadBitmap(indexListViewBeans.get(position).getRightTopImg(), holder.RightTopImg); loadBitmap(indexListViewBeans.get(position).getLeftBottomImg(), holder.LeftBottomImg); loadBitmap(indexListViewBeans.get(position).getRightBottomImg(), holder.RightBottomImg); return view; } private void loadBitmap(String urlStr, ImageView image) { ListViewImageTaskUtil asyncLoader = new ListViewImageTaskUtil(image, mLruCache);// 一個非同步圖片載入對象 Bitmap bitmap = asyncLoader.getBitmapFromMemoryCache(urlStr);// 首先從記憶體緩衝中擷取圖片 if (bitmap != null) { image.setImageBitmap(bitmap);// 如果緩衝中存在這張圖片則直接設定給ImageView } else { image.setImageResource(R.drawable.wait);// 否則先設定成預設的圖片 asyncLoader.execute(urlStr);// 然後執行非同步任務AsycnTask 去網上載入圖片 } } static class ViewHolder { TextView Title; ImageView LeftTopImg; TextView LeftTopTitle; TextView LeftTopTimes; ImageView RightTopImg; TextView RightTopTitle; TextView RightTopTimes; ImageView LeftBottomImg; TextView LeftBottomTitle; TextView LeftBottomTimes; ImageView RightBottomImg; TextView RightBottomTitle; TextView RightBottomTimes; }}重點在實體的書寫和適配器的書寫,那麼現在我實體的定義不僅僅是用來去用資料來映射視圖,還有一個很重要的是在對象上set資料,單個的item再去取,原來博主沒有將每個對象裡面的四個連結對應的bean實體中,而是用的全域變數(把activity或者fragment和adapter寫在一起,這樣寫不好,至於為什麼我這裡簡單會所一下,具體的大家去體會,首先就是代碼會很亂,再有就是adapter的複用,還有就是全域變數多的話一個是不好維護一個是效率會低,剩下的真得自己去理解了)的list資料,想根據getview中的position去找對應的連結,但是通過抓position我發現,他不和onitemonclick(這裡面的position是依次累加的,而且是唯一的)裡的position一樣,這裡面我設定的是每次載入三個,然後上拉載入更多再載入三個,這樣的話,我列印出來的position是0到2的一直的死迴圈,這樣問題就來了,得到的相應的連結肯定不對,因為是按照getview的position來擷取的,那麼,咱再向深層次想一下,android的getview的機制是什麼,為什麼listview控制項上的資料的對應關係並沒有錯,也沒有亂,這個就涉及到面試官經常問的面試題了,有的會問listview如何最佳化,看的一些資料說是settag,對,這是,而且是一般網路上的答案(但是這個我感覺回答最佳化不是很好,是在adapter如何進行處理事務,怎麼去處理,這個方向才應該是對的),但是這個settag恰恰是我們的問題所在,因為Google給的listview是如果這個view划出螢幕以後,那麼Google會給你處理,這個存在的view如果再劃回來,出現在螢幕上,那麼這時候settag開始起作用了,換句話說就是if那,開始執行else了。
博主處理的時候剛開始用了一個全域的list,但是這樣一個是不好,另一個沒有達到要的效果,然後博主又開始想另一個方法就是java的物件導向裡面設定bean,好,原來博主是在adapter又定義了全域的變數,在if else之外擷取,但是onclickerlistener在if else之內,這樣的話,相當遠博主上文說道的那個,執行那個的問題,這樣的話進行螢幕的滑動和重新整理裡面的全域的資料肯定會亂,一定會亂,這時候,再往深層次去挖,就到了上面說的那個了,就是要在綁定資料那裡去進行事件的監聽,並且去擷取相應的資料,這樣的話就可以得到想要的效果,而且view的顯示也都是這麼做的,沒有亂
這裡說一下adapter是如何將資料對應到xml,一般的話都是先去寫一個holder,裡面都是item的xml所需要的東西,然後再在這裡面去找layout,然後再去找相應的id,然後再去和holder裡面去對應(對應bean裡面定義的,一般是需要進行頁面顯示的,而資料的後台操作是不用去對應相應的布局id), 還有這裡著重強調一下adapter裡面的一些坑
getview的position是固定的幾個值,相對的,不要去當全域變數去使用
注意adapter開啟一個activity等等
監聽事件不要去寫在ifelse結構體裡面,事件處理也是一樣,放在外面單獨處理
注意耦合,否則代碼會亂,按照道理說程式員的邏輯思維應該是很清晰的,總有一條思路能夠讓你去進行解耦,但是哪一條好,而且適合你的處理方式方法,這一點就需要程式員的經驗了,剩下的靠大家去體驗了,這裡只是淺析
著作權聲明:本文為博主原創文章,未經博主允許不得轉載。
淺析android適配器adapter中的那些坑