【问题标题】:Android: Using Switch Preference pre API level 14Android:使用 API 级别 14 之前的 Switch Preference
【发布时间】:2012-03-19 08:08:23
【问题描述】:

在 API 级别 14 之前,没有切换首选项。如果我使用preferences.xml 来创建我的偏好屏幕,有什么方法可以区分API 级别吗?那么有一个旧版本的复选框和一个 API 14 的开关?

最好的方法是什么?

【问题讨论】:

    标签: android preferences


    【解决方案1】:

    如果我使用preferences.xml 创建我的偏好屏幕,有什么方法可以区分API 级别吗?那么有一个旧版本的复选框和一个 API 14 的开关?

    创建一个包含preferences.xmlres/xml-v14/ 目录,其中包含您的SwitchPreference。创建一个包含preferences.xml 文件的res/xml/ 目录,该文件将SwitchPreference 替换为CheckBoxPreference。 Android 将根据运行应用的设备版本加载正确的 preferences.xml 文件版本。

    【讨论】:

    • 是否存在与 lauout 文件的“包含”标签等效的标签,但对于首选项文件?这样,只需要最少的文本,因为 delta 将位于 v14 文件夹中,对吧?
    • @androiddeveloper:对不起,我不知道。
    • 我已经为这个问题做了一个很好的解决方法,它在可能的情况下包装了 switchPreference,如果不可能,则使用复选框。你能检查一下,看看它是否还可以?根据我的测试,它工作正常,但也许我错过了一些功能。
    • @androiddeveloper:恕我直言,您需要覆盖 all 方法并将它们中的 all 路由到您的_switchPreference,而不仅仅是显示的那些。否则,其他方法将适用于基础 CheckBoxPreference 内容,您可能会不同步。
    • 是的,我也这么认为,但我也认为,由于它只使用 onCreateView 中的 switchPreference 视图,它可能会一直使用它作为其他方法的参考。我并没有真正使用 switchPreference,只使用它的视图。我认为 android 的其余实现只是在所有方法中使用视图,这也表明它工作的原因(至少在我的测试用例中)。
    【解决方案2】:

    您还可以使用 android-switch-backport 库,它具有适用于 Android 2.1+ 的 SwitchPreference。

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

    【讨论】:

    • 当我将依赖项添加到gradle 时,我的项目卡在compiling dependencies 上。
    【解决方案3】:

    有一个解决方法,我不确定它有多满,通过在 CheckBoxPreference 中包装要使用的视图(可能会错过一些功能,但在一般使用中,它可以工作)。

    解决方法将使用针对 pre-API-14 的 CheckBoxPreference 和针对 API 14 及更高版本的 SwitchPreference。

    代码如下:

    public class SwitchPreference extends CheckBoxPreference
      {
      android.preference.SwitchPreference _switchPreference =null;
    
      public SwitchPreference(final Context context)
        {
        super(context);
        if(VERSION.SDK_INT>=VERSION_CODES.ICE_CREAM_SANDWICH)
          _switchPreference=new android.preference.SwitchPreference(context);
        }
    
      public SwitchPreference(final Context context,final AttributeSet attrs)
        {
        super(context,attrs);
        if(VERSION.SDK_INT>=VERSION_CODES.ICE_CREAM_SANDWICH)
          _switchPreference=new android.preference.SwitchPreference(context,attrs);
        }
    
      public SwitchPreference(final Context context,final AttributeSet attrs,final int defStyle)
        {
        super(context,attrs,defStyle);
        if(VERSION.SDK_INT>=VERSION_CODES.ICE_CREAM_SANDWICH)
          _switchPreference=new android.preference.SwitchPreference(context,attrs,defStyle);
        }
    
      @Override
      protected View onCreateView(final ViewGroup parent)
        {
        final View view;
        if(VERSION.SDK_INT>=VERSION_CODES.ICE_CREAM_SANDWICH)
          {
          view=_switchPreference.getView(null,parent);
          // set as checked the view and the view's children, each in case it extend from Checkable
          ViewUtil.setChecked(view,isChecked());
          // set as non-clickable the view and the view's children
          ViewUtil.setClickable(view,false);
          }
        else view=super.onCreateView(parent);
        return view;
        }
    

    【讨论】:

    • @3c71 抱歉,您错了,我认为您还没有尝试过。可以声明任何类型的类,即使由于 API 不同而无法访问它。只有使用类的方法(包括 CTOR)才会崩溃,因为您无权访问它们。
    • 实际上这是一个聪明且有效的解决方案。确保 SwitchPreference 只是在您自己的包中,并且 XML 没有使用原始 SwitchP,而是使用新的。此外,您可能需要覆盖更多方法,例如isChecked 等。换句话说,该项目作为 CheckBoxPreference 工作,但看起来像 SwitchPreference。
    • @digitalfootmark 我不确定。到目前为止,它对我来说效果很好。这就是我写它不是“完整”的原因,因为我不确定应该添加哪些功能。你确定“isChecked”不起作用吗?我的意思是,我什至在这段代码中使用它......
    【解决方案4】:

    试试这个代码:

    public class SettingsActivity extends PreferenceActivity {
    
        @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            // setContentView(R.layout.activity_settings);
            PreferenceScreen rootScreen = getPreferenceManager()
                    .createPreferenceScreen(this);
            setPreferenceScreen(rootScreen);
            Preference NotifCheck=null;
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
                NotifCheck = new SwitchPreference(this);
    
            } else {
                NotifCheck = new CheckBoxPreference(this);
    
            }
            NotifCheck.setKey("ShowNotification");
            NotifCheck.setTitle(R.string.ShowNotification);
            NotifCheck.setEnabled(true);
            rootScreen.addPreference(NotifCheck);
            // Show the Up button in the action bar.
            setupActionBar();
        }
    }
    

    【讨论】:

      【解决方案5】:

      您可以使用 SwitchCompat:

      <android.support.v7.widget.SwitchCompat
          android:id="@+id/switch_compat"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:layout_alignParentRight="true"
          android:checked="true"
          android:textOff="OFF"
          android:textOn="ON"
          app:showText="false"
          android:focusable="false"
          android:focusableInTouchMode="false"/>
      

      在 setOnCheckedChangeListener 上:

      SwitchCompat switchCompat = (SwitchCompat)convertView.findViewById(R.id.switch_compat);
              switchCompat.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                  @Override
                  public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                      if (isChecked) {
                          textView.setText("check");
                      } else {
                          textView.setText("unCheck");
                      }
                  }
              });
      

      希望对你有帮助。

      【讨论】:

        猜你喜欢
        • 2015-12-17
        • 1970-01-01
        • 2012-06-05
        • 2011-04-14
        • 1970-01-01
        • 2011-11-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多