Android Settings中Preference的理解以及使用

本文介绍了Android中Preference的重要性和使用场景,包括PreferenceActivity和PreferenceFragment的差异,以及如何自定义Preference。通过示例展示了设置Preference布局文件的方式,并探讨了自定义Preference时如何改变布局和控件的行为。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

      Preference 是Android App 中重要的控件之一,Settings 模块大部分都是通过 Preference 实现

优点:

        Preference 可以自动显示我们上次设置的数据,Android提供preference这个键值对的方式来处理这种情况,自动保存这些数据,并立时生效,无需用户自己保存操作,只需要在xml中定义对应的Preference控件即可。

PreferenceActivity和PreferenceFragment:

        PreferenceActivity是一个非常有用的基类,当我们开发Android项目时避免不了选项设置,这些设置习惯用Preference来保存。Android专门为这种Activity提供了便捷的基PreferenceActivity。如果继承自Preference则不需要自己控制Preference的读写,PreferenceActivity会为我们处理一切。

        PreferenceActivity与普通的Activity不同,它不是使用界面布局文件,而是使用选项设置的布局文件。选项设置布局文件以PreferenceScreen作为根元素来表示定义一个参数设置界面布局。

       从Android 3.0以后官方不再推荐直接让PreferenceActivity加载选项设置布局文件,而是建议使用PreferenceFragment,PreferenceFragment  源码布局实际就是一个RecyclerView,通过读取Preference的布局来作为其item,通过adapter适配器展示

Preference的介绍和使用

 1.preference常用控件
             Preference 控件家庭          View控件家庭         控件含义                   

               Preference                         TextView                文本框                      

              CheckPreference                CheckBox              单选框                  

              EditTextPreference              EditText               输入文本框            

              ListPreference                     ListView                  列表框             

              RingtonePreference          ——                            铃声

              PreferenceCategory        类似于LinearLayou、RelativeLayout,用于组合一组Preference,使布局更具备层次感 。

              PreferenceScreen            所有Preference元素的根节点
 2.使用 需要加入依赖

 implementation ("androidx.preference:preference:1.2.0-alpha01")

(1)在res文件下定义xml文件夹,定义 test.xml;如下

(2)xml文件中是定义的preference控件

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:settings="http://schemas.android.com/tools">

    <PreferenceCategory
        android:key="test2"
        android:title="第二组设置">

        <CheckBoxPreference
            android:defaultValue="false"
            android:key="g2_checkbox_key"
            android:summaryOff="关"
            android:summaryOn="开"
            android:title="第二组设置勾选" />

        <ListPreference
            android:dialogIcon="@android:drawable/stat_sys_warning"
            android:dialogTitle="第二组列表设置"
            android:key="g2_list_key"
            android:summary="选择"
            android:title="第一组列表设置" />

    </PreferenceCategory>

    <SwitchPreference
        android:defaultValue="false"
        android:key="show_advanced_setting"
        android:summary="高级设置"
        android:title="显示高级设置" />

    <PreferenceCategory android:key="yh">
        <com.android.test3.prefence.RestrictedSwitchPreference
            android:defaultValue="true"
            android:icon="@drawable/ic_settings_wireless"
            android:key="login_dji_account"

            android:title="蓝牙" />

        <com.android.test3.prefence.RestrictedSwitchPreference
            android:defaultValue="true"
            android:icon="@drawable/ic_launcher_background"
            android:key="login_dji_account1"
           app:allowDividerAbove="true"
            android:title="网络" />

        <com.android.test3.prefence.RestrictedPreference
            android:icon="@drawable/ic_launcher_background"
            android:key="internet_settings"
            android:order="20"
            android:summary=" SAA"
            android:title="互联网"
            app:allowDividerAbove="true"

            settings:keywords="@string/keywords_internet"
            settings:useAdminDisabledSummary="true" />

        <com.android.test3.prefence.LuxPreference
            android:icon="@drawable/ic_settings_wireless"
            android:summary="ww"
            app:allowDividerAbove="true"
            android:title="测试自动" />

        <com.android.test3.prefence.LuxArrowPreference
            android:icon="@drawable/ic_settings_wireless"
            android:summary="ww"
            android:title="开始" />

    </PreferenceCategory>

</PreferenceScreen>

 (3)新建类PrefFragment.java,让其继承PreferenceFragment,并加载选项设置的布局文件:(核心代码是第6行和13行)

package com.android.test3.fragment;
import android.os.Bundle;

import androidx.annotation.Nullable;
import androidx.preference.PreferenceFragmentCompat;

import com.android.test3.R;

/**
 * @author hudebo
 * @desc
 * @date 2022/11/11
 */
public class PowerFragment extends PreferenceFragmentCompat {
    @Override
    public void onCreatePreferences(@Nullable Bundle savedInstanceState, @Nullable String rootKey) {
        //从xml文件加载选项 
        setPreferencesFromResource(R.xml.pref_two, rootKey);
    }
}

(4)然后,在MainActivity.java中加载上面的Fragment

package com.android.test3;

import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import com.android.test3.fragment.PowerFragment;

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getSupportFragmentManager().beginTransaction().replace(
                R.id.content,new PowerFragment() ).commitAllowingStateLoss();
    }

}

自定义Preference

有时候原生的preference满足不了我们的需求,比如,加个背景,加个其他控件等;此时就需要我们自定义控件解决

 比如:(1)给布局设置背景;我们继承Preference;在onBindViewHolder 方法中对通过holder获取控件其进行设置

package com.android.test3.prefence;

import android.content.Context;
import android.util.AttributeSet;

import androidx.core.content.res.TypedArrayUtils;
import androidx.preference.Preference;
import androidx.preference.PreferenceViewHolder;

import com.android.test3.PrefenceFeatureManager;
import com.android.test3.R;

/**
 * @author hudebo
 * @desc 自定义子Preference 支持圆角; 去除summary  支持icon title
 * @date 2022/11/24
 */
public class LuxPreference extends Preference {
    public LuxPreference(Context context, AttributeSet attrs, int defStyleAttr) {
        this(context, attrs, defStyleAttr, 0);
    }

    public LuxPreference(Context context, AttributeSet attrs) {
        this(context, attrs, TypedArrayUtils.getAttr(context, R.attr.luxPreferenceStyle,
                android.R.attr.preferenceStyle));
    }

    public LuxPreference(Context context) {
        this(context, null);
    }

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

    @Override
    public void onBindViewHolder(PreferenceViewHolder holder) {
        super.onBindViewHolder(holder);
        if (holder != null) {
            PrefenceFeatureManager.setPrefenceBackground(this, holder.itemView);
        }
    }
}

(2)修改布局控件;a.首先我们在layout中定义绘制你的布局样式

 b.在自定义控件中引入你的布局即可

声明:setLayoutResource 方法即是覆盖原始preference的主布局;setWidgetLayoutResource 方法是覆盖原始布局的WidgetLayout的控件;如下图是preference的源码布局;

 setLayoutResource 是替换除了"@android:id/widget_frame" 这个控件的部分;setWidgetLayoutResource只是替换"@android:id/widget_frame"部分;如果setWidgetLayoutResource不设置也不影响;说明你得,右边没有布局

<?xml version="1.0" encoding="utf-8"?>
<!--
  ~ Copyright (C) 2015 The Android Open Source Project
  ~
  ~ Licensed under the Apache License, Version 2.0 (the "License");
  ~ you may not use this file except in compliance with the License.
  ~ You may obtain a copy of the License at
  ~
  ~      http://www.apache.org/licenses/LICENSE-2.0
  ~
  ~ Unless required by applicable law or agreed to in writing, software
  ~ distributed under the License is distributed on an "AS IS" BASIS,
  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  ~ See the License for the specific language governing permissions and
  ~ limitations under the License.
  -->

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:minHeight="?android:attr/listPreferredItemHeightSmall"
    android:gravity="center_vertical"
    android:paddingLeft="?android:attr/listPreferredItemPaddingLeft"
    android:paddingStart="?android:attr/listPreferredItemPaddingStart"
    android:paddingRight="?android:attr/listPreferredItemPaddingRight"
    android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
    android:background="?android:attr/selectableItemBackground"
    android:clipToPadding="false"
    android:baselineAligned="false">

    <include layout="@layout/image_frame"/>

    <RelativeLayout
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:paddingTop="16dp"
        android:paddingBottom="16dp">

        <TextView
            android:id="@android:id/title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:singleLine="true"
            android:textAppearance="?android:attr/textAppearanceListItem"
            android:ellipsize="marquee"/>

        <TextView
            android:id="@android:id/summary"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@android:id/title"
            android:layout_alignLeft="@android:id/title"
            android:layout_alignStart="@android:id/title"
            android:layout_gravity="start"
            android:textAlignment="viewStart"
            android:textColor="?android:attr/textColorSecondary"
            android:maxLines="10"
            style="@style/PreferenceSummaryTextStyle"/>

    </RelativeLayout>

    <!-- Preference should place its actual preference widget here. -->
    <LinearLayout
        android:id="@android:id/widget_frame"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:gravity="end|center_vertical"
        android:paddingLeft="16dp"
        android:paddingStart="16dp"
        android:paddingRight="0dp"
        android:paddingEnd="0dp"
        android:orientation="vertical"/>

</LinearLayout>

以上就是一些个人理解;像通用的preference属性;以及点击等相关方法后续介绍; 喜欢的点个赞吧!!!

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值