SQLの窓

2016年05月21日


Android の Spinner に関するいろいろな実装と知識 / Android Studio

Android の Spinner は、一般的にはコンボボックスと言われるものと同様で、何も指定しなければ以下のような動作をします。



Spinner には、spinnerMode というプロパティがあり、デフォルトでは MODE_DROPDOWN として動作しています。( XML で定義せずに、インスタンスを作成する場合は、コンストラクタで指定できます )



この部分を MODE_DIALOG に変更すると、以下のように動作します



リスト部分の実装について

リスト部分は、一般的なリストビューと同じです。ArrayAdapter を使用します。単純に一つの TextView を持つ、Android で定義済みの simple_spinner_dropdown_item を使って実装しています。( simple_spinner_dropdown_item である必要はありません )
package lightbox.may.combobox;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.Spinner;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

	// ******************************
	// 文字列配列 Spinner
	// ******************************
	private ArrayAdapter<String> adapter;
	private Spinner spinner;
	private String[] list_data = {"大阪","東京","愛知","岡山"};
	private String[] list_value = {"27","13","23","33"};

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		// 配列を格納して Android のリストを表示する ArrayAdapter クラス
		// レイアウトは Android で定義されたもの。
		// TextView を継承したクラスであれば自前のレイアウトで OK
		adapter = new ArrayAdapter(
			MainActivity.this,
			android.R.layout.simple_spinner_dropdown_item);

		// Spinner のインスタンスを取得
		spinner = (Spinner) MainActivity.this.findViewById(R.id.spinner);

		// ArrayAdapter に配列を格納
		adapter.addAll(list_data);

		// Spinner に ArrayAdapter をセット
		spinner.setAdapter(adapter);

		// ボタンの インスタンスを取得
		Button button = (Button) MainActivity.this.findViewById(R.id.button);
		// アルファベットの小文字を反映できるようにする
		button.setAllCaps(false);
		// ボタンのイベントの定義
		button.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {

				// ******************************************
				// Spinner より選択されているテキストを取得
				// ******************************************

				// simple_spinner_dropdown_item に定義されている id から
				String text = ((TextView)(MainActivity.this.findViewById(android.R.id.text1))).getText().toString();
				Log.i("lightbox", text);

				// sppiner から
				text = (String) spinner.getSelectedItem();
				Log.i("lightbox", text);

				// ポジション番号から、用意しておいた配列を使用して取り出す
				int pos = spinner.getSelectedItemPosition();
				Log.i("lightbox", list_data[pos]);

			}
		});


	}
}

Spinner とは関係ありませんが、setAllCaps でボタンの文字が全て大文字にならないようにしています。

Spinner の情報の取り出し

ここでは、Spinner に表示されるテキストを取り出しています。しかし、実際は Spinner の選択 されたインデックスより、テキストの元となるコードを list_value より取り出すのが正解です。ですが、これは最も簡単なサンプルとして、ArrayAdapter に 文字列の配列を引き渡しているからそうなるのであって、本来は専用クラスを作成し、その配列を最初に渡しておいて、その中の値を直接取り出すのが汎用的になります。

Spinner 用のクラスを作成して利用する
package lightbox.may.combobox;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.Spinner;

public class MainActivity extends AppCompatActivity {

	// ******************************
	// MyData 配列 Spinner
	// ******************************
	private ArrayAdapter<MyData> adapter;

	// セットする情報の配列
	private MyData[] my_data = {
		new MyData("大阪","27"),
		new MyData("東京","13"),
		new MyData("愛知","23"),
		new MyData("岡山","33")} ;

	// Spinner のインスタンス
	private Spinner spinner;

	// 情報格納用のクラス
	private class MyData {
		// 表示される文字列用
		private String myString = null;
		// 内部コード
		private String myValue = null;

		// コンストラクタ
		public MyData(String myString,String myValue) {
			this.myString = myString;
			this.myValue = myValue;
		}

		// 値取得用
		String getValue() {
			return myValue;
		}

		// ArrayAdapter の仕様に合わせて toString を 上書きしておく
		@Override
		public String toString() {
			return myString;
		}
	}

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		// 配列を格納して Android のリストを表示する ArrayAdapter クラス
		// レイアウトは Android で定義されたもの。
		// TextView を継承したクラスであれば自前のレイアウトで OK
		adapter = new ArrayAdapter(
			MainActivity.this,
			android.R.layout.simple_spinner_dropdown_item);

		// Spinner のインスタンスを取得
		spinner = (Spinner) MainActivity.this.findViewById(R.id.spinner);

		// ArrayAdapter に MyData 配列を格納
		adapter.addAll(my_data);

		// Spinner に ArrayAdapter をセット
		spinner.setAdapter(adapter);

		// ボタンの インスタンスを取得
		Button button = (Button) MainActivity.this.findViewById(R.id.button);
		// アルファベットの小文字を反映できるようにする
		button.setAllCaps(false);
		// ボタンのイベントの定義
		button.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {

				// ******************************************
				// Spinner より選択されている情報を取得
				// ******************************************
				// sppiner から MyData を取得
				MyData md = (MyData) spinner.getSelectedItem();
				// 内部コードの取得
				Log.i("lightbox", md.getValue());
				// テキストの取得
				Log.i("lightbox", md.toString());

			}
		});


	}
}

データをセットするのに、addAll を使用しているのは、インターネット経由で JSON を使用して読み込む事が通常想定されるので、一括となっています。

リストの行の表示のカスタマイズ

これらのサンプルでは、画面定義は simple_spinner_dropdown_item を使用していますが、単純に TextView のみの画面定義をして利用可能です。


<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:textSize="40dp"
          android:padding="10dp">

</TextView>

完全にカスタマイズするには

Spinner の見え方は、閉じた一つの View と リストで表示されるビューと二つあります。また、二つ以上のコントロールのある View を作った場合は ArrayAdapter を継承したクラスを作成して利用する必要があります。それらの機能を汎用的に実装したのが以下の SpinnerArrayAdapter です。
package lightbox.may.combobox;

import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;

/**
 * Created by lightbox on 2016/05/21.
 */
public class SpinnerArrayAdapter<T> extends ArrayAdapter<T> {

	public interface OnGetViewListener {
		abstract public View onGetViewListener(int position, View convertView, ViewGroup parent);
	}

	private OnGetViewListener listener = null;
	private OnGetViewListener listener_drop_down = null;

	public SpinnerArrayAdapter(Context context, int resource, OnGetViewListener listener, OnGetViewListener listener_drop_down) {
		super(context, resource);
		this.listener = listener;
		this.listener_drop_down = listener_drop_down;
	}

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		if ( listener != null ) {
			return listener.onGetViewListener(position, convertView, parent);
		}
		return super.getView(position, convertView, parent);
	}

	@Override
	public View getDropDownView(int position, View convertView, ViewGroup parent) {
		if ( listener != null ) {
			return listener_drop_down.onGetViewListener(position, convertView, parent);
		}
		return super.getDropDownView(position, convertView, parent);
	}
}


画面定義 / my_spinner_custom
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="match_parent"
              android:layout_height="match_parent">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/textView"
        android:textSize="40dp"
        android:padding="10dp"/>

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/textView2"
        android:textSize="20dp"
        android:padding="5dp"/>
</LinearLayout>



使用方法
package lightbox.may.combobox;

import android.content.Context;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.Spinner;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

	// ******************************
	// MyData 配列 Spinner
	// ******************************
	private SpinnerArrayAdapter <MyData> adapter;

	// セットする情報の配列
	private MyData[] my_data = {
		new MyData("大阪","27"),
		new MyData("東京","13"),
		new MyData("愛知","23"),
		new MyData("岡山","33")} ;

	// Spinner のインスタンス
	private Spinner spinner;

	// 情報格納用のクラス
	private class MyData {
		// 表示される文字列用
		private String myString = null;
		// 内部コード
		private String myValue = null;

		// コンストラクタ
		public MyData(String myString,String myValue) {
			this.myString = myString;
			this.myValue = myValue;
		}

		// 値取得用
		String getValue() {
			return myValue;
		}

		// ArrayAdapter の仕様に合わせて toString を 上書きしておく
		@Override
		public String toString() {
			return myString;
		}
	}

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		// my_spinner_custom を使用したカスタマイズ
		adapter = new SpinnerArrayAdapter<MyData>(
			MainActivity.this,
			R.layout.my_spinner_custom,
			// リストでは無い表示部分
			new SpinnerArrayAdapter.OnGetViewListener() {
				@Override
				public View onGetViewListener(int position, View convertView, ViewGroup parent) {

					View rowView = convertView;
					if (rowView == null) {
						// 現在の View の取得
						LayoutInflater inflater = (LayoutInflater) MainActivity.this.getSystemService
							(Context.LAYOUT_INFLATER_SERVICE);
						rowView = inflater.inflate(R.layout.my_spinner_custom, null);
					}

					// Adapter にセットされているこのポジションの MyData を取得
					MyData md = adapter.getItem(position);

					// my_spinner_custom 内の TextView にデータをセット
					TextView tv1 = (TextView) rowView.findViewById(R.id.textView);
					tv1.setText(md.toString());
					TextView tv2 = (TextView) rowView.findViewById(R.id.textView2);
					tv2.setText(md.getValue());

					return rowView;
				}
			},
			// リストの表示部分
			new SpinnerArrayAdapter.OnGetViewListener() {
				@Override
				public View onGetViewListener(int position, View convertView, ViewGroup parent) {
					View rowView = convertView;
					if (rowView == null) {
						// 現在の View の取得
						LayoutInflater inflater = (LayoutInflater) MainActivity.this.getSystemService
							(Context.LAYOUT_INFLATER_SERVICE);
						rowView = inflater.inflate(R.layout.my_spinner_custom, null);
					}

					// Adapter にセットされているこのポジションの MyData を取得
					MyData md = adapter.getItem(position);

					// my_spinner_custom 内の TextView にデータをセット
					TextView tv1 = (TextView) rowView.findViewById(R.id.textView);
					tv1.setText(md.toString());
					TextView tv2 = (TextView) rowView.findViewById(R.id.textView2);
					tv2.setText(md.getValue());

					return rowView;
				}
		});

		// Spinner のインスタンスを取得
		spinner = (Spinner) MainActivity.this.findViewById(R.id.spinner);

		// ArrayAdapter に MyData 配列を格納
		adapter.addAll(my_data);

		// Spinner に ArrayAdapter をセット
		spinner.setAdapter(adapter);

		// ボタンの インスタンスを取得
		Button button = (Button) MainActivity.this.findViewById(R.id.button);
		// アルファベットの小文字を反映できるようにする
		button.setAllCaps(false);
		// ボタンのイベントの定義
		button.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {

				// ******************************************
				// Spinner より選択されている情報を取得
				// ******************************************
				// sppiner から MyData を取得
				MyData md = (MyData) spinner.getSelectedItem();
				// 内部コードの取得
				Log.i("lightbox", md.getValue());
				// テキストの取得
				Log.i("lightbox", md.toString());

			}
		});


	}
}


関連するソースコード

ArrayAdapter

simple_spinner_dropdown_item.xml



【2 Android Studioの最新記事】
posted by lightbox at 2016-05-21 18:28 | 2 Android Studio | このブログの読者になる | 更新情報をチェックする
container 終わり

フリーフォントで簡単ロゴ作成
フリーフォントでボタン素材作成
フリーフォントで吹き出し画像作成
フリーフォントではんこ画像作成
ほぼ自由に利用できるフリーフォント
フリーフォントの書体見本とサンプル
画像を大きく見る為のウインドウを開くボタンの作成

CSS ドロップシャドウの参考デモ
BUTTONS (CSS でボタン)
イラストAC
ぱくたそ
写真素材 足成
フリーフォント一覧
utf8 文字ツール
右サイド 終わり
base 終わり