[Android Studio]下拉式選單(Spinner)筆記五--客製化選單
基本的Spinner只有文字,想要搭配圖片可以客製化選單,使用ArrayAdapter,並自訂選項內容,重新設計選項佈局(layout)。可參考Coding in Flow Custom Spinner - Android Studio Tutorial,裡面有詳細步驟,Source code: https://codinginflow.com/tutorials/android/custom-spinner,客製化Spinner範例畫面如下:
此次筆記仍以行星為主題,Spinner初始畫面結果如下:
Spinner下拉清單佈局如下:
準備工作:
1.下載下拉圖示(icon),可以參考Icons - Material Design,尋找頁面上Navigation類別,有很多方向圖示可以下載,此次選擇arrow_drop_down,格式選PNG,下載arrow_drop_down-black-18dp.zip,解壓縮後就可以看到圖示,此次選擇2x的baseline_arrow_drop_down_black_18dp.png圖檔。
2.在維基百科(Wikipedia)查所需的行星,並下載圖檔,存成"星球名.jpg",例如mercury.jpg、earth.jpg等,注意檔名只能是小寫英文字 (a-z)、數字 (0-9)及底線等,不能用大寫英文字。
完成後project架構:
客製化選單步驟:
步驟1:新增Project
先在Android Studio新增project,點選File>New>New Project,種類選擇[Empty Activity],名稱設為MySpinner1,完成新增project。
將需要的圖示檔和圖檔全部複製到app\src\main\res\drawable目錄下。
選左方 Resource Manager,可看到上述的下拉圖示、下載的行星圖檔及系統預設背景。
步驟2:設定Spinner item 內容
新增PlanetsItem.java設定選項(item)內容,在java->com.example.myapplication上按右鍵->New->Java Class,檔案名稱設為PlanetsItem 。新增一個PlanetsItem的class,內容包含行星名稱(String mPlanetName)及相對應的圖檔(int mPlanetsImage),並新增getPlanetName()功能,回傳行星名稱。
PlanetsItem.java內容如下:
package com.example.myspinner1;
public class PlanetsItem {
private String mPlanetName;
private int mPlanetsImage;
public PlanetsItem(String PlanetName, int PlanetImage) {
mPlanetName = PlanetName;
mPlanetsImage = PlanetImage;
}
public String getPlanetName() {
return mPlanetName;
}
public int getPlanetImage() {
return mPlanetsImage;
}
}
|
在MainActivity.java中,增加initList()函數,設定選單名稱及圖檔。
private void initList() {
mPlanetList = new ArrayList<>();
mPlanetList.add(new PlanetsItem("Mercury", R.drawable.mercury));
mPlanetList.add(new PlanetsItem("Venus", R.drawable.venus));
mPlanetList.add(new PlanetsItem("Earth", R.drawable.earth));
mPlanetList.add(new PlanetsItem("Mars", R.drawable.mars));
mPlanetList.add(new PlanetsItem("Jupiter", R.drawable.jupiter));
mPlanetList.add(new PlanetsItem("Saturn", R.drawable.saturn));
mPlanetList.add(new PlanetsItem("Uranus", R.drawable.uranus));
mPlanetList.add(new PlanetsItem("Neptune", R.drawable.neptune));
}
|
步驟3:新增客製化Spinner佈局(layout)
(1).設定Spinner初始佈局背景
在app\src\main\res\drawabl新增Spinner初始佈局背景spinner_back.xml,於drawable上按右鍵->New->Drawable Resource File,檔案名稱設為spinner_back
參考碼農日常-『Android studio』如何使用Spinner下拉式選單-2 自訂樣式的下拉式選單。產生一個有框、背景為黑色(因圖片背景為黑色,所以整個spinner背景都設為黑色),有白色下拉圖示(使用android:tint改變圖示bitmap顏色)的Spinner的背景。
(2).設定Spinner選項布局
在app\src\main\res\layout新增Spinner選項佈局(item layout)的myspinner.xml,於layout上按右鍵->New->Layout Resource File,檔案名稱設為myspinner。內容設定為RelativeLayout ,新增一個ImageView及TextView,設定初始圖型及文字,方面預覽,並設定大小、顏色、位置及各項參數。
可參考Coding in Flow Custom Spinner - Android Studio Tutorial。
完整spinner_back.xml:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
//第一組item 圓角邊框
<item>
<shape>
<stroke
android:width="2dp"
android:color="#B6B4B4"
/> //邊框線顏色
<corners android:radius="5dp" /> //圓角度數
<solid android:color="#000000" > //背景顏色
</solid>
<padding android:right="5dp" /> //邊距
<size
android:width="200dp"
android:height="30dp"
/>
</shape>
</item>
//第二組item spinner箭頭圖示
<item>
<bitmap
android:gravity="end"
android:src="@drawable/baseline_arrow_drop_down_black_18dp"
android:antialias="true"
android:tint="#FFFFFF"
/>
</item>
</layer-list>
|
完整myspinner.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="3dip"
>
<ImageView
android:id="@+id/image"
android:layout_width="150dp"
android:layout_height="100dp"
android:src="@drawable/earth" />
<TextView
android:id="@+id/text1"
android:layout_width="150dp"
android:layout_height="90dp"
android:layout_marginLeft="20dp"
android:layout_marginTop="2dip"
android:layout_toRightOf="@+id/image"
android:ellipsize="marquee"
android:gravity="center_vertical"
android:paddingLeft="16dp"
android:paddingTop="10dp"
android:paddingBottom="10dp"
android:text="Earth"
android:textSize="24dp"
android:textColor="#FFFF00"
android:textStyle="bold"
/>
</RelativeLayout>
|
步驟4:新增Spinner並設定背景及標題
參考[Android Studio]下拉式選單(Spinner)筆記四-設定標題文字大小顏色@ KOEI的旅行產生dialog模式的spinner,並設定標題大小及顏色。
設定標題名稱,srtings.xml內容如下:
<resources>
<string name="app_name">MySpinner1</string>
<string name="planet_prompt">Choose a planet</string>
</resources>
|
設定標題大小及顏色,完整styles.xml內容如下:
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
<item name="alertDialogTheme">@style/MyAlertDialogStyle</item>
</style>
<style name="MyAlertDialogStyle" parent="Base.V7.ThemeOverlay.AppCompat.Dialog">
<item name="android:background">#000000</item>
<item name="android:windowBackground">@null</item>
<item name="android:windowTitleStyle">@style/MyTextAppearance</item>
</style>
<style name="MyTextAppearance" >
<item name="android:textColor">@android:color/white</item>
<item name="android:textSize">24dp</item>
</style>
</resources>
|
在activity_main.xml中Spinner的背景設為新增的spinner_back.xml,android:background="@drawable/spinner_back"。
完整activity_main.xml內容如下:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
tools:context=".MainActivity">
<TextView
android:id="@+id/hello"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Spinner
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minWidth="100dp"
android:id="@+id/spinner"
android:drawSelectorOnTop="true"
android:spinnerMode="dialog"
android:prompt="@string/planet_prompt"
android:background="@drawable/spinner_back"
/>
|
步驟5:客製化Spinner view
新增 MyAdapter.java設定客製化內容及畫面(view),在java->com.example.myapplication上按右鍵->New->Java Class,檔案名稱設為MyAdapter 。新增MyAdapter為自己定義的ArrayAdapter class,ArrayAdapter的資料內容為步驟2定義的PlanetsItem。重新設定getView(初始或選擇後出現的畫面)及設定getDropDownView(下拉展開時選項的畫面),以顯示需要的畫面,此次2種畫面都一樣,都呼叫同一個initView()函數即可,並將客製的選項佈局myspinner.xml填入LayoutInflater(佈局填充器)。為顯示已選取的選項位置,新增一個spos參數,紀錄已選取的選項索引,並在下拉式畫面改面該選項顏色。
完整MyAdapter.java如下:
package com.example.myspinner1; import android.content.Context; import android.graphics.Color; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.ImageView; import android.widget.TextView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import java.util.ArrayList; // Adapter class for spinner control public class MyAdapter extends ArrayAdapter<PlanetsItem> { private Context context; private int spos=0; public MyAdapter(Context context, ArrayList<PlanetsItem> PlanetList) { super(context, 0, PlanetList); this.context=context; } @NonNull @Override public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) { spos = position; return initView(position, convertView, parent); } @Override public View getDropDownView(int position, @Nullable View convertView, @NonNull ViewGroup parent) { return initView(position, convertView, parent); } private View initView(int position, View convertView, ViewGroup parent) { convertView = LayoutInflater.from(getContext()).inflate( R.layout.myspinner, parent, false); ImageView imageViewFlag = convertView.findViewById(R.id.image); TextView textViewName = convertView.findViewById(R.id.text1); PlanetsItem currentItem = getItem(position); if (currentItem != null) { imageViewFlag.setImageResource(currentItem.getPlanetImage()); textViewName.setText(currentItem.getPlanetName()); if (position == spos) {textViewName.setTextColor (Color.argb(255, 255, 255, 255));} } return convertView; } } |
步驟6:運用客製化Spinner
MainActivity原本使用 ArrayAdapter,例如ArrayAdapte adapter = new ArrayAdapter(this,R.layout.spinner_style, planetsList)改為呼叫客製的MyAdapter;而DropDownView已經重新定義在MyAdapter,所以也不用再呼叫setDropDownViewResource了。只要以下程式,就可完成使用客製的Spinner:
Spinner spinner = (Spinner) findViewById(R.id.spinner);
mAdapter = new MyAdapter(this, mPlanetList);
spinner.setAdapter(mAdapter);
最後設定選取選項後的動作setOnItemSelectedListener即可。
完整MainActivity.java如下:
package com.example.myspinner1;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Spinner;
import android.widget.TextView;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
private TextView tvhello;
private ArrayList<PlanetsItem> mPlanetList;
private MyAdapter mAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initList();
tvhello= (TextView) findViewById(R.id.hello);
Spinner spinner = (Spinner) findViewById(R.id.spinner);
mAdapter = new MyAdapter(this, mPlanetList);
spinner.setAdapter(mAdapter);
spinner.setSelection(2, false);
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
PlanetsItem clickedItem = (PlanetsItem) parent.getItemAtPosition(position);
String clickedPlanetName = clickedItem.getPlanetName();
tvhello.setText(clickedPlanetName);
String sPos=String.valueOf(position);
tvhello.setText("選項"+sPos+":"+clickedPlanetName);
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
}
private void initList() {
mPlanetList = new ArrayList<>();
mPlanetList.add(new PlanetsItem("Mercury", R.drawable.mercury));
mPlanetList.add(new PlanetsItem("Venus", R.drawable.venus));
mPlanetList.add(new PlanetsItem("Earth", R.drawable.earth));
mPlanetList.add(new PlanetsItem("Mars", R.drawable.mars));
mPlanetList.add(new PlanetsItem("Jupiter", R.drawable.jupiter));
mPlanetList.add(new PlanetsItem("Saturn", R.drawable.saturn));
mPlanetList.add(new PlanetsItem("Uranus", R.drawable.uranus));
mPlanetList.add(new PlanetsItem("Neptune", R.drawable.neptune));
}
}
|
從基礎到進階下拉式選單(Spinner)筆記請參考:[Android Studio]下拉式選單(Spinner)筆記@ KOEI的旅行
