
[Android]値を変えたらそのまま保存、色選択プリファレンスアクティビティ#tryCustomListPreference00

PreferenceActivityのListPreferenceをカスタマイズする
普通はテキストの選択だけだけど、色をとかを選択する時があるので文字列の下に色のサンプルが表示されるようにする。
選択後に戻ったPreferenceActivityでも、選択された色が表示されているようにする
検索した事
android PreferenceActivity ListPreference
ListPreference カスタマイズ
ListPreference 色
preference widgetLayout
開発環境
Eclipse IDE バージョン: 4.2.1
PreferenceActivityに飛ぶだけで特に何もしない
package com.example.trycustomlistpreference00; import android.os.Bundle; import android.preference.ListPreference; import android.app.Activity; import android.app.AlertDialog.Builder; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences.Editor; import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.Menu; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.ListAdapter; import android.widget.RadioButton; import android.widget.TextView; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 設定のアクティビティに飛ばす Intent intent = new Intent(this, PrefActivity.class); this.startActivity(intent); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.activity_main, menu); return true; } }
色選択用のカスタムアダプタや、それ専用のListPreference
package com.example.trycustomlistpreference00; import java.util.Random; import android.app.Activity; import android.app.AlertDialog.Builder; import android.content.Context; import android.content.SharedPreferences; import android.content.SharedPreferences.Editor; import android.content.SharedPreferences.OnSharedPreferenceChangeListener; import android.graphics.Color; import android.os.Bundle; import android.preference.ListPreference; import android.preference.PreferenceActivity; import android.text.SpannableString; import android.text.SpannedString; import android.text.style.BackgroundColorSpan; import android.text.style.RelativeSizeSpan; import android.util.AttributeSet; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.View.OnClickListener; import android.widget.ArrayAdapter; import android.widget.ListAdapter; import android.widget.RadioButton; import android.widget.TextView; // ______________________________________________________________________________ public class PrefActivity extends PreferenceActivity implements OnSharedPreferenceChangeListener { private static int PREFS = R.xml.prefs; // レイアウト // ______________________________________________________________________________ @SuppressWarnings("deprecation") @Override // アクティビティ作成時の呼び出し protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // XMLからメニューを作る addPreferencesFromResource(PREFS); } // ______________________________________________________________________________ @SuppressWarnings("deprecation") @Override // アクティビティの再開 protected void onResume() { super.onResume(); // プリファレンスの変更の通知リスナーを埋め込む this.getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this); } // ______________________________________________________________________________ @Override // アクティビティの停止 protected void onPause() { super.onPause(); // プリファレンスの変更の通知リスナーをはずす this.getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this); } // ______________________________________________________________________________ @SuppressWarnings("deprecation") @Override // 設定が変更された時に呼び出される public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { // カラーが変更されている if (this.getString(R.string.pref_key_color).equals(key) == true) { // プリファレンスから値を取り出す String value = sharedPreferences.getString(key, "0"); // セレクタからプリファレンスを取り出す ColorSelector pref = (ColorSelector)this.findPreference(this.getString(R.string.pref_key_color)); // 表示を切り替える // ※これをすることでListPreference内のonBindViewが呼ばれてビューの更新がされる SpannableString summary = new SpannableString("選択された色(#" + String.format("%x", Integer.parseInt(value)) + ")"); pref.setSummary(summary); //pref.setI } } } //______________________________________________________________________________ /** * 色選択用のListPreference * */ class ColorSelector extends ListPreference { private static final String TAG = "ColorSelector#"; // ______________________________________________________________________________ /** * コンストラクタ * @param context コンテキスt * @param attrs アトリビュートセット */ public ColorSelector(Context context, AttributeSet attrs) { super(context, attrs); } // ______________________________________________________________________________ @Override // ダイアログを作る奴 protected void onPrepareDialogBuilder(Builder builder) { // プリファレンスから値を取り出す String value = this.getSharedPreferences().getString(this.getKey(), "0x00ffffff"); // これを使うと完全に中の値が一致しないとだめなので、自分で登録されている値を // 調べながら選択されているものを探し出す。 //int index = this.findIndexOfValue(value); CharSequence[] values = this.getEntryValues(); // リストに登録されている項目 int selItem = -1; // 登録されているアイテムリストから今選択されているものを呼び出す for (int i = 0; i < values.length; i++) { // 登録されている値と、選択されている値が同じとき if (ColorSelectorAdapter.getColor((String)values[i]) == Integer.parseInt(value)) { // 選択されている項目のインデックス発見! selItem = i; break; } } Log.i(TAG + "onPrepareDialogBuilder", "index: " + selItem + " val: " + value); // リストアダプターを作る ListAdapter la = (ListAdapter)new ColorSelectorAdapter(this.getContext(), R.layout.custom_row, this.getEntryValues(), selItem, this); // リストアダプターをセットする builder.setAdapter(la, this); super.onPrepareDialogBuilder(builder); } // ______________________________________________________________________________ /** * 値を取り出す * @param selectedItemValue 選択された値 */ public void setResult(int selectedItemValue) { // これでTrueになった時だけ処理するようにする(onPreferenceChangeを受けるため) if (this.callChangeListener("" + selectedItemValue)) { // 値プリファレンスにを保存する this.saveToPreference(selectedItemValue); } // ダイアログを閉じる this.getDialog().dismiss(); } // ______________________________________________________________________________ /** * プリファレンスに保存する * @param color */ private void saveToPreference(int color) { // Preferenceの名前を取り出す String prefName = this.getPreferenceManager().getSharedPreferencesName(); // Preferenceの値を更新する Editor edit = this.getContext().getSharedPreferences(prefName, 0).edit(); edit.putString(this.getKey(), "" + color); edit.commit(); Log.i(TAG + "setResult", "color: " + color); } // ______________________________________________________________________________ @Override // PreferenceActivityの項目の表示の切替(右側にでるカラーサンプル) protected void onBindView(View view) { super.onBindView(view); // プリファレンスから色を取り出す int color = Integer.parseInt(this.getSharedPreferences().getString(this.getKey(), "0x00ffffff")); // カラーサンプルの色を設定する View v = view.findViewById(R.id.color_sample); v.setBackgroundColor(color); Log.i(TAG + "onBindView", "color: " + color); } } //______________________________________________________________________________ /** * 色選択用のアダプタ * */ class ColorSelectorAdapter extends ArrayAdapter<CharSequence> implements OnClickListener { private static final String TAG = "ColorSelectorAdapter#"; private int mSelectedItem; // 選択されている項目 private ColorSelector mSelector; // セレクター // ______________________________________________________________________________ /** * コンストラクタ * @param context コンテキスト * @param rowResourceId 項目のリソースID * @param objects 各項目に設定する値 * @param selectedItem 最初から選択されているもの * @param cs カラー選択のListPreference */ public ColorSelectorAdapter(Context context, int rowResourceId, CharSequence[] objects, int selectedItem, ColorSelector cs) { super(context, rowResourceId, objects); this.mSelectedItem = selectedItem; this.mSelector = cs; } // ______________________________________________________________________________ /** * 文字列からINT型の色へ変換 * @param col "0xff00ffff"みたいな色の文字列 * @return Int型に変換された色 */ public static int getColor(String col) { int res = 0; // 全部小文字 String tmp = col.toLowerCase(); // 最初の0xがある時は取り除く if (tmp.charAt(0) == '0' && tmp.charAt(1) == 'x') { tmp = tmp.substring(2); } // aarrggbb形式 if (tmp.length() == 8) { res = StrToHex(tmp.substring(0, 2)) << 24 | StrToHex(tmp.substring(2, 4)) << 16 | StrToHex(tmp.substring(4, 6)) << 8 | StrToHex(tmp.substring(6, 8)); // rrggbb形式 } else if (tmp.length() == 6) { res = 0xff000000 | StrToHex(tmp.substring(0, 2)) << 16 | StrToHex(tmp.substring(2, 4)) << 8 | StrToHex(tmp.substring(4, 6)); } return res; } // ______________________________________________________________________________ /** * 文字列2桁から16進数の数値へ変換 * @param xx a0とかffとか2桁の文字列 * @return 変換された数値(ミスったら0が返る) */ public static int StrToHex(String xx) { int res = 0; try { // 16進の数値に変換 res = Integer.parseInt(xx, 16); } catch (Exception e) { e.printStackTrace(); res = 0; } return res; } // ______________________________________________________________________________ @Override // ビュー作るときに呼ばれる public View getView(int position, View convertView, ViewGroup parent) { CharSequence colorId = this.getItem(position); // 行を作る LayoutInflater inflater = ((Activity)this.getContext()).getLayoutInflater(); View row = inflater.inflate(R.layout.custom_row, parent, false); // 設定する色を取り出す int color = ColorSelectorAdapter.getColor(colorId.toString()); row.setId(color); // クリックリスナーをセット row.setOnClickListener(this); // タイトルを設定する TextView tv = (TextView)row.findViewById(R.id.row_color_title); tv.setText(colorId); tv.setTextColor(color); // チェックボックスのセット RadioButton rb = (RadioButton)row.findViewById(R.id.row_check); // 選択されているものをチェックを入れる if (position == this.mSelectedItem) { rb.setChecked(true); } // クリックイベントに反応しないようにする rb.setClickable(false); // サンプル表示用ビューに色をセットする View view = row.findViewById(R.id.row_color_sample); view.setBackgroundColor(color); return row; } // ______________________________________________________________________________ @Override // なんかクリックされた時に呼ばれる public void onClick(View view) { // 結果をListPreferenceに通知 this.mSelector.setResult(view.getId()); } }
xml/prefs.xmlから呼び出される。
サンプル色を表示するところ。
<?xml version="1.0" encoding="utf-8"?> <View xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/color_sample" android:layout_width="50dp" android:layout_height="50dp" android:background="#ff00ff00" > </View>
色を選択するためのチェックリストの内容
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <LinearLayout android:layout_width="234dp" android:layout_height="wrap_content" android:layout_weight="1" android:orientation="vertical" > <TextView android:id="@+id/row_color_title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="5dp" android:layout_marginTop="5dp" android:text="#ff00ff00" android:textAppearance="?android:attr/textAppearanceLarge" /> <View android:id="@+id/row_color_sample" android:layout_width="wrap_content" android:layout_height="30dp" /> </LinearLayout> <RadioButton android:id="@+id/row_check" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" /> </LinearLayout>
PreferenceActivityの本体
この中で項目を定義する
<?xml version="1.0" encoding="utf-8"?> <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" > <PreferenceCategory android:title="タイトル"> <com.example.trycustomlistpreference00.ColorSelector android:key="@string/pref_key_color" android:title="色の選択" android:summary="選択した色はこれ→" android:dialogTitle="色を選択する" android:defaultValue="0" android:entries="@array/color_title_array" android:entryValues="@array/color_array" android:widgetLayout="@layout/color_sample"/> </PreferenceCategory> </PreferenceScreen>
[Android]リストビューのヘッダー/フッターにボタンを置く方法のサンプル#... [Android]スクラッチのように画面をこすると下の画像が浮き出てくるサンプ...