Preference Support Library の試行錯誤メモ

何で導入しようと思ったか

根本解決ではない。

  • で一番うるさくない方法が

    • AppCompat + PreferenceFragment
    • AppCompat + PreferenceFragmentCompat
  • onAttachの件

onAttach何に使うの? という話題自体出てきそうですけど

Activityへのリスナーはこのタイミングで設定するのがお作法らしい

導入編辺り

dependencies {
    compile 'com.android.support:preference-v7:24.1.+'
}

を追加して使う

  • values/style.xml
<style name="AppTheme" parent="Theme:AppCompat.Light">
    <!-- Customize your theme here. -->
    <item name="preferenceTheme">@style/PreferenceThemeOverlay</item>
</style>

style.xmlの定義がないとビルド失敗しよる。。

ただ色合い調整するなら、PreferenceThemeOverlayを上書きして色調整の必要があり

に詳細が乗ってる

ただ従来通りのXMLがそのまま使えるのは楽。

public class SettingsFragment extends PreferenceFragment

  @Override
    public void onCreate(Bundle bundle) {
        //add xml
        addPreferencesFromResource(R.xml.preferences);

=>

public class SettingsFragment extends PreferenceFragmentCompat

  @Override
    public void onCreatePreferences(Bundle bundle, String s) {
        //add xml
        addPreferencesFromResource(R.xml.preferences);

導入編辺り (StackOverFlowによるスタイル崩れ修正方法)

  • これG様が
    • support-v7 のスタイルを修正してくれなくて
    • issueで質問したら => support-v14 のスタイル使えばいいじゃんと回答
    • それでも治ってないから有志の方がレイアウト直したの作ってますよ//<= 今ココ

というひどい状況らしい。はーと思わず溜息ついてしまいますね。

  • app/build.gradle
dependencies {
    compile 'com.android.support:preference-v7:24.1.+'
    compile 'com.android.support:preference-v14:24.1.+'
    compile 'com.android.support:recyclerview-v7:24.1.+' //★
}

ちなみに、★のrecyclerview 記述が必要なのは

  • preference-v14 が内部で使ってるらしい
  • 内部のdependency参照が糞だから
    • classpath上にない=>jcenterから落としてこようとする
    • =>Jcenterに勿論そんなものは無い=>エラー*1
    • 何のためにSDKの中にmvnrepo持たせているのか訳わからん><

でもまあJrebelとかだと、

  • 一旦動かすようのbuild.gradleを別生成
    • ローカルSDKの中のmvnrepoを明示的に指定していた

ところがあり、G様のやっつけ感が実感できるところだったり。。

  • app/AndroidManifest.xml
    • 記述で v14で宣言されているminsdkの定義を無視
<uses-sdk xmlns:tools="http://schemas.android.com/tools"
    tools:overrideLibrary="android.support.v14.preference" />
  • app/values/style.xml
    • スタイルをv14の方を指定
<style name="AppTheme" parent="Theme.AppCompat.NoActionBar">
    <!-- Customize your theme here. -->
    <item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item>
</style>

または、対象アクティビティのみであれば

<style name="SettingTheme" parent="Theme.AppCompat.NoActionBar">
    <!-- Customize your theme here. -->
    <item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item>
</style>

なんかそのまま適応すると真っ黒/白字なので微妙といえば微妙。。

  • app/res/style.xml
<style name="AppTheme" parent="Theme.AppCompat.NoActionBar">

<item name="android:listSeparatorTextViewStyle">@style/AppTheme.ListSeparatorTextView</item>

</style>

<style name="AppTheme.ListSeparatorTextView">
    <item name="android:textSize">14sp</item>
    <item name="android:textStyle">bold</item>
    <item name="android:textColor">@color/accent</item>
    <item name="android:paddingTop">16dp</item>
    <item name="android:layout_marginBottom">16dp</item>
</style>

スタイル変更の参照情報

未だに修正はされていない状態らしいですね。。

<style name="SettingTheme" parent="Theme.AppCompat.NoActionBar">
    <item name="preferenceTheme">@style/CustumPreference</item>
</style>

<style name="CustumPreference" parent="PreferenceThemeOverlay.v14.Materialr">
    <!-- Customize your theme here. -->
</style>

のCustumPreferenceを弄りまくれば、色は変わるけど

殆どlayout.xml指定なので公式使っても死ぬ思いをしますね。。

なぜActionBarのメインスタイルの色とか使ってくれないのかがすごい疑問

Custom Preference の置き換えについて(support-v7版に)

自分で CustomPreference を作成しようとした場合

android.support.v7.preference.DialogPreference

のに置き換え対応あたりで実現できなくてハマる*2

とsupport-libraryを使わない場合は、onBindViewで実装する

import android.preference.Preference;

public class CustomButtonPreference extends Preference {

    public CustomButtonPreference(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public CustomButtonPreference(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        setWidgetLayoutResource(R.layout.preference_button;
    //    or
    //setLayoutResource(R.layout.preference_button);
    }

    protected void onBindView(View view) {
        SwitchCompat switch = (SwitchCompat)view.findViewById(R.id.switch);

でこれに対処しようとしたらググるとか下記が出てきたんですが、いまいち上手く動かず。

でソース読んでたら onBindViewHolder で置き換えると良いことが分かる

import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceViewHolder;

public class CustomButtonPreference extends Preference {

    public CustomButtonPreference(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public CustomButtonPreference(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        setWidgetLayoutResource(R.layout.preference_button;
        //setLayoutResource(R.layout.preference_button);
    }

    protected void onBindViewHolder(PreferenceViewHolder holder) {
        super.onBindViewHolder(holder);
        holder.itemView.setClickable(false); // disable parent click
    SwitchCompat switch = (SwitchCompat)holder.findViewById(R.id.switch);

に良いサンプルが載ってたので、これを参考にするとよいかと

因みにSwitchCompatの件

あたりの情報が出てくるんですけど

  • appcompat-v7 の
AppCompatAutoCompleteTextView
AppCompatButton
AppCompatCheckBox
AppCompatCheckedTextView
AppCompatEditText
AppCompatMultiAutoCompleteTextView
AppCompatRadioButton
AppCompatRatingBar
AppCompatSpinner
AppCompatTextView

辺りとか

  • Design Support Library

あたりしか更新が入ってないようなんだよな。。

G様が使ってないからかもしれないんですけど、、

*1:でもgradle pluginのバージョン上げると sdk repoに有るはずなのになぜかNWからDLすることがある挙動は、ココらへんの記述面倒くさいからだと思われる。。

*2:値のBindView辺りで