如何使用Androidx的PreferenceScreen

21

我的问题是我想要在我的应用程序中添加一个首选项屏幕(PreferenceScreen),但我无法使用它,也不知道原因。

我实现了库androidx.preference:preference:1.1.0-rc01。然后我想将PreferenceScreen添加到我的XML布局中,但它没有提供任何建议。

接下来,我将Android Developers的XML代码复制到我的XML布局中并编译它,但启动活动时会出现以下错误:java.lang.ClassCastException: class androidx.preference.PreferenceScreen cannot be cast to android.view.View

有谁能帮我正确使用androidx.preference.PreferenceScreen吗?

我的布局:

<?xml version="1.0" encoding="utf-8"?>
<androidx.preference.PreferenceScreen  xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_height="match_parent"
    android:layout_width="match_parent">
    <androidx.preference.SwitchPreference
        android:defaultValue="true"
        android:key="example_switch"
        android:summary="Turn this option on or off"
        android:title="Settings option" />
</androidx.preference.PreferenceScreen>

你可以发布你的布局吗? - Richard Dapice
是的,我可以发布我的布局。在这里。 - BierDav
此外,您的Preference活动会很有帮助。 - Richard Dapice
3个回答

38

现在是完整的答案:

  1. 将以下行添加到您的App-Gradle中:implementation 'androidx.preference:preference:1.1.1' 或者针对Kotlin implementation 'androidx.preference:preference-ktx:1.1.1'。然后同步Gradle。在res文件夹中创建一个名为xml的目录。

  2. 在该目录中创建一个XML文件,命名为您喜欢的名称,例如main_preferences。根元素必须是androidx.preference.PreferenceScreen

  3. 使用您的设置填充XML文件,例如:

<?xml version="1.0" encoding="utf-8"?>
<androidx.preference.PreferenceScreen  xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_height="match_parent"
    android:layout_width="match_parent">
    <androidx.preference.SwitchPreference
        android:defaultValue="true"
        android:key="example_switch"
        android:summary="Turn this option on or off"
        android:title="Settings option" />
</androidx.preference.PreferenceScreen>
  1. 在文件夹com.???.???中创建一个名为MainSettingsFragment的Java文件。其超类(意味着<Classname> extends <Superclass>)必须是PreferenceFragmentCompat并覆盖onCreatePreferences方法。您可以复制此代码:
import android.os.Bundle; 
import androidx.preference.PreferenceFragmentCompat;
import com.???.???.R;

public class <YourClassname> extends PreferenceFragmentCompat {
    @Override
    public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
        // Load the preferences from an XML resource
        setPreferencesFromResource(R.xml.<yourXmlFilename>, rootKey);
    }
}
  1. 接下来,有两个选项来在您的.中实现PreferencesSreen。

最好和最美的方法是,在创建时通过代码来实现它。 在您的SettingsActivty中添加一个FrameLayout并为其指定一个ID,例如fl_main_settings

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_height="match_parent"
    android:layout_width="match_parent"
    android:id="@+id/<!-- yourID -->">

</FrameLayout>

并且在您的Activity Code中,在onCreate方法的顶部添加以下内容:

package com.???.???;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.text.Html;
import android.view.MenuItem;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.text.HtmlCompat;

import com.???.???.MainSettingsFragment;
public class SettingsActivity extends AppCompatActivity {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.<SettingsActivityXML(with the FrameLayout)>);

        //If you want to insert data in your settings
        <YourSettingsFragmentClass> settingsFragment = new <YourSettingsFragmentClass>();
        settingsFragment. ...
        getSupportFragmentManager().beginTransaction().replace(R.id.<YourFrameLayout>,settingsFragment).commit();
        
        //Else
        getSupportFragmentManager().beginTransaction().replace(R.id.<YourFrameLayout>,new <YourSettingsFragmentClass>()).commit();
    }

或者您可以在您的SettingsActivityXml中实现一个Fragment。 但是我不建议这样做,因为启动活动需要几秒钟时间


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:baselineAligned="false">

    <fragment
        android:tag="frag"
        android:name="com.quickme.musicme.Fragments.MainSettingsFragment"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"/>
</LinearLayout>

就是这样,玩得愉快。


2
谢谢您提供的教程,非常清晰易懂。但是当您说(第5点)“添加一个FrameLayout”时,您漏掉了一个单词,不是吗?是在您的main_activity.xml文件中添加一个FrameLayout吗?还是在另一个xml文件中? - Christian
我一直收到"java.lang.NullPointerException: Attempt to invoke virtual method 'void androidx.recyclerview.widget.RecyclerView.setAdapter(androidx.recyclerview.widget.RecyclerView$Adapter)' on a null object reference"的错误提示,只有当我取消注释这行代码:"setPreferencesFromResource(R.xml.settings, rootKey);" ,且这个 xml 文件看起来没有问题。 - pete
谢谢你,Christian。我无意中评论了它。现在我已经修复了它。 - BierDav
你为什么要使用RecyclerView,Pete?我不认为这是因为我的代码有问题。也许你需要检查一下你的RecyclerView适配器及其初始化方式 ;) - BierDav

1
java.lang.ClassCastException: 类 androidx.preference.PreferenceScreen 无法转换为 android.view.View
我的布局:
<?xml version="1.0" encoding="utf-8"?>
<androidx.preference.PreferenceScreen>
...
</androidx.preference.PreferenceScreen>

请注意。
这不是一个布局。

有人能帮我正确使用androidx.preference.PreferenceScreen吗?

您可以在此处找到所有信息

您可以定义首选项层次结构。

注意:根标签必须是<PreferenceScreen>,并且XML资源必须放置在res/xml/目录中

<PreferenceScreen
    xmlns:app="http://schemas.android.com/apk/res-auto">

    ....

</PreferenceScreen>

要从 XML 属性扩展层次结构,请创建一个 PreferenceFragmentCompat,重写 onCreatePreferences() 方法,并提供 XML 资源:

class MySettingsFragment : PreferenceFragmentCompat() {
    override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
        setPreferencesFromResource(R.xml.preferences, rootKey)
    }
}

然后将这个Fragment添加到您的Activity中,就像处理其他任何`Fragment`一样。


-2
尝试:xml/preferences.xml
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen  
  xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_height="match_parent"
    android:layout_width="match_parent">
    <SwitchPreference
        android:defaultValue="true"
        android:key="example_switch"
        android:summary="Turn this option on or off"
        android:title="Settings option" />
</PreferenceScreen>

我也更喜欢使用偏好设置片段,由我的活动托管。

class MySettingsActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        supportFragmentManager
                .beginTransaction()
                .replace(R.id.settings_container, SettingsFragment())
                .commit()
    }
}

class SettingsFragment : PreferenceFragmentCompat() {
    override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
        setPreferencesFromResource(R.xml.preferences, rootKey)
    }
}

问题要求使用Java解决方案,而不是Kotlin。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接