The understanding and use of Preference in Android Settings

      Preference is one of the important controls in Android App, and most of the Settings module is implemented through Preference

advantage:

        Preference can automatically display the data we set last time. Android provides the key-value pair of preference to deal with this situation, automatically save these data, and take effect immediately. There is no need for the user to save the operation by himself, only need to define the corresponding Preference in xml controls.

PreferenceActivity和PreferenceFragment:

        PreferenceActivity is a very useful base class. When we develop Android projects, option settings cannot be avoided. These settings are used to save with Preference. Android provides a convenient base PreferenceActivity specifically for this kind of Activity. If you inherit from Preference, you don't need to control the reading and writing of Preference yourself, PreferenceActivity will handle everything for us.

        PreferenceActivity is different from ordinary Activity. It does not use interface layout files, but layout files that use option settings. The option setting layout file uses PreferenceScreen as the root element to define a parameter setting interface layout.

       Since Android 3.0, it is no longer officially recommended to directly let PreferenceActivity load options to set the layout file. Instead, it is recommended to use PreferenceFragment. The source code layout of PreferenceFragment is actually a RecyclerView, which reads the layout of Preference as its item and displays it through the adapter adapter.

Introduction and use of Preference

 1. Preference commonly used controls
             Preference control family View control family Control meaning                   

               Preference TextView text box                      

              CheckPreference CheckBox radio button                  

              EditTextPreference EditText input text box            

              ListPreference ListView list box             

              RingtonePreference - Ringtone

              PreferenceCategory is similar to LinearLayout and RelativeLayout, and is used to combine a set of Preferences to make the layout more layered.

              PreferenceScreen The root node of all Preference elements
 2. Use needs to add dependencies

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

(1) Define the xml folder under the res file and define test.xml; as follows

(2) The preference control is defined in the xml file

<?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) Create a new class PrefFragment.java, let it inherit PreferenceFragment, and load the layout file for option settings: (the core code is line 6 and line 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) Then, load the above Fragment in MainActivity.java :

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();
    }

}

Custom Preferences

Sometimes the original preference can't meet our needs, for example, add a background, add other controls, etc.; at this time, we need to customize the control to solve it

 For example: (1) Set the background for the layout; we inherit Preference; in the onBindViewHolder method, set the control obtained through the 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) Modify the layout control; a. First, we define and draw your layout style in layout

 b. Introduce your layout in the custom control

Declaration: The setLayoutResource method is the main layout that covers the original preference; the setWidgetLayoutResource method is the WidgetLayout control that covers the original layout; the following figure is the source code layout of the preference;

 setLayoutResource is to replace the part of the control except "@android:id/widget_frame"; setWidgetLayoutResource just replaces the part of "@android:id/widget_frame"; if setWidgetLayoutResource is not set, it will not affect it; it means you have to, there is no layout on the right

<?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>

The above are some personal understandings; like the general preference attribute; and the follow-up introduction of related methods such as clicking; if you like it, give it a thumbs up! ! !

Guess you like

Origin blog.csdn.net/hhbstudy/article/details/128304762