PreferenceFragmentCompat

學習記錄中

本來是用PreferenceFragment滑频,發(fā)現這東西過期了译荞,提示要用v7下的背犯,然后搜下用哪個包
參考這里:
因為新工程都用的androidx的脆烟,所以這個也換成androidx的
遷移到 AndroidX新老庫查詢
https://blog.csdn.net/qq_26914291/article/details/79917097

androidx.preference:preference:1.0.0

使用

class SettingFragment : PreferenceFragmentCompat() {
    
    override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {

    }

1.簡單看下PreferenceFragmentCompat的源碼凡恍,看下數據的加載過程

private int mLayoutResId = R.layout.preference_list_fragment;//默認布局志秃,下邊有

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
//省略,就是應用下主題
//然后就是下邊這個抽象方法嚼酝,我們到時候在這里加載xml即可
        onCreatePreferences(savedInstanceState, rootKey);
    }

public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {

       //...可以自定義布局浮还,設置divider,divider高度闽巩,最后一個item是否添加divider
        mLayoutResId = a.getResourceId(R.styleable.PreferenceFragmentCompat_android_layout,
                mLayoutResId);

        final Drawable divider = a.getDrawable(
                R.styleable.PreferenceFragmentCompat_android_divider);
        final int dividerHeight = a.getDimensionPixelSize(
                R.styleable.PreferenceFragmentCompat_android_dividerHeight, -1);
        final boolean allowDividerAfterLastItem = a.getBoolean(
                R.styleable.PreferenceFragmentCompat_allowDividerAfterLastItem, true);

//...后邊就是加載布局了钧舌,獲取id是android.R.id.list_container的容器,
//然后是創(chuàng)建RecyclerView

//省略涎跨,設置divider的代碼

        // If mList isn't present in the view hierarchy, add it. mList is automatically inflated
        // on an Auto device so don't need to add it.
        if (mList.getParent() == null) {
            listContainer.addView(mList);
        }
        mHandler.post(mRequestFocus);

        return view;
    }

//另外還有一些可以用到的方法
//在當前的選項里添加新的
public void addPreferencesFromResource(@XmlRes int preferencesResId) 

//替換新的
public void setPreferencesFromResource(@XmlRes int preferencesResId, @Nullable String key)

默認布局preference_list_fragment.xml
里邊一個FrameLayout容器洼冻,到時候會add一個RecyclerView進去,然后還有一個empty的textview

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_height="match_parent"
    android:layout_width="match_parent" >

    <FrameLayout
        android:id="@android:id/list_container"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />

    <TextView android:id="@android:id/empty"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:padding="8dp"
        android:gravity="center"
        android:visibility="gone" />

</LinearLayout>

2. 開始寫xml

系統提供的還不少隅很,一個一個學習


image.png

常用的preference的層級結構

//A container for multiple  {@link Preference} objects
public abstract class PreferenceGroup extends Preference

public final class PreferenceScreen extends PreferenceGroup 
//Used to group {@link Preference} objects and provide a disabled title above  the group.
public class PreferenceCategory extends PreferenceGroup

3.邊學邊記錄

寫了個簡單的碘赖,完事發(fā)現沒有divider,看源碼里有divider啊
仔細看下DividerDecoration的源碼
看完發(fā)現外构,要顯示divider有兩個條件
①非最后一個item的情況普泡,需要同時滿足自己isDividerAllowedBelow為true,完事下邊緊挨著的那個item的isDividerAllowedAbove為true审编;
②至于最后一個item撼班,則需要滿足isDividerAllowedBelow和mAllowDividerAfterLastItem這兩個條件;
這些默認都是false的

        private boolean shouldDrawDividerBelow(View view, RecyclerView parent) {
            final RecyclerView.ViewHolder holder = parent.getChildViewHolder(view);
            final boolean dividerAllowedBelow = holder instanceof PreferenceViewHolder
                    && ((PreferenceViewHolder) holder).isDividerAllowedBelow();
            if (!dividerAllowedBelow) {
                return false;
            }
            boolean nextAllowed = mAllowDividerAfterLastItem;
            int index = parent.indexOfChild(view);
            if (index < parent.getChildCount() - 1) {
                final View nextView = parent.getChildAt(index + 1);
                final RecyclerView.ViewHolder nextHolder = parent.getChildViewHolder(nextView);
                nextAllowed = nextHolder instanceof PreferenceViewHolder
                        && ((PreferenceViewHolder) nextHolder).isDividerAllowedAbove();
            }
            return nextAllowed;
        }

如何修改默認的divider了

看下PreferenceFragmentCompat的默認值哪來的

        getActivity().getTheme().resolveAttribute(R.attr.preferenceTheme, tv, true);
        int theme = tv.resourceId;
        if (theme == 0) {
            // Fallback to default theme.
            theme = R.style.PreferenceThemeOverlay;
        }
//我們沒有設置主題垒酬,默認用的就是PreferenceThemeOverlay這個主題砰嘁,然后我們去這個fragment所在的包的res下找
        TypedArray a = mStyledContext.obtainStyledAttributes(null,
                R.styleable.PreferenceFragmentCompat,
                R.attr.preferenceFragmentCompatStyle,
                0);

        mLayoutResId = a.getResourceId(R.styleable.PreferenceFragmentCompat_android_layout,
                mLayoutResId);

        final Drawable divider = a.getDrawable(
                R.styleable.PreferenceFragmentCompat_android_divider);
        final int dividerHeight = a.getDimensionPixelSize(
                R.styleable.PreferenceFragmentCompat_android_dividerHeight, -1);
        final boolean allowDividerAfterLastItem = a.getBoolean(
                R.styleable.PreferenceFragmentCompat_allowDividerAfterLastItem, true);

這是找到的默認的style


image.png

我們可以修改這個,系統的如下

    <style name="PreferenceFragment.Material">
        <item name="android:divider">@drawable/preference_list_divider_material</item>
        <item name="allowDividerAfterLastItem">false</item>
    </style>

修改后的,放到我們app的style.xml下即可

    <style name="PreferenceFragment.Material" tools:override="true">
        <item name="android:divider">@drawable/divider_normal_gray</item>
        <item name="android:dividerHeight">5dp</item>
        <item name="allowDividerAfterLastItem">true</item>
    </style>

當然了,這里也可以修改fragment默認加載的布局勘究,不過里邊必須有一個id如下的ViewGroup,
還可以有個id是recycler_view的RecyclerView矮湘,沒有的話代碼里會add一個進去

    <FrameLayout
        android:id="@android:id/list_container"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />

PreferenceCategory

image.png

category的title顏色,默認使用的是colorAccent
當然口糕,這些都是可以改的缅阳,你可以修改默認的布局,修改默認布局里TextView的style


image.png
    <androidx.preference.PreferenceCategory android:title="category">
        <androidx.preference.PreferenceScreen
            android:icon="@drawable/settings_general"
            android:title="test1"
            app:layout="@layout/view_settings_list_item">
            <androidx.preference.CheckBoxPreference
                android:icon="@drawable/i_settings_wifi_0"
                android:key="wifiauto"
                android:title="auto" />
            <androidx.preference.SwitchPreference
                android:icon="@drawable/i_settings_wifi_4"
                android:key="wifi111"
                android:title="wifi" />
        </androidx.preference.PreferenceScreen>
    </androidx.preference.PreferenceCategory>

ListPreference

單選彈框

    <androidx.preference.ListPreference
        android:entries="@array/ID_SETTING_MENU_ARRAY"
        android:entryValues="@array/ID_SETTING_MENU_ARRAY_VALUE"
        android:defaultValue="0"
        android:title="single choice"
        android:key="@string/ID_SETTINGS_KEY_MENU_LAYOUT2"/>

系統沒有提供頁面內的單選功能景描,只有這種彈框十办,如果需要的話得自定義了
比如需要這種頁面內的單選


image.png

系統有checkbox的preference秀撇,沒有radiobutton的,我們可以稍微修改下
看下checkbox的style,最右邊的widget替換的是個checkbox

    <style name="Preference.CheckBoxPreference">
        <item name="android:widgetLayout">@layout/preference_widget_checkbox</item>
    </style>

而CheckBoxPreference 里并沒有強求是checkbox向族,判斷的都是Checkable,而radioButton也有這屬性

public class CheckBoxPreference extends TwoStatePreference

    private void syncCheckboxView(View view) {
        if (view instanceof CompoundButton) {
            ((CompoundButton) view).setOnCheckedChangeListener(null);
        }
        if (view instanceof Checkable) {
            ((Checkable) view).setChecked(mChecked);
        }
        if (view instanceof CompoundButton) {
            ((CompoundButton) view).setOnCheckedChangeListener(mListener);
        }
    }

如下簡單修改即可

        <androidx.preference.CheckBoxPreference
            android:key="@string/ID_SETTINGS_KEY_MENU_LAYOUT"
            app:widgetLayout="@layout/preference_widget_radiobutton"
            android:title="@string/ID_SETTINGS_MENU_LAYOUT_TILE"/>

//preference_widget_radiobutton布局如下呵燕,原本是個CheckBox,我們這里替換成RadioButton
<?xml version="1.0" encoding="utf-8"?>
<RadioButton xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/checkbox"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:focusable="false"
    android:clickable="false"
    android:background="@null" />

替換完發(fā)現沒啥太大意義件相,這玩意和radioButton有區(qū)別再扭,這個可以取消選擇,RadioButton選中的再點還是選中狀態(tài)

自定義單選功能

我們自定義一下頁面內單選功能夜矗,用同一個key泛范,給個默認的value

    <androidx.preference.PreferenceScreen
        android:key="@string/ID_SETTINGS_KEY_MENU_LAYOUT"
        android:title="@string/ID_SETTINGS_MENU_LAYOUT"
        android:layout="@layout/view_settings_list_item"
        android:summary="">
        <com.xxx.demo0327.setting.RadioButtonPreference
            android:key="@string/ID_SETTINGS_KEY_MENU_LAYOUT"
            app:widgetLayout="@layout/preference_widget_radiobutton"
            android:icon="@drawable/settings_general"
            app:defaultValue="0"
            android:title="@string/ID_SETTINGS_MENU_LAYOUT_SIDE"/>
        <com.xxx.demo0327.setting.RadioButtonPreference
            android:key="@string/ID_SETTINGS_KEY_MENU_LAYOUT"
            app:defaultValue="1"
            app:widgetLayout="@layout/preference_widget_radiobutton"
            android:title="@string/ID_SETTINGS_MENU_LAYOUT_TILE"/>
    </androidx.preference.PreferenceScreen>

代碼

import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.TypedArray;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.View;
import android.widget.Checkable;
import androidx.preference.Preference;
import androidx.preference.PreferenceViewHolder;


public class RadioButtonPreference extends Preference implements SharedPreferences.OnSharedPreferenceChangeListener{

    public RadioButtonPreference(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override//給每個選項設置一個defaultValue,用來判斷選中的是哪個
    protected String onGetDefaultValue(TypedArray a, int index) {
        value=a.getString(index);
        return value;
    }

    private String value; 

    public String getValue(){
      return   getPreferenceManager().getSharedPreferences().getString(getKey(),"0");
    }
    public void saveValue(){
        getPreferenceManager().getSharedPreferences().edit().putString(getKey(),value).commit();
    }

    @Override
    public void onAttached() {
        super.onAttached();
        getPreferenceManager().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
    }

    @Override
    public void onDetached() {
        super.onDetached();
        getPreferenceManager().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
    }
    @Override
    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {

        if (TextUtils.equals(getKey(),key)&&view!=null&&view instanceof Checkable) {
            ((Checkable) view).setChecked(TextUtils.equals(getValue(),value));
        }
//單選的preference大家的key都一樣侯养,所以監(jiān)聽下改變,修改自己的radioButton的狀態(tài)即可
    }
    @Override
    protected void onClick() {
        super.onClick();//點擊的時候還繼續(xù)是選中狀態(tài)
        saveValue();
        if (view!=null&&view instanceof Checkable) {
            ((Checkable) view).setChecked(true);
        }
    }
    View view;
    @Override
    public void onBindViewHolder(PreferenceViewHolder holder) {
        super.onBindViewHolder(holder);
         view=holder.findViewById(android.R.id.checkbox);
        if (view instanceof Checkable) {
            ((Checkable) view).setChecked(TextUtils.equals(getValue(),value));
        }
    }

}

這里點擊以后頁面不消失的澄干,如果你點擊以后想退回上個頁面逛揩,那么在fragment里處理即可,
如下每個preference點擊都會走這里,可以判斷下然后做處理

override fun onPreferenceTreeClick(preference: Preference?): Boolean 

前邊的icon不設置麸俘,在pad上也占位的問題

新的這種preference辩稽,前邊的icon,就算不設置它也會占位的从媚,代碼如下

            if (mIcon != null) {
                imageView.setVisibility(View.VISIBLE);
            } else {
                imageView.setVisibility(mIconSpaceReserved ? View.INVISIBLE : View.GONE);
            }

查下默認值iconSpaceReserved在pad上默認是true逞泄,我測試機就是pad
你可以在自定義style里改,也可以在xml里改

    <style name="Preference.Material">
        <item name="android:layout">@layout/preference_material</item>
        <item name="allowDividerAbove">false</item>
        <item name="allowDividerBelow">true</item>
        <item name="singleLineTitle">false</item>
        <item name="iconSpaceReserved">@bool/config_materialPreferenceIconSpaceReserved</item>
    </style>
image.png

暫時不研究這個了拜效,先把已有的代碼貼下

class SettingFragment : PreferenceFragmentCompat() ,SharedPreferences.OnSharedPreferenceChangeListener{


    override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
//加載xml文件
        addPreferencesFromResource(R.xml.setting_preference)
    }

    override fun onResume() {
        super.onResume()
        preferenceManager.sharedPreferences.registerOnSharedPreferenceChangeListener(this)
    }

    override fun onPause() {
        super.onPause()
        preferenceManager.sharedPreferences.unregisterOnSharedPreferenceChangeListener(this)
    }

    override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) {
        println("change==========$key=====${findPreference(getString(R.string.ID_SETTINGS_KEY_MENU_LAYOUT)).title}")
        if(TextUtils.equals(key,getString(R.string.ID_SETTINGS_KEY_MENU_LAYOUT))){    findPreference(getString(R.string.ID_SETTINGS_KEY_MENU_LAYOUT)).setSummary(sharedPreferences.getString(key,"-1"))
        }
    }

    override fun onPreferenceTreeClick(preference: Preference?): Boolean {
        val result=super.onPreferenceTreeClick(preference);
        println("onPreferenceTreeClick====$result==========$preference")

        return result
    }
//對于Preference下邊有子元素的喷众,點擊的時候會走這里,然后我們就可以設置跳轉【其實就是加載新的preference】
    override fun onNavigateToScreen(preferenceScreen: PreferenceScreen?) {

        super.onNavigateToScreen(preferenceScreen)
        println("onNavigateToScreen============$preferenceScreen====${preferenceScreen?.preferenceCount}")
        setPreferenceScreen(preferenceScreen)
        (activity as SettingActivity).changeTitle(preferenceScreen?.title?:"")//修改acitivity的標題
    }

//activity的onbackPress調用這個方法判斷是否需要關閉頁面
    fun handledBack():Boolean{
        println("handledBack==================${preferenceScreen.parent}")
        return handleParent(preferenceScreen.parent)
    }

//根據當前展示的preference紧憾,判斷parent是否是PreferenceScreen到千,是的話展示parent
    fun handleParent(preferenceGroup: PreferenceGroup?):Boolean{
        if(preferenceGroup==null) return false
        if(preferenceGroup is PreferenceScreen){
            preferenceScreen=preferenceGroup;
            (activity as SettingActivity).changeTitle(preferenceScreen?.title?:"")
            return true;
        }
        if(preferenceGroup is PreferenceCategory){
           return handleParent(preferenceGroup.parent)
        }
        return false;
    }
}

xml文件,主要就寫了第一個赴穗,下邊還有2層可以點憔四,其他幾個沒寫

<?xml version="1.0" encoding="utf-8"?>
<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:title="@string/ID_SETTINGS_TITLE">

<androidx.preference.PreferenceScreen
    android:title="@string/ID_SETTINGS_GENERAL"
    android:layout="@layout/view_settings_list_item"
    app:allowDividerBelow="true"
    android:icon="@drawable/settings_general">
    <!--Audio-->
    <androidx.preference.PreferenceScreen
        android:title="@string/ID_SETTINGS_AUDIO"
        app:iconSpaceReserved="false"
        android:layout="@layout/view_settings_list_item">
        <androidx.preference.SeekBarPreference
            android:key="@string/ID_SETTINGS_KEY_VOLUME"
            android:title="@string/ID_SETTINGS_AUDIO_VOLUME"/>
        <androidx.preference.SwitchPreference
            android:key="@string/ID_SETTINGS_KEY_TOUCH_AUDIO"
            android:title="@string/ID_SETTINGS_AUDIO_TOUCH_AUDIO"/>
    </androidx.preference.PreferenceScreen>


    <!--Menu layout-->
    <androidx.preference.PreferenceScreen
        android:key="@string/ID_SETTINGS_KEY_MENU_LAYOUT"
        android:title="@string/ID_SETTINGS_MENU_LAYOUT"
        android:layout="@layout/view_settings_list_item"
        android:summary="">
        <com.charliesong.demo0327.setting.RadioButtonPreference
            android:key="@string/ID_SETTINGS_KEY_MENU_LAYOUT"
            app:widgetLayout="@layout/preference_widget_radiobutton"
            android:icon="@drawable/settings_general"
            app:defaultValue="0"
            android:title="@string/ID_SETTINGS_MENU_LAYOUT_SIDE"/>
        <com.charliesong.demo0327.setting.RadioButtonPreference
            android:key="@string/ID_SETTINGS_KEY_MENU_LAYOUT"
            app:defaultValue="1"
            app:widgetLayout="@layout/preference_widget_radiobutton"
            android:title="@string/ID_SETTINGS_MENU_LAYOUT_TILE"/>
    </androidx.preference.PreferenceScreen>
    <androidx.preference.ListPreference
        android:entries="@array/ID_SETTING_MENU_ARRAY"
        android:entryValues="@array/ID_SETTING_MENU_ARRAY_VALUE"
        android:defaultValue="0"
        android:title="single choice"
        android:key="@string/ID_SETTINGS_KEY_MENU_LAYOUT2"/>

    <androidx.preference.PreferenceCategory android:title="category">
        <androidx.preference.PreferenceScreen
            android:icon="@drawable/settings_general"
            android:title="test1"
            app:layout="@layout/view_settings_list_item">
            <androidx.preference.CheckBoxPreference
                android:icon="@drawable/i_settings_wifi_0"
                android:key="wifiauto"
                android:title="auto" />
            <androidx.preference.SwitchPreference
                android:icon="@drawable/i_settings_wifi_4"
                android:key="wifi111"
                android:title="wifi" />
        </androidx.preference.PreferenceScreen>
    </androidx.preference.PreferenceCategory>
</androidx.preference.PreferenceScreen>


    <androidx.preference.PreferenceScreen
        android:title="@string/ID_SETTINGS_MAPS"
        app:allowDividerAbove="true"
        android:layout="@layout/view_settings_list_item"
        android:icon="@drawable/settings_maps">

    </androidx.preference.PreferenceScreen>


</androidx.preference.PreferenceScreen>

xml里Preference的顯示順序

有這樣一個布局,那個my_device_info_header 根據order的不同,顯示的位置也不同般眉,這個邏輯到底是啥樣的了赵。其他兩個PreferenceCategory沒有設置order。
第一個Preference設置order為負值甸赃,它就顯示在第一個位置柿汛,
如果order為0,那么顯示在第二個位置埠对,
為1顯示在第三個位置

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:settings="http://schemas.android.com/apk/res-auto"
    android:key="my_device_info_pref_screen"
    android:title="about_settings">

    <Preference
        android:key="my_device_info_header"
        android:layout="@layout/settings_entity_header"
        android:order="0"
        android:selectable="false" />

    <PreferenceCategory
        android:key="basic_info_category"
        android:selectable="false"
        android:title="my_device_info_basic_info_category_title">
    </PreferenceCategory>
    <PreferenceCategory android:title="my_device_info_legal_category_title">
    </PreferenceCategory>

首先默認的order如下,在Preference類里

    public static final int DEFAULT_ORDER = Integer.MAX_VALUE;
    private int mOrder = DEFAULT_ORDER;

    public int getOrder() {
        return mOrder;
    }
//排序的話苛茂,先比較order已烤,一樣的話再看title
    public int compareTo(@NonNull Preference another) {
        if (mOrder != another.mOrder) {
            // Do order comparison
            return mOrder - another.mOrder;
        } else if (mTitle == another.mTitle) {
            // If titles are null or share same object comparison
            return 0;
        } else if (mTitle == null) {
            return 1;
        } else if (another.mTitle == null) {
            return -1;
        } else {
            // Do name comparison
            return mTitle.toString().compareToIgnoreCase(another.mTitle.toString());
        }
    }

查下哪里用到這個getOrder,在PreferenceGroup類里

    public boolean addPreference(@NonNull Preference preference) {
        if (mPreferences.contains(preference)) {
            return true;
        }
//...

        if (preference.getOrder() == DEFAULT_ORDER) {
            if (mOrderingAsAdded) {//這個默認是true妓羊,除非你在xml里設置
                preference.setOrder(mCurrentPreferenceOrder++);//默認是0
            }
//...
        }

        int insertionIndex = Collections.binarySearch(mPreferences, preference);
        if (insertionIndex < 0) {
            insertionIndex = insertionIndex * -1 - 1;
        }
        synchronized (this) {
            mPreferences.add(insertionIndex, preference);
        }

分析上邊的代碼胯究,可以看到集合數據mPreferences的插入順序,主要看索引insertionIndex躁绸。
如果preference有設置order的話裕循,那就用自己的order,如果沒有設置的話净刮,那么按照順序設置order(從0開始增加剥哑,這里主要看binarySearch這個方法了。

    int binarySearch(List<? extends Comparable<? super T>> list, T key) {
        if (list instanceof RandomAccess || list.size()<BINARYSEARCH_THRESHOLD)
            return Collections.indexedBinarySearch(list, key);
        else
            return Collections.iteratorBinarySearch(list, key);
    }

    private static <T>
    int indexedBinarySearch(List<? extends Comparable<? super T>> list, T key) {
        int low = 0;
        int high = list.size()-1;

        while (low <= high) {
            int mid = (low + high) >>> 1;
            Comparable<? super T> midVal = list.get(mid);
            int cmp = midVal.compareTo(key);

            if (cmp < 0)
                low = mid + 1;
            else if (cmp > 0)
                high = mid - 1;
            else
                return mid; // key found
        }
        return -(low + 1);  // key not found
    }

這里舉例說明:
第一個Preference的order是0淹父,后邊兩個沒設置order株婴,按照代碼里的邏輯,會自動為order賦值為0和1. xml里的順序為 A(0),B(0),C(1) 暑认,括弧里為order的值困介,ABC分別表示xml里的3個Preference。
解析第一個A(0), 集合長度為0蘸际,所以low=0,high=-1,while不滿足,返回-1 座哩,根據

        if (insertionIndex < 0) {
            insertionIndex = insertionIndex * -1 - 1;
        }

所以A的insertionIndex 為-1*-1-1也就是0.
此時集合里數據為 [A0]
解析第二個B(0), 集合長度為1,所以low=0,high=0,mid=0, mid取出來的就是A0粮彤,根據比較規(guī)則根穷,因為A0的title為null,所以cmp=1导坟,high為-1屿良,跳出循環(huán),返回-1.同上B的insertionIndex 為0.所以B0插入在A0前邊惫周。
此時集合里的數據為 [B0,A0]
解析第三個C1,集合長度為2管引,所以low=0,high=1,mid=0,mid取出來的就是B0,根據比較規(guī)則,cmp為-1闯两,所以low變?yōu)?褥伴,mid也成了1,取出的值為A0漾狼,和C1比較重慢,cmp為-1,此時low變?yōu)?.跳出循環(huán)逊躁,返回-3似踱,根據if條件,insertionIndex最終為2.
此時集合里的數據為 [B0,A0,C1]

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市核芽,隨后出現的幾起案子囚戚,更是在濱河造成了極大的恐慌,老刑警劉巖轧简,帶你破解...
    沈念sama閱讀 216,496評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件驰坊,死亡現場離奇詭異,居然都是意外死亡哮独,警方通過查閱死者的電腦和手機拳芙,發(fā)現死者居然都...
    沈念sama閱讀 92,407評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來皮璧,“玉大人舟扎,你說我怎么就攤上這事°参瘢” “怎么了睹限?”我有些...
    開封第一講書人閱讀 162,632評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長讯檐。 經常有香客問我羡疗,道長,這世上最難降的妖魔是什么裂垦? 我笑而不...
    開封第一講書人閱讀 58,180評論 1 292
  • 正文 為了忘掉前任顺囊,我火速辦了婚禮肌索,結果婚禮上蕉拢,老公的妹妹穿的比我還像新娘。我一直安慰自己诚亚,他們只是感情好晕换,可當我...
    茶點故事閱讀 67,198評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著站宗,像睡著了一般闸准。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上梢灭,一...
    開封第一講書人閱讀 51,165評論 1 299
  • 那天夷家,我揣著相機與錄音,去河邊找鬼敏释。 笑死库快,一個胖子當著我的面吹牛,可吹牛的內容都是我干的钥顽。 我是一名探鬼主播义屏,決...
    沈念sama閱讀 40,052評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了闽铐?” 一聲冷哼從身側響起蝶怔,我...
    開封第一講書人閱讀 38,910評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎兄墅,沒想到半個月后踢星,有當地人在樹林里發(fā)現了一具尸體,經...
    沈念sama閱讀 45,324評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡察迟,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,542評論 2 332
  • 正文 我和宋清朗相戀三年斩狱,在試婚紗的時候發(fā)現自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片扎瓶。...
    茶點故事閱讀 39,711評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡所踊,死狀恐怖,靈堂內的尸體忽然破棺而出概荷,到底是詐尸還是另有隱情秕岛,我是刑警寧澤,帶...
    沈念sama閱讀 35,424評論 5 343
  • 正文 年R本政府宣布误证,位于F島的核電站继薛,受9級特大地震影響,放射性物質發(fā)生泄漏愈捅。R本人自食惡果不足惜遏考,卻給世界環(huán)境...
    茶點故事閱讀 41,017評論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望蓝谨。 院中可真熱鬧灌具,春花似錦、人聲如沸譬巫。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,668評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽芦昔。三九已至诱贿,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間咕缎,已是汗流浹背珠十。 一陣腳步聲響...
    開封第一講書人閱讀 32,823評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留凭豪,地道東北人焙蹭。 一個月前我還...
    沈念sama閱讀 47,722評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像墅诡,于是被迫代替她去往敵國和親壳嚎。 傳聞我的和親對象是個殘疾皇子桐智,可洞房花燭夜當晚...
    茶點故事閱讀 44,611評論 2 353

推薦閱讀更多精彩內容

  • 我媽媽年輕的時候就喜歡看小說,特別是瓊瑤阿姨的書烟馅,我也受到媽媽的影響说庭,從小學就開始看小說,其中最先讀到的就是家里面...
    汐堇年閱讀 266評論 0 2
  • 前言 前段時間在泡網上看到這個文章傳送門郑趁,對于客戶端開發(fā)而言刊驴,實現各種奇奇怪怪的UI效果也是常態(tài),動畫更是點睛之筆...
    貍小華閱讀 5,431評論 6 11
  • 我們雖然都生活在同一個城市寡润,但卻過著截然不同的生活捆憎。遇見你,我才知道什么是青春梭纹。
    旻子826閱讀 163評論 0 0
  • 雨变抽,滴滴答答地掉落在青瓦沿上捌显,高高低低的回響碍庵。透過古舊的窗格望出去聘鳞,斑駁的白墻落寞的佇立在雨里两波,寂靜無語。 宏村击儡,...
    余葉子閱讀 595評論 10 17
  • 詠荊軻(其一) 衛(wèi)客報強秦塔沃,吳鉤三尺寒。 狗屠筑前橫阳谍,和泣正酒酣蛀柴。 燕丹奉賓客,當保金甌全边坤。 俠者如曹...
    灼灼新桃閱讀 243評論 0 1