日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

Android中Adapter之BaseAdapter使用

 Go_Ahead 2012-11-20
       Android界面中有時(shí)候需要顯示稍微復(fù)雜的界面時(shí),就需要我們自定義一個(gè)adapter,而此adapter就要繼承BaseAdapter,重新其中的方法.
        Android中Adapter類其實(shí)就是把數(shù)據(jù)源綁定到指定的View上,然后再返回該View,而返回來的這個(gè)View就是ListView中的某一行item。這里返回來的View正是由我們的Adapter中的getView方法返回的。這樣就會(huì)容易理解數(shù)據(jù)是怎樣一條一條顯示在ListView中的。
       在完成這篇文章中的例子之后,我思考了很長時(shí)間,關(guān)于重寫一個(gè)adapter,這其中真的有很多講究,遇到一處不懂的都會(huì)查閱很長時(shí)間,但也不能保證我已經(jīng)把其中的重中之重已經(jīng)找完了,只要你想延伸都可以發(fā)現(xiàn)其中的無限.....
       問題1:為什么我們要重寫一個(gè)adapter?
       問題2:android中這么多adapter,什么情況下該重寫哪一個(gè)adapter(ArrayAdapter/SimpleAdapter/SimpleCursorAdapter...)?
       問題3:我們重寫的adapter為什么是一個(gè)內(nèi)部類,是否建議把a(bǔ)dapter做成一個(gè)內(nèi)部類?
       問題4:理解應(yīng)用中的數(shù)據(jù)源一般都會(huì)用一個(gè)Map類型的List,有何意途?
       問題5:通過adapter是怎樣做到把一條一條的item放到ListView中的?
       問題6:理解重寫adapter時(shí),重寫的幾個(gè)方法(getCount()/getItem()/getItemId()/getView())?
       問題7:理解ListView使用adapter的機(jī)制
      
 
案例概覽步驟:
1)創(chuàng)建2個(gè)layout,一個(gè)是界面頂部的顯示,一個(gè)是ListView中的內(nèi)容
   1.1)ListView_header.xml(注:自我感覺界面中的控件的位置擺放與layout_width/layout_height/orientation/gravity/layout_gravity的屬性設(shè)置關(guān)系非常大,一定要注意每個(gè)屬性的用法)
 
<?xml version="1.0" encoding="UTF-8"?>
<!-- 第一個(gè)LinearLayout,充當(dāng)父容器,要包攬兩行,因此設(shè)置其 android:orientation為    縱向-->
<LinearLayout xmlns:android="http://schemas./apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"

    android:orientation="vertical">
   
    <!-- 第二個(gè)LinearLayout
    android:gravity 表示該LinearLayout中的類容相對(duì)于該LinearLayout 水平居中
    android:layout_gravity 表示的是該LinearLayout相對(duì)于它上面的父容器(這里是第一個(gè)LinearLayout)水平居中
    -->

    <LinearLayout android:id="@+id/toprow"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:gravity="center_horizontal">
       
     <TextView android:id="@+id/quna"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:textColor="#ff9966ff"
         android:textSize="25dp"
         android:text="@string/places"/>
    
     <!-- 用一個(gè)圖片按鈕 -->
     <ImageButton android:id="@+id/goBtn"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:src="@drawable/quna"/>
    </LinearLayout>
   
    <TextView android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:text="@string/placesList"
         android:textColor="#ff9966ff"
         android:textSize="20dp"/>
   
    <ListView android:id="@+id/list_places"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"/>
   
</LinearLayout>
 
1.2)listview_item.xml
 
<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout xmlns:android="http://schemas./apk/res/android"
    android:orientation="horizontal" //此屬性的設(shè)置非常重要,決定里面的控件橫向擺放
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <!-- android:layout_margin設(shè)置圖片與旁邊文章的距離 -->
    <ImageView android:id="@+id/image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="5dp"/>
    <LinearLayout android:orientation="vertical" //也很重要決定里面的兩個(gè)textview豎著放
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">
        <TextView android:id="@+id/title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="#ff3399ff"
            android:textSize="20dp"/>
        <TextView android:id="@+id/info"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="#ff3399ff"
            android:textSize="13dp"/>
    </LinearLayout>
    <!-- 注意此處button的屬性android:layout_gravity的用法 ,這里設(shè)置了都沒效果
    這里不是很理解為什么要在加一個(gè)LinearLayout,里面的button才可以居右??
    而且LinearLayout的width必須為fill_parent才可以
    -->

    <LinearLayout android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        >
    <Button android:id="@+id/viewBtn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/btn_select"
        android:layout_gravity="bottom|right"/>
   
    </LinearLayout>
</LinearLayout>
 
2)、寫java class,開發(fā)activity(建一個(gè)class繼承Activity,添加click事件的時(shí)候還要實(shí)現(xiàn)onClickListener接口)
       2.1)  重寫onCreate方法----------------------------------------------->
 
         private ListView listView;
         private ImageButton goBtn;
         private List<Map<String, Object>> testData;
      protected void onCreate(Bundle savedInstanceState) {
                      super.onCreate(savedInstanceState);
                      setContentView(R.layout.listview_header);//這里運(yùn)行該項(xiàng)目的時(shí)候,讓其顯示listview_header.xml界面(layout),然后再將listview要顯示的item項(xiàng)加到里面
                      //獲得listview_header.xml中的ListView控件
                      listView = (ListView) findViewById(R.id.list_places);
                      //獲得imageButton給它添加click事件
                      goBtn = (ImageButton) findViewById(R.id.goBtn);
                      goBtn.setOnClickListener(new OnClickListener() {
                                 //這里只是做出了簡單的彈出框
                                @Override
                                 public void onClick(View v) {
                                            new AlertDialog.Builder(BaseAdapterTest2.this).setTitle("想去的國家:")
                                                                                  .setMessage("i want to go France")
                                                                                  .setPositiveButton("確定", null).sho();
                                  }
                                 });
  
                     //數(shù)據(jù)源
                     testData = buildData();
                     MyAdapter adapter = new MyAdapter(this);
                     //通過setAdapter而把數(shù)據(jù)綁定到ListView中
                     listView.setAdapter(adapter); 
           }
 
      2.2)創(chuàng)建數(shù)據(jù),注意這里為什么要是Map類型的List集合
            private List<Map<String, Object>> buildData(){
                        List<Map<String, Object>> data = new ArrayList<Map<String,Object>>();
                        Map<String, Object> map = new HashMap<String, Object>();
                        map.put("title", "中國");
                       map.put("info", "China");
                       map.put("image", R.drawable.p6);
                       data.add(map);
  
                       map = new HashMap<String, Object>();
                       map.put("title", "英國");
                       map.put("info", "England");
                       map.put("image", R.drawable.p7);
                       data.add(map);
  
                       map = new HashMap<String, Object>();
                       map.put("title", "美國");
                       map.put("info", "America");
                       map.put("image", R.drawable.p9);
  
                        map = new HashMap<String, Object>();
                        map.put("title", "荷蘭");
                        map.put("info", "Dutch");
                        map.put("image", R.drawable.p9);
                       data.add(map);
  
                       map = new HashMap<String, Object>();
                       map.put("title", "新西蘭");
                       map.put("info", "New Zealand");
                       map.put("image", R.drawable.p7);
                       data.add(map);
 
                       data.add(map);
  
                       return data;
           }
 
         2.3)寫自定義adapter(它是一個(gè)內(nèi)部類,繼承自BaseAdapter,并不確定是否自定義的adapter一般都是繼承它),尤其注意其中的幾個(gè)方法
           public class MyAdapter extends BaseAdapter{
                       private LayoutInflater inflater;//這個(gè)一定要懂它的用法及作用
  
                      //構(gòu)造函數(shù):要理解(這里構(gòu)造方法的意義非常強(qiáng)大,你也可以傳一個(gè)數(shù)據(jù)集合的參數(shù),可以根據(jù)需要來傳參數(shù))
                      public MyAdapter(Context context){
                                 this.inflater = LayoutInflater.from(context);
                      }
  
                     //這里的getCount方法是程序在加載顯示到ui上時(shí)就要先讀取的,這里獲得的值決定了listview顯示多少行
                     @Override
                     public int getCount() {
                               //在實(shí)際應(yīng)用中,此處的返回值是由從數(shù)據(jù)庫中查詢出來的數(shù)據(jù)的總條數(shù)
                               return testData.size();
                     }
                    
                     //根據(jù)ListView所在位置返回View
                    @Override
                     public Object getItem(int position) {
                                // TODO Auto-generated method stub
                               return this.testData.get(position);
                     }
 
                      //根據(jù)ListView位置得到數(shù)據(jù)源集合中的Id
                     @Override
                     public long getItemId(int position) {
                               // TODO Auto-generated method stub
                               return position;
                     }
                    //重寫adapter最重要的就是重寫此方法,此方法也是決定listview界面的樣式的
                    @Override
                    public View getView(int position, View convertView, ViewGroup parent) {
                                    //有很多例子中都用到這個(gè)holder,理解下??
                               ViewHolder holder = null;
                                //思考這里為何要判斷convertView是否為空  ??
                                if(convertView == null){
                                         holder = new ViewHolder();
    
                                         //把vlist layout轉(zhuǎn)換成View【LayoutInflater的作用】
                                         convertView = inflater.inflate(R.layout.vlist, null);
                                         //通過上面layout得到的view來獲取里面的具體控件
                                         holder.image = (ImageView) convertView.findViewById(R.id.image);
                                         holder.title = (TextView) convertView.findViewById(R.id.title);
                                         holder.info = (TextView) convertView.findViewById(R.id.info);
                                         holder.viewBtn = (Button) convertView.findViewById(R.id.viewBtn);
                                         //不懂這里setTag什么意思??
                                         convertView.setTag(holder);
                               }
                               else{
                                          holder = (ViewHolder) convertView.getTag();
                                }
                            //這里testData.get(position).get("title1")),其實(shí)就是從list集合(testData)中取出對(duì)應(yīng)索引的map,然后再根據(jù)鍵值對(duì)取值
                            holder.image.setBackgroundResource((Integer) testData.get(position).get("image1"));
                            holder.title.setText((String) testData.get(position).get("title1"));
                            holder.info.setText((String) testData.get(position).get("info1"));
                            //為listview上的button添加click監(jiān)聽
                            holder.viewBtn.setOnClickListener(new View.OnClickListener() {
                                       @Override
                                       public void onClick(View v) {
                                                   .....
                                       }
                            });
   
              return convertView;
  }
  
 }
 
        到此,整個(gè)案例的關(guān)鍵部分已經(jīng)全部出來了,做的過程中有很多地方?jīng)]有想通也都做有注釋,做完以后,多揣摩了幾遍才將就理解,嘿嘿
重點(diǎn)提出一個(gè)疑問:不能確定是否在onCreate方法中的 new Adapter,在里面表面上看是只調(diào)用了一次而進(jìn)入自定義Adapter中調(diào)用(其實(shí)也沒有直接調(diào)用,自己想的它可能有一個(gè)自己的內(nèi)部機(jī)制,每new完一個(gè)Adapter就直接調(diào)用getCount/getView方法嗎)它里面的方法 ,調(diào)用一次就會(huì)繪制一個(gè)ListView中的一個(gè)item項(xiàng),那么有很多條item的時(shí)候,它是否要那樣循環(huán)調(diào)用很多次呢??
       getView方法中的參數(shù),convertview那塊。在初始化的時(shí)候,每顯示一行item項(xiàng)都會(huì)調(diào)用一次getView方法但每次調(diào)用的時(shí)候convertview為null(因?yàn)檫€沒有舊的view);如果屏幕移動(dòng)了之后,并且導(dǎo)致某些item項(xiàng)跑到屏幕外面,此時(shí)如果還有新的item需要產(chǎn)生,則這些item顯示時(shí)調(diào)用的getView方法中的convertview就不為null,而是那些移出到屏幕之外的view,我們所要做的就是將需要顯示的item項(xiàng)填充到移除屏幕外的(舊的)view中去,注意【convertview為null的不僅僅是初始化顯示的那些item,還有一些是已經(jīng)開始移入屏幕但還沒有view被回收的那些item】。
  
運(yùn)行結(jié)果:
 

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多