大家好!接續[Day10-12]三篇文章的介紹,我們了解到常用的清單元件有ListView、GridView和Spinner,分別從其中了解到:
三者在xml檔的設計
了解ListView、GridView的比較,GridView為二維的排列方式,而ListView是可滑動的垂直清單,清單為單方向的排列
Spinner的偵聽方式setOnItemSelectedListener與ListView、GridView的偵聽方式setOnItemClickListener不同
雖然介紹完這三者元件的特色,不過好像缺了甚麼東西,總覺得三者的清單選單太過單調、不吸引人,那是不是有什麼方法可以改變清單的樣式呢?能否自己設計我想要的清單模式呢?OK,千萬別離開,這篇文章將會討論上述問題喔。那我們趕快來討論清單模式的設計吧!
這篇要接續作水果清單,以下範例以GridView元件作說明:
xml檔必須要設計2個檔案,第一個主畫面GridView的顯示,第二個選單的設計,沒錯!選單的設計就是在layout文件底下建立xml檔。
主畫面GridView程式碼
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<GridView
android:id="@+id/gvShow"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:numColumns="2"
/>
</LinearLayout>
選單程式碼
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/imgFruit"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_marginTop="5dp"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:layout_gravity="center_horizontal"
/>
<TextView
android:id="@+id/tvName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:layout_gravity="center_horizontal"/>
<TextView
android:id="@+id/tvPrice"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:layout_gravity="center_horizontal"
android:layout_marginBottom="5dp"/>
</LinearLayout>
這樣主畫面和選單都準備妥當了!趕緊來設計Java程式!GO!
首先,要建立清單內容,每一個選項內容包含名稱、價格、圖片,由於選項中有比較多的資訊,因此我們定義一個類別為Fruit裡面存放水果名稱、水果價格及水果圖片,往後要使用裡頭的內容可以建立Fruit物件呼叫類別的方法。
public class Fruit {
private String name;
private int price;
private int img;
Fruit(String name,int price,int img){
this.name=name;
this.price=price;
this.img=img;
}
public void setName(String name) {
this.name = name;
}
public void setPrice(int price) {
this.price = price;
}
public void setImg(int img) {
this.img = img;
}
public String getName() {
return name;
}
public int getPrice() {
return price;
}
public int getImg() {
return img;
}
}
第二步驟準備列表以便存放Fruit物件
private List<Fruit> fruitList = new ArrayList<>();
第三步驟建立資料,新增Fruit物件,並加入Fruit物件集合的列表
private List<Fruit> getList () {
fruitList.add(new Fruit("Apple", 50, R.drawable.apple));
fruitList.add(new Fruit("Banana", 20, R.drawable.banana));
fruitList.add(new Fruit("Orange", 30, R.drawable.orange));
fruitList.add(new Fruit("Grape", 100, R.drawable.grape));
fruitList.add(new Fruit("Strawberry", 120, R.drawable.strawberry));
return fruitList;
}
第四步驟實作baseAdapter類別
在實作之前先討論一下baseAdapter需要覆寫的方法
public class FruitAdapter extends BaseAdapter{
@Override
public int getCount() {
return 0;
}
@Override
public Object getItem(int i) {
return null;
}
@Override
public long getItemId(int i) {
return 0;
}
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
return null;
}
}
public class FruitAdapter extends BaseAdapter {
private List<Fruit> fruitList = new ArrayList<>();
FruitAdapter(List<Fruit> fruitList) {
this.fruitList = fruitList;
}
@Override
public int getCount() {
return fruitList.size();
}
@Override
public Object getItem(int position) {
return fruitList.get(position);
}
@Override
public long getItemId(int position) {
return fruitList.get(position).getImg();
}
@Override
public View getView(int position, View view, ViewGroup viewGroup) {
View gridview = view;
if (gridview == null) {
gridview = getLayoutInflater().inflate(R.layout.fruit_layout, null);
}
Fruit fruit = fruitList.get(position);
TextView tvName = (TextView) gridview.findViewById(R.id.tvName);
tvName.setText(fruit.getName());
TextView tvPrice = (TextView) gridview.findViewById(R.id.tvPrice);
tvPrice.setText(Integer.toString(fruit.getPrice()));
ImageView imgFruit = (ImageView) gridview.findViewById(R.id.imgFruit);
imgFruit.setImageResource(fruit.getImg());
return gridview;
}
}
}
long getItemId物件內容有水果名稱、水果價格及水果圖片,通常尋找符合int型別有唯一值作為ID,物件內容的水果名稱不是int型別以及水果價格容易重複,因此實作會以水果圖片作為ID值
View getView(int position, View view, ViewGroup viewGroup) view存放當前使用者所看到的選單
if (gridview == null)避免重新載入同一個選單
getLayoutInflater().inflate(R.layout.fruit_layout, null) 得到LayoutInflater物件去載入已經設計好的fruit_layout.xml
元件取得皆是由gridview所載入的fruit_layout.xml獲得
第五步驟建立GridView偵聽器
private void setListener() {
gvShow.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
setToast(position);
}
});
}
完整程式碼
//改為自己設定的APK名稱
package com.example.myapplication;
public class MainActivity extends AppCompatActivity {
private List<Fruit> fruitList = new ArrayList<>();
private GridView gvShow;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.gridview_layout);
findViews();
fruitList=getList();
setAdapter();
setListener();
}
private void findViews () {
gvShow = (GridView) findViewById(R.id.gvShow);
}
private void setToast (int position){
Toast.makeText(MainActivity.this,fruitList.get(position).getName(), Toast.LENGTH_SHORT).show();
}
private void setAdapter() {
FruitAdapter adapter = new FruitAdapter(fruitList);
gvShow.setAdapter(adapter);
}
private void setListener() {
gvShow.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
setToast(position);
}
});
}
private List<Fruit> getList () {
fruitList.add(new Fruit("Apple", 50, R.drawable.apple));
fruitList.add(new Fruit("Banana", 20, R.drawable.banana));
fruitList.add(new Fruit("Orange", 30, R.drawable.orange));
fruitList.add(new Fruit("Grape", 100, R.drawable.grape));
fruitList.add(new Fruit("Strawberry", 120, R.drawable.strawberry));
return fruitList;
}
public class FruitAdapter extends BaseAdapter {
private List<Fruit> fruitList = new ArrayList<>();
FruitAdapter(List<Fruit> fruitList) {
this.fruitList = fruitList;
}
@Override
public int getCount() {
return fruitList.size();
}
@Override
public Object getItem(int position) {
return fruitList.get(position);
}
@Override
public long getItemId(int position) {
return fruitList.get(position).getImg();
}
@Override
public View getView(int position, View view, ViewGroup viewGroup) {
View gridview = view;
if (gridview == null) {
gridview = getLayoutInflater().inflate(R.layout.fruit_layout, null);
}
Fruit fruit = fruitList.get(position);
TextView tvName = (TextView) gridview.findViewById(R.id.tvName);
tvName.setText(fruit.getName());
TextView tvPrice = (TextView) gridview.findViewById(R.id.tvPrice);
tvPrice.setText(Integer.toString(fruit.getPrice()));
ImageView imgFruit = (ImageView) gridview.findViewById(R.id.imgFruit);
imgFruit.setImageResource(fruit.getImg());
return gridview;
}
}
}
//改為自己設定的APK名稱
package com.example.myapplication;
public class Fruit {
private String name;
private int price;
private int img;
Fruit(String name,int price,int img){
this.name=name;
this.price=price;
this.img=img;
}
public void setName(String name) {
this.name = name;
}
public void setPrice(int price) {
this.price = price;
}
public void setImg(int img) {
this.img = img;
}
public String getName() {
return name;
}
public int getPrice() {
return price;
}
public int getImg() {
return img;
}
}
終於完成自己打造的Adapter~
辛苦大家了~
若文章有誤,歡迎大家提出建議。
Thank you for your time.