編輯:關於Android編程
適配器模式的應用:
1.降低程序耦合性
2.容易擴展
BaseAdapter
ListView的顯示與緩存機制:需要才顯示,顯示完就被會受到緩存。
BaseAdapter基本結構
--public int getCount(); 適配器中數據集中數據的個數
--public Object getItem(int position):獲取數據集中與指定索引對應的數據項
--public long getItem(int position):獲取指定行對應的ID
--public View getView(int position, ViewconverView, ViewGroup parent):獲取每一個Item的顯示內容
第一步: 創建布局文件 activity_main.xml 創建好了一個簡單的listView
創建item布局文件item.xml,其中有一個ImageView 兩個 TextView
activity_main.xml
item.xml
效果如圖:
第二步:創建一個Bean對象ItemBean,封裝item中顯示的內容,在主頁面MainActivity.java裡面創建數據源
ItemBean.java
public class ItemBean { public int ItemImageResid; public String Itemtitle; public String ItemContent; public ItemBean(int itemImageResid, String itemtitle, String itemContent) { super(); ItemImageResid = itemImageResid; Itemtitle = itemtitle; ItemContent = itemContent; } }
MainActivity.java
package com.example.sr; import java.util.ArrayList; import java.util.List; import android.os.Bundle; import android.app.Activity; import android.view.Menu; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ListitemBeanList = new ArrayList (); for(int i = 0; i < 20; i++){ itemBeanList.add(new ItemBean(R.drawable.ic_launcher, "我是標題"+i, "我是內容"+i)); } } }
第三步:新建MyAdapter類,繼承自BaseAdapter , 重寫裡面的方法,實現適配器
MyAdapter.java
package com.example.sr; import java.util.List; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; public class MyAdapter extends BaseAdapter { private ListmList; public MyAdapter(List list){ //數據源與適配器進行了關聯 mList = list; } @Override public int getCount() { //返回ListView需要顯示的數據量 // TODO Auto-generated method stub return mList.size(); } @Override public Object getItem(int position) {//獲取數據集中與指定索引對應的數據項 // TODO Auto-generated method stub return mList.get(position); } @Override public long getItemId(int position) {//獲取指定行對應的ID // TODO Auto-generated method stub return position; } @Override public View getView(int arg0, View arg1, ViewGroup arg2) {//返回每一項的顯示內容 // TODO Auto-generated method stub return null; } }
1.逗比式
MyAdapter.java
package com.example.sr; import java.util.List; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.TextView; public class MyAdapter extends BaseAdapter { private ListmList; private LayoutInflater minflater;//布局裝載器對象,用於把xml布局文件轉化為view public MyAdapter(Context context, List list){ //數據源與適配器進行了關聯 mList = list; minflater = LayoutInflater.from(context);//context要使用當前的Adapter的界面對象 } @Override public int getCount() { //返回ListView需要顯示的數據量 // TODO Auto-generated method stub return mList.size(); } @Override public Object getItem(int position) {//獲取數據集中與指定索引對應的數據項 // TODO Auto-generated method stub return mList.get(position); } @Override public long getItemId(int position) {//獲取指定行對應的ID // TODO Auto-generated method stub return position; } @Override public View getView(int postion, View convertView, ViewGroup parent) {//返回每一項的顯示內容 // TODO Auto-generated method stub View view = minflater.inflate(R.layout.item, null); //第一個參數為 需要裝載到item.xml布局文件,第二個參數通常寫null ImageView imageView = (ImageView) view.findViewById(R.id.iv_image); TextView title = (TextView)view.findViewById(R.id.tv_title); TextView content = (TextView)view.findViewById(R.id.tv_content); //將數據取出來賦給這三個控件 ItemBean bean = mList.get(postion); imageView.setImageResource(bean.ItemImageResid); title.setText(bean.Itemtitle); content.setText(bean.ItemContent); return view; } }
回到MainActivity.java 建立listView與MyAdapter的聯系
MainActivity.java
package com.example.sr; import java.util.ArrayList; import java.util.List; import android.os.Bundle; import android.app.Activity; import android.view.Menu; import android.widget.ListView; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ListitemBeanList = new ArrayList (); for(int i = 0; i < 20; i++){ itemBeanList.add(new ItemBean(R.drawable.ic_launcher, "我是標題"+i, "我是內容"+i)); } //建立listView與MyAdapter的聯系 ListView listView = (ListView) findViewById(R.id.lv_main); listView.setAdapter(new MyAdapter(this, itemBeanList));//第一個參數為context,第二個是數據源 } }
至此,運行程序,發現listView可以顯示我們想要的東西了。
為什麼式逗比式呢?listView有緩沖機制,但是在getView無視了緩沖機制,都通過創建一個新的view去設置空間,效率及其低下,完全沒有利用到listView的緩存機制。
2. 普通式
修改getView方法
@Override public View getView(int postion, View convertView, ViewGroup parent) {//返回每一項的顯示內容 // TODO Auto-generated method stub //逗比式開始---------- //View view = minflater.inflate(R.layout.item, null); //第一個參數為 需要裝載到item.xml布局文件,第二個參數通常寫null /* ImageView imageView = (ImageView) view.findViewById(R.id.iv_image); TextView title = (TextView)view.findViewById(R.id.tv_title); TextView content = (TextView)view.findViewById(R.id.tv_content); //將數據取出來賦給這三個控件 ItemBean bean = mList.get(postion); imageView.setImageResource(bean.ItemImageResid); title.setText(bean.Itemtitle); content.setText(bean.ItemContent); */ //逗比式結束----------- //普通式,參數中已經有了一個converView,考慮是否緩存過了,如果緩存過了,可以直接使用 if(convertView == null){ convertView = minflater.inflate(R.layout.item, null); } ImageView imageView = (ImageView) convertView.findViewById(R.id.iv_image); TextView title = (TextView)convertView.findViewById(R.id.tv_title); TextView content = (TextView)convertView.findViewById(R.id.tv_content); ItemBean bean = mList.get(postion); imageView.setImageResource(bean.ItemImageResid); title.setText(bean.Itemtitle); content.setText(bean.ItemContent); return convertView; }
利用了ListView的緩存特性,如果沒有緩存才創建新的View,算入門,但是findViewById依然會浪費大量時間
3. 文藝式(最好的)
創建了一個內部類 ViewHolder ,它與view相關聯,並緩存item的組件,這樣給item設置內容的時候,不用再去findviewById, 直接在ViewHolder裡面取出來就行了。
@Override public View getView(int postion, View convertView, ViewGroup parent) {//返回每一項的顯示內容 // TODO Auto-generated method stub //逗比式開始---------- //View view = minflater.inflate(R.layout.item, null); //第一個參數為 需要裝載到item.xml布局文件,第二個參數通常寫null /* ImageView imageView = (ImageView) view.findViewById(R.id.iv_image); TextView title = (TextView)view.findViewById(R.id.tv_title); TextView content = (TextView)view.findViewById(R.id.tv_content); //將數據取出來賦給這三個控件 ItemBean bean = mList.get(postion); imageView.setImageResource(bean.ItemImageResid); title.setText(bean.Itemtitle); content.setText(bean.ItemContent); */ //逗比式結束----------- //普通式,參數中已經有了一個converView,考慮是否緩存過了,如果緩存過了,可以直接使用--------- /* if(convertView == null){ convertView = minflater.inflate(R.layout.item, null); } ImageView imageView = (ImageView) convertView.findViewById(R.id.iv_image); TextView title = (TextView)convertView.findViewById(R.id.tv_title); TextView content = (TextView)convertView.findViewById(R.id.tv_content); ItemBean bean = mList.get(postion); imageView.setImageResource(bean.ItemImageResid); title.setText(bean.Itemtitle); content.setText(bean.ItemContent); return convertView; */ //普通式結束----------------- ViewHolder viewHolder; if(convertView == null){ viewHolder = new ViewHolder(); convertView = minflater.inflate(R.layout.item, null); viewHolder.imageView = (ImageView) convertView.findViewById(R.id.iv_image);//把控件保存在ViewHolder中 viewHolder.title = (TextView)convertView.findViewById(R.id.tv_title); viewHolder.content = (TextView)convertView.findViewById(R.id.tv_content); convertView.setTag(viewHolder);//進行關聯,把它的控件保存在viewHolder中,避免了findviewbyid去實例化 }else{ viewHolder = (ViewHolder)convertView.getTag(); } ItemBean bean = mList.get(postion); viewHolder.imageView.setImageResource(bean.ItemImageResid); viewHolder.title.setText(bean.Itemtitle); viewHolder.content.setText(bean.ItemContent); return convertView; } class ViewHolder{ //首先創建內部類 public ImageView imageView; public TextView title; public TextView content; }
不僅利用了ListView的緩存,更通過ViewHolder類來實現顯示數據的視圖的緩存,避免多次通過findViewById尋找控件,這是最好的方法。
總結:
ViewHolder優化BaseAdapter的思路
--創建Bean對象,用於封裝數據
--創建MyAdapter(繼承BaseAdapter)在構造方法中初始化用於映射的數據List
--創建ViewHolder類,創建布局映射關系
--判斷ConverView,為空則創建,並設置Tag,否則通過tag來取出ViewHolder
--給ViewHolder中的控件設置數據
前一遍文章我們講了靜態創建Fragment,這個在實際的開發中幾乎不用,都是動態創建的,所謂動態創建就是根據某個條件動態創建Fragment, 現在創建一個android
先上幾張自定義所實現的效果圖吧,有興趣的可以繼續往下看 實現思路,前四張圖呢在自定義progressbar時沒有加入text文本,文本是在xml布局時加
先占個位置,過會兒來翻譯,:p DEMO下載地址:http://download.csdn.net/detail/sweetvvck/7728735 Unlike
RatingBar簡單介紹RatingBar是基於SeekBar(拖動條)和ProgressBar(狀態條)的擴展,用星形來顯示等級評定,在使用默認RatingBar時,