跳到主要內容

[隋堂筆記] Android 利用BaseAdapter來自訂ListView

BaseAdapter 可以讓使用者自己定義許多種 View ,像是 Spinner, ListView, GridView等,而且可以重用View來節省資源:使用setTag將View存起來,之後就可以利用getTag將數據取出來

Step1  在activity_main.xml中新增ListView

例如:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp">
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/lv"/>
</LinearLayout>

Step2 在layout中新增list_content.xml,並排好想要的ListView item佈局







<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingTop="16dp"
android:paddingBottom="16dp"
android:gravity="center_vertical">
<ImageView
android:id="@+id/iv"
android:layout_width="64dp"
android:layout_height="64dp"
android:src="@drawable/photos"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/tv1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/tv2"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>

Step3 在MainActivity.java 新增一個類別BA並繼承BaseAdapter


透過繼承 BaseAdapter,我們可以重新覆寫4個方法:

    public int getCount();
    取得 ListView 列表 Item 的數量。通常數量就是從建構子傳入的陣列或是集合大小。

    public Object getItem(int position);
    取得 ListView 列表於 position 位置上的 Item。position 通常是資料在陣列或是集合上的位置。

    public long getItemId(int position);
    取得 ListView 列表於 position 位置上的 Item 的 ID,一般用 position 的值即可。

    public View getView(int position, View view, ViewGroup viewGroup);
    通常會設定與回傳View 作為顯示在這個 position 位置的 Item 的 View。

基本上只要處理兩個方法 getCount跟getView即可。

getCount回傳我所宣告的String陣列st1的長度。
public int getCount() {
return st1.length;
}

在getView之前,要先取得LayoutInflater
LayoutInflater loi;
public BA(){
loi = (LayoutInflater) MainActivity.this.getSystemService(LAYOUT_INFLATER_SERVICE);
}

再來要先宣告一個類別viewHolder,用來存放list_content.xml內所有元件的內容
private class viewHolder {
ImageView iv;
TextView tv1,tv2;
}

接著判斷view是否為空,如果為空就要對他進行初始化:
1,透過LayoutInflater將我們自訂的list_content.xml裝進去
2,new一個viewHolder出來,並將元件內容裝進去
3,透過setTag把viewHolder裝進去
如果view不為空,就利用getTag將數據讀出來
if (view == null) {
//將自訂的list_contnet灌進view裡
view = loi.inflate(R.layout.list_content, null);
//new一個VH,並將iv,tv1,tv2裝進去
vh = new viewHolder();
vh.iv = (ImageView) view.findViewById(R.id.iv);
vh.tv1 = (TextView) view.findViewById(R.id.tv1);
vh.tv2 = (TextView) view.findViewById(R.id.tv2);
//再透過view.setTag把vh裝進去
view.setTag(vh);
}else {
vh = (viewHolder) view.getTag();
}

最後設定元件要放置的內容,並return view
vh.iv.setImageResource(R.drawable.photos);
vh.tv1.setText(st1[position]);
vh.tv2.setText("xxxxxxxx");
return view;

Step4 在MainActivity.java  onCreate中使用BA這個 Adapter


lv = (ListView) findViewById(R.id.lv);
lv.setAdapter(new BA());



完整MainActivity.java程式碼:

public class MainActivity extends AppCompatActivity {
ListView lv;
String st1[] = {"Name01","Name02","Name03","Name04","Name05","Name06"};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lv = (ListView) findViewById(R.id.lv);
lv.setAdapter(new BA());
}
private class BA extends BaseAdapter {
LayoutInflater loi;
public BA(){
loi = (LayoutInflater) MainActivity.this.getSystemService(LAYOUT_INFLATER_SERVICE);
}
@Override
public int getCount() {
return st1.length;
}
@Override
public Object getItem(int i) {
return null;
}
@Override
public long getItemId(int i) {
return 0;
}
@Override
public View getView(int position, View view, ViewGroup viewGroup) {
viewHolder vh;
//判斷view是否為空,為空才設置view
if (view == null) {
//將自訂的list_contnet灌進view裡
view = loi.inflate(R.layout.list_content, null);
//new一個VH,並將iv,tv1,tv2裝進去
vh = new viewHolder();
vh.iv = (ImageView) view.findViewById(R.id.iv);
vh.tv1 = (TextView) view.findViewById(R.id.tv1);
vh.tv2 = (TextView) view.findViewById(R.id.tv2);
//再透過view.setTag把vh裝進去
view.setTag(vh);
}else {
vh = (viewHolder) view.getTag();
}
//設定iv,tv1,tv2要放置的內容
vh.iv.setImageResource(R.drawable.photos);
vh.tv1.setText(st1[position]);
vh.tv2.setText("xxxxxxxx");
return view;
}
}
//宣告類別 viewHolder,記住list_content.xml中的item
private class viewHolder {
ImageView iv;
TextView tv1,tv2;
}
}


執行結果:



參考資料:賽肥膩膩GiveMePasS's Android惡補筆記



留言

這個網誌中的熱門文章

[Android] 使用shape自訂形狀及陰影

shape可以定義下面四種類型的形狀:     rectangle- 矩形(直角矩形、圓角矩形),默認的形狀     oval- 橢圓形、圓形     line- 線形(實線、虛線)     ring- 環形、環形進度條 rectangle 執行結果: 如果填色要填入漸層色的話,需要將solid標籤改成gradient標籤,用法如下: 執行結果: oval 執行結果: oval和ring的漸層有三種類型(android:type):linear(線性)、radial(放射性)、sweep(掃描) 如果漸層效果為radial(放射性)的話,必須加上android:gradientRadius屬性(指定漸層的半徑)。 執行結果: line 線的高度是透過stroke的android:width屬性設置,而size的android:height是定義整個形狀區域的高度,所以 size的height必須大於stroke的width 。 執行結果: ring 屬於ring的屬性:     android:innerRadius 內環的半徑     android:thickness 環的厚度     android:useLevel 一般設為false,要不然環可能會無法顯示 執行結果: 將環設計成環狀進度條的樣式: 1,在shape標籤外再加上rotate標籤 rotate屬性:     android:fromDegrees:開始旋轉的角度位置     android:toDegrees:結束時轉到的角度位置     android:pivotX:旋轉起點的X軸座標位置,可以是數值、百分比、百分比p     android:pivotY:旋轉起點的Y軸座標位置,可以是數值、百分比、百分比p 2,在style.xml裡加上style樣式 3,在activity_main.xml裡加上progressBar標籤...

[iOS] Objective-C 自訂UITableViewCell樣式

Step1 在Storyboard中拉出TableView和按下TableView Cell後要切換的View,並設定對應的class檔 TableView連結至ListController類別,並設定Storyboard ID為ListController 要切換的View連結至ViewController類別,並設定Storyboard ID為viewController Step2 新增CustomCell.xib 新增File(File → New → File...),選擇View,並將檔案命名為CustomCell 開啟CustomCell.xib,把預設的View元件刪掉,然後從元件庫拖曳Table View Cell,並拉好想要的Cell內容排版 Step3 新增自訂Objective-C class給這個NIB檔 新增File(File → New → File...),選擇Cocoa Touch class 需要繼承UITableViewCell Step4 回到CustomCell.xib,將Class連結到CustomTableViewCell Step5 在CustomTableViewCell.h檔中,設定元件變數 Step6 在ListController.h中設定TableView的元件變數,且宣告一個陣列,負責儲存表格上要呈現的資料 Step7 在ListController.m  的viewDidLoad方法中設定TableView的兩個輸出口:dataSource、delegate,並初始化陣列資料 dataSource所連結到的View Controller用來提供表格上Cell的內容 delegate為指定哪一個View Controller需要處理使用者在表格上的操作 Step8 在ListController.m中,實作tableView:numberOfRowsInSection:方法 -通知Table View需要產生多少個Cell(儲存格)來顯示資料 Step9 在ListController.m中,實作tableView:cellForRowAtIndexPat...