天天看點

Android_擴充卡的使用

介紹擴充卡的使用,從淺到深,一共6步,這6步所用到的xml檔案相同,就是下面這兩個

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="${relativePackage}.${activityClass}" >

    <ListView
        android:id="@+id/lv"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>
item1中第二個TextView隻有在5和6中用到
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal" >
    <ImageView
        android:id="@+id/item1_iv"
        android:layout_width="70dp"
        android:layout_height="70dp"
        android:layout_gravity="center_vertical"
        android:src="@drawable/h2" />

    <TextView
        android:id="@+id/item1_tv"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:text="ddddddd"
        android:gravity="center" />

    <CheckBox
        android:id="@+id/item1_cb"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical" />

</LinearLayout>
           

1.簡單擴充卡的使用

package com.example.adapterdemo2;


import android.app.Activity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;

public class MainActivity2 extends Activity {
    ListView lv;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        lv=(ListView) findViewById(R.id.lv);
        MyAdapter ma=new MyAdapter();
        lv.setAdapter(ma);
    }
    class MyAdapter extends BaseAdapter{

        @Override
        public int getCount() {
            // TODO Auto-generated method stub
            return ;
        }

        @Override
        public Object getItem(int position) {
            // TODO Auto-generated method stub
            return position;
        }

        @Override
        public long getItemId(int position) {
            // TODO Auto-generated method stub
            return ;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            // TODO Auto-generated method stub
            LayoutInflater                          layoutInflater=MainActivity2.this.getLayoutInflater();
            View view=layoutInflater.inflate(R.layout.item1, parent,false);
            return view;
        }

    }
}
           

這篇代碼實作的功能比較簡單,在activity_main.xml檔案中建立一個元件ListView,設定相應的id.在MainActivity中findViewByid執行個體化這個控件.

建立一個子類繼承BaseAdapter,實作抽象方法.在getCount()方法中設定條目數量,之後再getView()方法中實作下面的功能(MainActivity中沒有以下注釋)

Android_擴充卡的使用

之後的步驟就是建立子類的對象,然後通過setAdapter();方法将這個對象傳進去,詳情看代碼

2.将集合資料傳到條目中的擴充卡的使用

package com.example.adapterdemo2;

import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;

public class MainActivity extends Activity {
    private ListView lv;
    private List<String>datas=new ArrayList<String>();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        for(int i=;i<;i++){
            datas.add("我是資料------>"+i);
        }
        lv=(ListView) findViewById(R.id.lv);
        MyAdapter ma=new MyAdapter();
        lv.setAdapter(ma);
    }
    class MyAdapter extends BaseAdapter{

        @Override
        public int getCount() {
            // TODO Auto-generated method stub
            return datas.size();
        }

        @Override
        public String getItem(int position) {
            // TODO Auto-generated method stub
            return datas.get(position);
        }

        @Override
        public long getItemId(int position) {
            // TODO Auto-generated method stub
            return position;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            // TODO Auto-generated method stub
            LayoutInflater layoutInflater=MainActivity.this.getLayoutInflater();
            View view=layoutInflater.inflate(R.layout.item1, parent,false);
            TextView tv=(TextView)view.findViewById(R.id.item1_tv);
            tv.setText(getItem(position));
            return view;
        }
    }
}
           

和上面的擴充卡的使用基本一樣,有幾處需要注意的地方

(1)下面代碼紅色标注的地方,注意這裡并不是activity_main中的元件,而是在上一行view對象中,上一行已經将相應的布局檔案轉換成View對象,而所加載的TextView就在這個布局中,是以在這裡應該特别注意

Android_擴充卡的使用

(2)紅線标注的方法,傳回一個字元串,position是條目的位置,也可以将第二個橫線位置,換成datas.get(position),也就是上面方法的傳回值

Android_擴充卡的使用

3.擴充卡内部的優化使用(針對View對象)

這個擴充卡的使用效果和上的擴充卡使用的效果一樣,但是内部進行了優化,使記憶體的使用的到了優化

getView() 方法會被反複調用很多次,加載不同位置的條目

當ListView初次展開時,getView方法調用多少次?

取決于目前界面展現了多少條目,不展現的條目暫時不加載 ——這就是BaseAdapter的内部優化機制

當上下滾動時,界面展現哪個條目,我們就調用getView方法加載哪一個條目

此時因為 重新調用了該位置的getView,是以會重新inflate一個新的view對象,那麼之前我們舊的view對象就成為了垃圾對象 ,造成記憶體必要的消耗

是以,我們要針對此種情況進行優化 :複用view對象 使用參數converView

假如我們界面 可以展現5個條目 那麼總共會有多少個view對象?會有7個,最上面的露一半,最下面的露一半.是以可能有7個

在這篇代碼getView方法中有如下代碼

Android_擴充卡的使用

在标簽可以看出converView.hashCode()的值會被反複使用,而上一個擴充卡的使用converView.hashCode()所列印的完全不同.關于這裡的優化問題在另一篇筆記擴充卡(2)中有介紹

4.擴充卡内部的優化使用(針對View和TextView對象)

針對View對象造成的記憶體浪費,在3中已經進行了優化,但是在每次調用getVeiw方法,更新TextView對象tv時,tv都會重新finViewById,而這個方法也會重新建立一個對象,也會造成記憶體的浪費,(在新版本的手機中這個問題已經在版本中進行了優化,不用開發者考慮,但是我們也需要知道這個原理和方法,主要針對沒有進行優化的手機版本),問題和3中所說的問題相似,就不在贅述,隻說一下解決方法.

Android_擴充卡的使用

我已開始是這麼了解的:

Android_擴充卡的使用

convertView怎麼解決,tv就怎麼解決,這樣的了解是錯了,因為converView是緩存對象,是時刻存在的而TextView的對象tv不是,每次執行這個方法時,tv對象都需要重新建立,而converView不為空時,tv為空,是以既然convertView不會消失,那麼就将tv存到converView中,于是就有了開始時候的解決辦法了,通過setTag進行存儲,getTag進行提取

5.多個TextView對象的擴充卡的使用

我一開始的了解是如果有兩個TextView,是不是可以一個一個的使用,就和上面TextView對象tv一樣,隻是多了一個,事實是錯的,因為convertView的setTag方法隻能用一次,getTag也是同樣的道理

是以應用java面向對象的思想,一個功能一個類,将多個TextView對象封裝到一個類裡面,對這個類對象進行操作即可,代碼不難,了解思想

6.對CheckBox使用優化的擴充卡

Android_擴充卡的使用

因為convertView對象中沒有儲存CheckBox的狀态,是以就算打上勾條目消失後,勾選狀态也就消失了,是以應該想辦法,留住相應位置的選中狀态,可以用鍵值對來儲存,也就是用Map集合,位置是Key,狀态是Value.把CheckBox也封裝到類裡面(就是5中的 ViewHolder類)

圖中紅線:将位置存到CheckBox對象cb的Tag裡

圖中紫線:對cb進行監聽(最好不要内名内部類,因為每次都會産生一個新對象)

圖中藍線:根據位置position(Key)取出是否被選中的狀态(Value)

圖中黃線:取出存儲在cb中的位置