[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的旅行
留言列表