【问题标题】:Android AppCompat v21 provides SwitchCompat does not provide SwitchCompatPreferenceAndroid AppCompat v21 提供 SwitchCompat 不提供 SwitchCompatPreference
【发布时间】:2014-10-23 20:07:13
【问题描述】:

似乎 AppCompat v21 提供了 SwitchCompat 不提供 SwitchCompatPreference。

我知道我可以使用 SwitchPreference,但它在视觉上并不相同。在 Android 4.x 上;当我在活动界面上使用 v21 的 SwitchCompact 时,它看起来像材质切换按钮,但是因为没有 SwitchCompactPreference 我必须在我的偏好视图中使用 SwitchPreference 并且显然它具有 Android 4.0 外观。

看起来 AppCompact v21 完成了一半。

我错过了什么吗?

【问题讨论】:

标签: android android-appcompat switchcompat switchpreference


【解决方案1】:

根据当前接受的答案和 cgollner 的要点,如果您只从那里获取 xml 布局: https://gist.github.com/cgollner/3c7fe2f9d34aee38bd0c

然后这样做:

<CheckBoxPreference
            android:widgetLayout="@layout/preference_switch_layout"
            android:defaultValue="off"
            android:key="key1"
            android:title="@string/title1" />

取而代之的是(使用 setWidgetLayoutResource 从源添加布局):

<com.cgollner.unclouded.preferences.SwitchCompatPreference
            android:defaultValue="off"
            android:key="key1"
            android:title="@string/title1" />

然后,动画也将在棒棒糖和以下使用相同的 xml 上工作。

【讨论】:

  • 想知道为什么动画可以使用这种方法以及为什么当您扩展 CheckBoxPreferences 并调用 setWidgetLayoutResource() 时它们不起作用。但无论出于何种原因,这似乎确实有效,所以 +1。
  • 这是一个很好的解决方案。我也很好奇为什么setWidgetLayoutResource() 不起作用。我做了一个快速测试,如果我们在注释掉 setWidgetLayoutResource() 调用的同时使用 SwitchCompatPreference 执行 android:widgetLayout="@layout/preference_switch_layout",它仍然不起作用。它仅适用于 CheckboxPreference。
【解决方案2】:
【解决方案3】:

我为自己构建了一些东西,SwitchCompatPreference.java。扩展SwitchPreference 被证明是构建它的最简单方法。可悲的是,SwitchCompat 没有继承自Switch,所以原来的SwitchPreference 需要稍作修改。首选项使用如下:

<me.barrasso.android.volume.ui.SwitchCompatPreference
        android:icon="@drawable/icon"
        android:key="key"
        android:defaultValue="false"
        android:widgetLayout="@layout/pref_switch"
        android:title="@string/title"
        android:summary="@string/summary" />

布局超级简单,根据需要进行调整。

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.SwitchCompat
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/toggle"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center_vertical"
    android:textIsSelectable="false"
    android:textStyle="bold" />

【讨论】:

    【解决方案4】:

    您不会喜欢这个答案,但我能想到的最好方法是从 SwitchCompat 对象创建您自己的偏好:

    http://developer.android.com/guide/topics/ui/settings.html#Custom

    我知道这个答案不是最好的,而且还没有代码示例。我会在周末尝试解决这个问题,并用我发现的内容更新这个答案。

    【讨论】:

      【解决方案5】:

      缺点:可能无法在所有设备上运行。


      在您的PreferenceActivity 中使用AppCompatDelegate(您可以基于AppCompatPreferenceActivity 的类)并在创建Switch 视图时覆盖onCreateView 以返回SwitchCompat

      即,

      public abstract class AppCompatPreferenceActivity extends PreferenceActivity {
          private AppCompatDelegate mDelegate;
      
          //... other methods omitted for clarity
      
          @Override
          public View onCreateView(String name, Context context, AttributeSet attrs) {
              // Allow super to try and create a view first
              final View result = super.onCreateView(name, context, attrs);
              if (result != null) {
                  return result;
              }
      
              if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
                  switch (name) {
                      // ... can add other views here
                      case "Switch":
                          return new SwitchCompat(this, attrs);
                  }
              }
              return null;
          }
      }
      

      这样做的好处是,您可以在不更改布局的情况下添加对现有应用程序的支持,而且工作量很小。

      【讨论】:

        【解决方案6】:

        这是关于已接受答案中 SwitchCompat 小部件的动画。

        我发现问题是Preference类中的一个flag引起的,在Android 4.0-4.3,这个flag是mHasSpecifiedLayout,在Android 4.4这个flag是mCanRecycleLayout。

        当您使用 setWidgetLayoutResource 设置小部件时,它会更改此标志。

        如果您使用不同的包名称(android.preference 或 com.android 除外)创建新的自定义首选项类,它也会更改此标志。

        当 mHasSpecifiedLayout 为 false 或 CanRecycleLayout 为 true 时,动画会起作用,否则动画不起作用。

        所以你可以使用反射而不是 setWidgetLayoutResource() 方法来设置小部件布局,这样动画就不会被破坏。

        这是一个sn-p:

                CheckBoxPreference switchPref = new CheckBoxPreference(getActivity());
                try {
                    Field field = Preference.class.getDeclaredField("mWidgetLayoutResId");
                    field.setAccessible(true);
                    field.setInt(switchPref, R.layout.preference_switch_layout);
                } catch (Exception e) {
                    switchPref.setWidgetLayoutResource(R.layout.preference_switch_layout);
                }
                switchPref.setKey(key);
                switchPref.setTitle(titleRes);
                switchPref.setSummary(summaryRes);
                switchPref.setDefaultValue(defaultValue);
        

        【讨论】:

          【解决方案7】:

          来自official Android blog

          如何将 AppCompat 与 Preferences 一起使用?
          在 API v11+ 设备上运行时,您可以继续在 ActionBarActivity 中使用 PreferenceFragment。对于之前的设备,您需要提供一个非材质样式的普通 PreferenceActivity。

          【讨论】:

          • 我明白这一点。我的问题是关于 SwitchPreference 的外观,而不是偏好活动
          猜你喜欢
          • 2014-12-23
          • 1970-01-01
          • 1970-01-01
          • 2015-02-04
          • 2011-10-10
          • 1970-01-01
          • 2014-07-09
          • 1970-01-01
          • 2014-05-04
          相关资源
          最近更新 更多