第一行程式碼第二版ListView的使用(listView複用遇到的坑)
阿新 • • 發佈:2019-01-31
這個複雜又好用的控制元件,說不清是愛是恨。開始學習它吧。
首先當然是建立專案啊,然後修改一下activity_main的佈局檔案,內容如下
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<ListView
android:id="@+id/list_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
這裡就注意讓它佔滿全屏就好了,按照之前控制元件的邏輯呢,現在只要去MainActiviry裡邊findViewById就行,這個不行,為啥?開頭說了,它比較複雜嘛….這個控制元件呢需要一個介面卡,,我們可以在介面卡裡面幫它繫結資料,方便它來展示
新建一個layout,,程式碼如下
<?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="wrap_content">
<ImageView
android:id="@+id/fruit_image"
android:layout_width="50dp"
android:layout_height ="50dp"
android:src="@drawable/apple" />
<TextView
android:id="@+id/fruit_text"
android:layout_width="90dp"
android:layout_height="50dp"
android:layout_marginLeft="10dp"
android:gravity="center_vertical"
android:text="Apple"
android:textSize="18dp" />
</LinearLayout>
這個也很簡單,我們想讓這個listView顯示什麼樣式呢,就在這個裡面做就行,現在我做的,就是左邊一個水果圖片,右邊一個名字。然後,我們寫一個方便呼叫的工具類,程式碼如下
/**
* 工具類
*/
public class Fruits {
private String name;
private int imageId;
public Fruits(String name, int imageId) {
this.name = name;
this.imageId = imageId;
}
public String getName() {
return name;
}
public int getImageId() {
return imageId;
}
}
接下來就是重頭戲了,介面卡,listview的介面卡有很多種,這本書裡使用的是ArrayAdapter,所以,我也是,看程式碼
/**
* 介面卡
*/
public class FruitAdapter extends ArrayAdapter<Fruits> {
private int resourceId;
/**
* 重寫方法,方便之後呼叫
* @param context 上下文
* @param textViewResourceId 要繫結的佈局檔案
* @param objects 佈局檔案裡面要使用的資料,(函式)
*/
public FruitAdapter(Context context, int textViewResourceId, List<Fruits> objects) {
super(context, textViewResourceId, objects);
this.resourceId = textViewResourceId;
}
/**
* 重寫getView方法,在這個方法裡面做資料的繫結等操作
* @param position 當前的item
* @param convertView 快取的資料
* @param parent 父佈局
* @return
*/
@NonNull
@Override
public View getView(int position, View convertView, ViewGroup parent) {
Fruits fruits = getItem(position); //獲取當前的item的例項
View view;
final ViewHoder viewHoder; //為了優化listview建立的一個內部類,可以不用每次都重新建立item的例項
//如果快取為空的話,就建立view,,否則,就複用快取的view(這麼做的前提是,每個view的佈局都一樣)
if (convertView == null) {
view = LayoutInflater.from(getContext()).inflate(resourceId, parent, false);
viewHoder = new ViewHoder();
viewHoder.fruitText = (TextView) view.findViewById(R.id.fruit_text);
viewHoder.fruitImage = (ImageView) view.findViewById(R.id.fruit_image);
viewHoder.fruitText.setText(fruits.getName());
viewHoder.fruitImage.setImageResource(fruits.getImageId());
view.setTag(viewHoder);//將viewHolder的例項儲存在view裡面
}else {
view = convertView;
viewHoder = (ViewHoder) view.getTag();//如果沒有快取就取出來
viewHoder.fruitText.setText(fruits.getName());
viewHoder.fruitImage.setImageResource(fruits.getImageId());
}
return view;
}
private class ViewHoder {
TextView fruitText;
ImageView fruitImage;
}
}
很麻煩是吧,我在這遇到了一個坑,大家可以看到,在 if 和 else 裡面有兩行相同的程式碼,是給圖片和名字賦值的。這時候有人問了,既然viewHolder的例項已經儲存在view裡邊了,為什麼還要再次賦值呢?思維盲點啊,我也想半天啊,它儲存的是例項啊,不重新賦值的話,拿到的值每次都不一樣的啊。
viewHoder.fruitText.setText(fruits.getName()); viewHoder.fruitImage.setImageResource(fruits.getImageId());
我試了一下,不再次賦值,也能成功執行。但是,每次出現的資料都不同的。想要資料正確,請千萬記得重新賦值。好吧,我這個腦子容易出這種亂七八糟的錯誤,如果有同樣錯的。希望能幫到你。
對了,還有最後MainActivity的程式碼:
public class MainActivity extends AppCompatActivity {
//建立一個集合,待會要放資料的
private List<Fruits> fruitList = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//這個方法裡邊全是資料
initFruit();
//介面卡,要記得繫結你定樣式的那個佈局檔案
FruitAdapter adapter = new FruitAdapter(MainActivity.this,
R.layout.fruit_item, fruitList);
ListView listView = (ListView) findViewById(R.id.list_view);
listView.setAdapter(adapter);
}
//寫了個for迴圈,資料太少,不迴圈的話不夠滑動頁面的
private void initFruit() {
for (int i = 0; i < 5; i++) {
Fruits apple = new Fruits("Apple", R.drawable.apple);
fruitList.add(apple);
Fruits banana = new Fruits("Banana", R.drawable.banana);
fruitList.add(banana);
Fruits cherry = new Fruits("Cherry", R.drawable.cherry);
fruitList.add(cherry);
Fruits grape = new Fruits("Grape", R.drawable.grape);
fruitList.add(grape);
Fruits orange = new Fruits("Orange", R.drawable.orange);
fruitList.add(orange);
Fruits pear = new Fruits("Pear", R.drawable.pear);
fruitList.add(pear);
Fruits watermelon = new Fruits("WatermeIon", R.drawable.watermelon);
fruitList.add(watermelon);
}
}
}
嗯,基本就這樣了