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属性;以及点击等相关方法后续介绍; 喜欢的点个赞吧!!!