[解決済み] 初期テキストが「Select One」のAndroidスピナーを作るには?
質問
スピナーを使いたいのですが、初期状態(ユーザーがまだ選択していない状態)では、"Select One"というテキストが表示されます。ユーザーがスピナーをクリックすると、項目のリストが表示され、ユーザーは選択肢の中から一つを選択します。ユーザーが選択した後は、"Select One"の代わりに選択された項目がSpinnerに表示されます。
Spinnerを作成するために以下のコードを用意しました。
String[] items = new String[] {"One", "Two", "Three"};
Spinner spinner = (Spinner) findViewById(R.id.mySpinner);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_spinner_item, items);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
このコードでは、初期状態では、項目 "One" が表示されています。新しい項目 "Select One" を項目に追加すればいいのですが、そうすると "Select One" も最初の項目としてドロップダウンリストに表示されてしまい、これは私が望んでいるものではありません。
どうすればこの問題を解決できますか?
解決方法は?
をオーバーライドする一般的な解決策を紹介します。
Spinner
ビューを表示します。これは
setAdapter()
を使用して初期位置を -1 に設定し、提供された
SpinnerAdapter
を使用して、0 未満の位置でプロンプト文字列を表示する。
Android 1.5から4.2まででテストしていますが、買い手は要注意です! この解決策はリフレクションに依存しているため、プライベートな
AdapterView.setNextSelectedPositionInt()
と
AdapterView.setSelectedPositionInt()
将来のOSアップデートでの動作は保証されていません。動作する可能性は高いと思われますが、決して保証されているわけではありません。
通常、私はこのようなことを容認しませんが、この質問は何度もされており、十分に合理的な要求であると思われるので、私の解決策を投稿しようと思いました。
/**
* A modified Spinner that doesn't automatically select the first entry in the list.
*
* Shows the prompt if nothing is selected.
*
* Limitations: does not display prompt if the entry list is empty.
*/
public class NoDefaultSpinner extends Spinner {
public NoDefaultSpinner(Context context) {
super(context);
}
public NoDefaultSpinner(Context context, AttributeSet attrs) {
super(context, attrs);
}
public NoDefaultSpinner(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public void setAdapter(SpinnerAdapter orig ) {
final SpinnerAdapter adapter = newProxy(orig);
super.setAdapter(adapter);
try {
final Method m = AdapterView.class.getDeclaredMethod(
"setNextSelectedPositionInt",int.class);
m.setAccessible(true);
m.invoke(this,-1);
final Method n = AdapterView.class.getDeclaredMethod(
"setSelectedPositionInt",int.class);
n.setAccessible(true);
n.invoke(this,-1);
}
catch( Exception e ) {
throw new RuntimeException(e);
}
}
protected SpinnerAdapter newProxy(SpinnerAdapter obj) {
return (SpinnerAdapter) java.lang.reflect.Proxy.newProxyInstance(
obj.getClass().getClassLoader(),
new Class[]{SpinnerAdapter.class},
new SpinnerAdapterProxy(obj));
}
/**
* Intercepts getView() to display the prompt if position < 0
*/
protected class SpinnerAdapterProxy implements InvocationHandler {
protected SpinnerAdapter obj;
protected Method getView;
protected SpinnerAdapterProxy(SpinnerAdapter obj) {
this.obj = obj;
try {
this.getView = SpinnerAdapter.class.getMethod(
"getView",int.class,View.class,ViewGroup.class);
}
catch( Exception e ) {
throw new RuntimeException(e);
}
}
public Object invoke(Object proxy, Method m, Object[] args) throws Throwable {
try {
return m.equals(getView) &&
(Integer)(args[0])<0 ?
getView((Integer)args[0],(View)args[1],(ViewGroup)args[2]) :
m.invoke(obj, args);
}
catch (InvocationTargetException e) {
throw e.getTargetException();
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
protected View getView(int position, View convertView, ViewGroup parent)
throws IllegalAccessException {
if( position<0 ) {
final TextView v =
(TextView) ((LayoutInflater)getContext().getSystemService(
Context.LAYOUT_INFLATER_SERVICE)).inflate(
android.R.layout.simple_spinner_item,parent,false);
v.setText(getPrompt());
return v;
}
return obj.getView(position,convertView,parent);
}
}
}
関連
-
[解決済み] TextViewでテキストを水平・垂直方向にセンタリングするには?
-
cygwinのダウンロード、インストールチュートリアル、およびCDTの「makeプログラムがパスに見つからない」バグの解消
-
問題 ---- Android ---- ActivityManager: Error: アクティビティクラス{xx/xx.MainActivity}が存在しない
-
Android--shape--描画のコーナー、グラデーション、パディング、サイズ、ソリッド、ストロークのプロパティを指定する。
-
Android TextViewは、テキスト内容が表示省略記号を超えているかどうかを判断する
-
android.content.ActivityNotFoundException を解決します。Intent問題を処理するActivityが見つからない
-
[解決済み] Androidのソフトキーボードをプログラムで閉じる/隠すにはどうすればよいですか?
-
[解決済み] Androidでアクティビティ起動時にEditTextにフォーカスが当たらないようにする方法
-
[解決済み] Bitmapオブジェクトに画像を読み込む際にOutOfMemoryが発生する問題
-
[解決済み] Android: スピナーをカスタムオブジェクトリストにバインドする方法は?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
java.lang.NullPointerException: NULLオブジェクト参照で仮想メソッド......を呼び出そうとしました。
-
[android studio]com.android.ide.common.process.ProcessException: aaptの実行に失敗しました
-
Android Studio を 3.6.3 にアップデートした後、構成 :classpath のアーティファクトをすべて解決できない。
-
アプリはGoogle検索でインデックスされません Androidmanifestのクソみたいな黄色い警告
-
telnet'が内部コマンドまたは外部コマンドとして認識されない 解決方法
-
エラー:未宣言の識別子(AS)の使用
-
アンドロイドのエリプサイズを使用する
-
Android ProgressBarの色を変更する
-
Androidの美しいSeekBarスタイルのカスタマイズ
-
android studioが新しいプロジェクトを作成しますが、プロジェクトの同期に成功するまでデザインエディタが使用できません。