アプリケーション設定のSeekBar



Androidには、CheckBoxPreference、EditTextPreference、ListPreferenceなどの設定画面を作成するための非常に便利なウィジェットのセットが用意されています。 何らかの理由で既存のウィジェットが要件を満たしていない場合は、既存のウィジェットに基づいて独自のウィジェットを作成できます。

明るさ、音量など、1つまたは別の整数設定に合理的な制限がある場合がよくあります。 この場合、独自のウィジェットを作成してアプリケーションで再利用するのが理にかなっています。

準備する

DialogPreferenceクラスを基礎としてみましょう-設定画面に2行の要素を表示し、押されたときにダイアログを開くウィジェットの基本クラスです。



このクラスをSeekBarPreferenceと呼びます。 パラメータは最小値、最大値、および現在のデフォルト値になり、指定されたキーによって関連するアプリケーション設定から実際の現在値を取得します。

次に、設定マークアップを含む/res/xml/preferences.xmlファイルは次のようになります。

<?xml version="1.0" encoding="utf-8"?> <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" xmlns:example="http://schemas.android.com/apk/res/com.mnm.seekbarpreference"> <com.mnm.seekbarpreference.SeekBarPreference android:key="seekBarPreference" android:title="@string/dialog_title" android:dialogTitle="@string/dialog_title" android:summary="@string/summary" android:persistent="true" android:defaultValue="20" example:minValue="10" example:maxValue="50" /> </PreferenceScreen> 

既存のタグを使用してデフォルト値を設定できますが、最小値と最大値については独自のタグを作成する必要があります。 これを行うには、属性の説明を/res/values/attrs.xmlファイルに追加します。

 <?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="com.mnm.seekbarpreference.SeekBarPreference"> <attr name="minValue" format="integer" /> <attr name="maxValue" format="integer" /> </declare-styleable> </resources> 

<declare-styleable>タグのname属性には、ウィジェットの修飾クラス名が含まれている必要があります。

同じ名前で、より完全な形式( schemas.android.com/apk/res/qualified_class_name )のみが、追加のネームスペースとして設定ファイルのマークアップに示される必要があります(上記を参照)。

xmlを使用する最後の手順は、ウィジェットをクリックして呼び出されるダイアログのマークアップを作成することです。 マークアップコードは珍しいものではないため、結果なしで省略できます。 最小値、最大値、現在値、そして実際にはSeekBarのTextViewが含まれています。

これで、SeekBarPreferenceクラスの実装を続行できます。

実装

まず、コンストラクターの属性から指定された値を読み取る必要があります。

 mMinValue = attrs.getAttributeIntValue(PREFERENCE_NS, ATTR_MIN_VALUE, DEFAULT_MIN_VALUE); mMaxValue = attrs.getAttributeIntValue(PREFERENCE_NS, ATTR_MAX_VALUE, DEFAULT_MAX_VALUE); mDefaultValue = attrs.getAttributeIntValue(ANDROID_NS, ATTR_DEFAULT_VALUE, DEFAULT_CURRENT_VALUE); 

ここで、定数は名前空間の名前、属性、および最小値、最大値、およびデフォルト値のデフォルト値です(マークアップで指定されていない場合)。

 private static final String PREFERENCE_NS = "http://schemas.android.com/apk/res/com.mnm.seekbarpreference"; private static final String ANDROID_NS = "http://schemas.android.com/apk/res/android"; private static final String ATTR_DEFAULT_VALUE = "defaultValue"; private static final String ATTR_MIN_VALUE = "minValue"; private static final String ATTR_MAX_VALUE = "maxValue"; 

ダイアログを初期化するには、onCreateDialogViewメソッドを実装します。

 @Override protected View onCreateDialogView() { //     mCurrentValue = getPersistedInt(mDefaultValue); //   LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); View view = inflater.inflate(R.layout.dialog_slider, null); //     ((TextView) view.findViewById(R.id.min_value)).setText(Integer.toString(mMinValue)); ((TextView) view.findViewById(R.id.max_value)).setText(Integer.toString(mMaxValue)); //  SeekBar mSeekBar = (SeekBar) view.findViewById(R.id.seek_bar); mSeekBar.setMax(mMaxValue - mMinValue); mSeekBar.setProgress(mCurrentValue - mMinValue); mSeekBar.setOnSeekBarChangeListener(this); //    mValueText = (TextView) view.findViewById(R.id.current_value); mValueText.setText(Integer.toString(mCurrentValue)); return view; } 

値は、ウィジェットのpreference.xmlで指定されたキーによって読み取られます。 SeekBarを設定するときは、SeekBarの最小値が常に0であることを考慮する必要があるため、最小値がゼロ以外の場合は減算する必要があります。 ちなみに、このコードは、非負の数値、および最大値が最小値より大きい場合にのみ有効です。

その後、アプリケーションをすでに起動してスライダーを移動できますが、変更を処理する必要があるため、現在の値のテキストは変更されません。

これを行うには、SeekBarPreferenceのOnSeekBarChangeListenerインターフェイスを実装します。 上記のコードでは、 mSeekBar.setOnSeekBarChangeListener(this)へのリンクがこのインターフェイスに渡されます。 実装する必要があるのは、次の3つの方法のうち1つだけです。

 public void onProgressChanged(SeekBar seek, int value, boolean fromTouch) { mCurrentValue = value + mMinValue; mValueText.setText(Integer.toString(mCurrentValue)); } 

また、SeekBarの最小値はゼロであるため、加算を適用する必要があります。

次のステップは、結果の値を保存することです。 変更を適用またはキャンセルすると、 onDialogClosedメソッドがonDialogClosedます。これはオーバーライドする必要があります。

 @Override protected void onDialogClosed(boolean positiveResult) { super.onDialogClosed(positiveResult); if (!positiveResult) { return; } if (shouldPersist()) { persistInt(mCurrentValue); } notifyChanged(); } 

正の場合、現在の値が保存されます。 check shouldPersist()は、これを行う必要があるかどうかを分析します。 これは、 preferences.xmlで指定されたandroid:persistentフラグをチェックします

最後の行はちょっとしたトリックに必要です。 実際には、デフォルトではウィジェットの2行目( summary )は動的ではないため、現在の値を表示する場合は、次の行を追加する必要があります。

 @Override public CharSequence getSummary() { String summary = super.getSummary().toString(); int value = getPersistedInt(mDefaultValue); return String.format(summary, value); } 

ここで、 summaryを照会すると、元の文字列は現在の値が置換されるテンプレートとして機能します。 これは、設定画面を開いたときにうまく機能します。 ただし、値を変更した後にこのコードを機能させるには、 notifyChanged()を呼び出す必要があります。

結果

結果のウィジェットは、幅広い設定に適用するのに適しており、既存のウィジェットをエレガントに補完します。 ダイナミックラインサマリーアプローチは、他のタイプの設定で使用できます。

参照資料

ドラフト例を使用したアーカイブ
SeekBarの説明(en)
DialogPreferenceの説明(en)

Source: https://habr.com/ru/post/J114733/


All Articles