web-dev-qa-db-ja.com

AndroidのカスタムSwitchPreference

AndroidのSwitchPreferenceウィジェット用に描画可能なカスタムスタイルまたはその他の背景セレクターを設定するにはどうすればよいですか?

(注:通常のSwitchウィジェットではなく、SwitchPreference/PreferenceActivityで使用される標準のPreferenceFragmentウィジェットを意味します)

11
micnoy

スイッチ自体のカスタムレイアウトを作成する必要があり、のように動的に適用できます。

preference.setWidgetLayoutResource(R.layout.custom_switch);

しかし、私は詳細に立ち入り、これを達成する方法を正確に示します。

したがって、preferences.xmlのようなxmlファイルで設定を定義します。

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:Android="http://schemas.Android.com/apk/res/Android" >
    <PreferenceCategory Android:title="YOUR_CATEGORY_TITLE" >
        <SwitchPreference
            Android:key="SWITCH"
            Android:title="YOUR_TITLE_FOR_SWITCH" />
    </PreferenceCategory>
</PreferenceScreen>

次に、PreferenceActivtyクラス内のonCreate()メソッドでそれを読み取ります。

    SwitchPreference pref = (SwitchPreference) findPreference(getString(R.string.SWITCH));
    //pref.setChecked(true); // You can check it already if needed to true or false or a value you have stored persistently
    pref.setWidgetLayoutResource(R.layout.custom_switch); // THIS IS THE KEY OF ALL THIS. HERE YOU SET A CUSTOM LAYOUT FOR THE WIDGET
    pref.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {

        @Override
        public boolean onPreferenceChange(Preference preference, Object newValue) {
            // Here you can enable/disable whatever you need to
            return true;
        }
    });

custom_switchレイアウトは次のようになります:

<?xml version="1.0" encoding="utf-8"?>
<Switch xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:id="@+id/custom_switch_item"
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
    Android:gravity="center_vertical"
    Android:textColor="@Android:color/white"
    Android:textIsSelectable="false"
    Android:textSize="18sp"
    Android:textStyle="bold"
    Android:track="@drawable/switch_track" 
    Android:thumb="@drawable/switch_thumb"/>

また、スイッチには、trackthumbの2つのセレクターがあります。プロパティ。これらのセレクターのドローアブルは、Android Holo Color Generatorで生成できます。これは tasomaniac によって提案されました。この場合、必要なのはコピーすることだけです。生成されたドローアブルフォルダーのコンテンツ(drawable-hdpi、drawable-mdpi、drawable-xhdpi、drawable-xxhdpiのみ)。ただし、必要な状態ごとにカスタムビューを作成できます。

これらのセレクターは次のようになります。switch_track:

<?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:Android="http://schemas.Android.com/apk/res/Android">

    <item Android:drawable="@drawable/switch_bg_focused" Android:state_focused="true"/>
    <item Android:drawable="@drawable/switch_bg"/>

</selector>

switch_thumb:

<?xml version="1.0" encoding="utf-8"?>
     <selector xmlns:Android="http://schemas.Android.com/apk/res/Android">

     <item Android:drawable="@drawable/switch_thumb_disabled" Android:state_enabled="false"/>
     <item Android:drawable="@drawable/switch_thumb_pressed" Android:state_pressed="true"/>
     <item Android:drawable="@drawable/switch_thumb_activated" Android:state_checked="true"/>
     <item Android:drawable="@drawable/switch_thumb"/>

</selector>

そして、それはほとんどそれです。この解決策は私を助けました。何か省略した場合はお知らせください。問題を修正します。

15
Mike

以下のWebサイトを使用して、スイッチのスタイルを生成できます。 http://Android-holo-colors.com/

次に、次のライブラリを使用して、通常のスイッチのカスタム実装を行うことができます。これらのライブラリには、SwitchPreferenceの代替も含まれています。

https://github.com/BoD/Android-switch-backport

https://github.com/ankri/SwitchCompatLibrary

4
tasomaniac

これを行う1つの方法は、SwitchPreferenceをサブクラス化し、onBindViewメソッドをオーバーライドすることです。その際、そのメソッドでsuper.onBindView(view)を呼び出しますが、子ビューでSwitchを見つけて、必要に応じてスタイルを設定します。

package com.example;

import Android.annotation.SuppressLint;
import Android.content.Context;
import Android.preference.SwitchPreference;
import Android.util.AttributeSet;
import Android.view.View;
import Android.view.ViewGroup;
import Android.widget.Switch;

import com.example.R;


public class CustomSwitchPreference extends SwitchPreference {

    @SuppressLint("NewApi")
    public CustomSwitchPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    public CustomSwitchPreference(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public CustomSwitchPreference(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public CustomSwitchPreference(Context context) {
        super(context);
    }

    @Override
    protected void onBindView(View view) {

        super.onBindView(view);
        Switch theSwitch = findSwitchInChildviews((ViewGroup) view);
        if (theSwitch!=null) {
            //do styling here
            theSwitch.setThumbResource(R.drawable.new_thumb_resource);
        }

    }

    private Switch findSwitchInChildviews(ViewGroup view) {
        for (int i=0;i<view.getChildCount();i++) {
            View thisChildview = view.getChildAt(i);
            if (thisChildview instanceof Switch) {
                return (Switch)thisChildview;
            }
            else if (thisChildview instanceof  ViewGroup) {
                Switch theSwitch = findSwitchInChildviews((ViewGroup) thisChildview);
                if (theSwitch!=null) return theSwitch;
            }
        }
        return null;
    }
}
1
Chris