close

[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初始畫面結果如下:

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架構:

spinner

 

客製化選單步驟:

步驟1:新增Project

先在Android Studio新增project,點選File>New>New Project,種類選擇[Empty Activity],名稱設為MySpinner1,完成新增project。

將需要的圖示檔和圖檔全部複製到app\src\main\res\drawable目錄下。

選左方 Resource Manager,可看到上述的下拉圖示、下載的行星圖檔及系統預設背景。

Spinner

 

步驟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的背景。

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

 

完整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的旅行

 

arrow
arrow

    KOEI 發表在 痞客邦 留言(0) 人氣()