androidQ 设置模块分析--二级菜单--蓝牙(开关)

二级菜单UI:

SettingsActivity类:

private SwitchBar mSwitchBar;
protected void onCreate(Bundle savedState) {
...
setContentView(R.layout.settings_main_prefs);//加载布局
...
mSwitchBar = findViewById(R.id.switch_bar);//开关 switchbar
...
}

settings_main_prefs内容如下:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_height="match_parent"
              android:layout_width="match_parent">
<!--开关-->
    <com.android.settings.widget.SwitchBar
        android:id="@+id/switch_bar"
        android:layout_height="?android:attr/actionBarSize"
        android:layout_width="match_parent"
        android:theme="?attr/switchBarTheme"/>

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

    <RelativeLayout android:id="@+id/button_bar"
                    android:layout_height="wrap_content"
                    android:layout_width="match_parent"
                    android:layout_weight="0"
                    android:visibility="gone">

        <Button android:id="@+id/back_button"
                android:layout_width="150dip"
                android:layout_height="wrap_content"
                android:layout_margin="5dip"
                android:layout_alignParentStart="true"
                android:text="@*android:string/back_button_label"/>

        <LinearLayout
                android:orientation="horizontal"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentEnd="true">

            <Button android:id="@+id/skip_button"
                    android:layout_width="150dip"
                    android:layout_height="wrap_content"
                    android:layout_margin="5dip"
                    android:text="@*android:string/skip_button_label"
                    android:visibility="gone"/>

            <Button android:id="@+id/next_button"
                    android:layout_width="150dip"
                    android:layout_height="wrap_content"
                    android:layout_margin="5dip"
                    android:text="@*android:string/next_button_label"/>

        </LinearLayout>

    </RelativeLayout>

</LinearLayout>

SwitchBar类:

定义了一个接口

public class SwitchBar extends LinearLayout implements CompoundButton.OnCheckedChangeListener {

    public interface OnSwitchChangeListener {
        void onSwitchChanged(Switch switchView, boolean isChecked);
    }

蓝牙的入口是放在《已连接设备》菜单里的:

connected_devices_advanced.xml:

<PreferenceScreen
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:settings="http://schemas.android.com/apk/res-auto"
    android:key="connected_devices_advanced_screen"
    android:title="@string/connected_device_connections_title">

    <Preference
        android:fragment="com.android.settings.connecteddevice.BluetoothDashboardFragment"
        android:key="bluetooth_settings"
        android:title="@string/bluetooth_settings_title"
        android:icon="@*android:drawable/ic_settings_bluetooth"
        android:order="-9"
        settings:searchable="false"/>

    <Preference
        android:fragment="com.mediatek.nfc.NfcSettings"
        android:key="toggle_mtk_nfc"
        android:title="@string/nfc_quick_toggle_title"
        android:icon="@drawable/ic_nfc"
        android:order="-6"/>

    <SwitchPreference
        android:key="toggle_nfc"
        android:title="@string/nfc_quick_toggle_title"
        android:icon="@drawable/ic_nfc"
        android:summary="@string/nfc_quick_toggle_summary"
        settings:controller="com.android.settings.nfc.NfcPreferenceController"
        android:order="-7"/>

    <com.android.settingslib.RestrictedPreference
        android:fragment="com.android.settings.nfc.AndroidBeam"
        android:key="android_beam_settings"
        android:title="@string/android_beam_settings_title"
        settings:controller="com.android.settings.nfc.AndroidBeamPreferenceController"
        android:icon="@drawable/ic_android"
        android:order="-6"/>

    <SwitchPreference
        android:key="nfc_secure_settings"
        android:title="@string/nfc_secure_settings_title"
        settings:controller="com.android.settings.nfc.SecureNfcPreferenceController"
        android:icon="@drawable/ic_nfc"
        android:summary="@string/nfc_secure_toggle_summary"
        android:order="-7"/>

    <com.android.settingslib.RestrictedPreference
        android:key="connected_device_printing"
        android:title="@string/print_settings"
        android:summary="@string/summary_placeholder"
        android:icon="@*android:drawable/ic_settings_print"
        android:fragment="com.android.settings.print.PrintSettingsFragment"
        android:order="-3"
        settings:searchable="false"/>

    <Preference
        android:key="bt_received_files"
        android:icon="@drawable/ic_folder_vd_theme_24"
        android:title="@string/bluetooth_show_files_received_via_bluetooth"/>

    <PreferenceCategory
        android:key="dashboard_tile_placeholder"
        android:order="-8"/>

</PreferenceScreen>

对应的fragment是BluetoothDashboardFragment。

BluetoothDashboardFragment类:

public class BluetoothDashboardFragment extends DashboardFragment {
    ...
    private SwitchBar mSwitchBar;
    private BluetoothSwitchPreferenceController mController;

        ...

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    
    SettingsActivity activity = (SettingsActivity) getActivity();
    mSwitchBar = activity.getSwitchBar();
    mController = new BluetoothSwitchPreferenceController(activity,
            new SwitchBarController(mSwitchBar), mFooterPreference);
    ...
}

...

BluetoothDashboardFragment有一个成员变量是BluetoothSwitchPreferenceController,这个BluetoothSwitchPreferenceController的构造函数有一个SwitchBarController,SwitchBarController的构造函数又需要一个mSwitchBar,这里的mSwitchBar可以看出来,就是SettingsActivity的SwitchBar。

BluetoothSwitchPreferenceController类:

public class BluetoothSwitchPreferenceController
        implements LifecycleObserver, OnStart, OnStop,
        SwitchWidgetController.OnSwitchChangeListener, View.OnClickListener {

BluetoothSwitchPreferenceController实现了SwitchWidgetController.OnSwitchChangeListener的接口

public abstract class SwitchWidgetController {

    protected OnSwitchChangeListener mListener;

  ...
    public interface OnSwitchChangeListener {
      ...
        boolean onSwitchToggled(boolean isChecked);
    }

...

    @VisibleForTesting
    public BluetoothSwitchPreferenceController(Context context, RestrictionUtils restrictionUtils,
            SwitchWidgetController switchController, FooterPreference footerPreference) {
        mRestrictionUtils = restrictionUtils;
        mSwitch = switchController;
        mContext = context;
        mFooterPreference = footerPreference;

        mSwitch.setupView();
        updateText(mSwitch.isChecked());

        mBluetoothEnabler = new BluetoothEnabler(context,
                switchController,
                FeatureFactory.getFactory(context).getMetricsFeatureProvider(),
                SettingsEnums.ACTION_SETTINGS_MASTER_SWITCH_BLUETOOTH_TOGGLE,
                mRestrictionUtils);
        mBluetoothEnabler.setToggleCallback(this);

    }

而SwitchWidgetController类是一个抽象类,而且它还定义了一个接口OnSwitchChangeListener,接口只有一个onSwitchToggled的方法。而我们的BluetoothSwitchPreferenceController实现了这个接口方法。这个onSwitchToggled在什么时候调用?

再看BluetoothSwitchPreferenceController的构造函数,它创建了一个BluetoothEnabler的对象,把从BluetoothDashboardFragment传过来的switchController做为参数。并将自己通过mBluetoothEnabler.setToggleCallback(this);设置进去。

BluetoothEnabler类:
public final class BluetoothEnabler implements SwitchWidgetController.OnSwitchChangeListener {
...
 SwitchWidgetController mSwitchController;
 public BluetoothEnabler(Context context, SwitchWidgetController switchController,
            MetricsFeatureProvider metricsFeatureProvider, int metricsEvent,
            RestrictionUtils restrictionUtils) {
        mContext = context;
        mMetricsFeatureProvider = metricsFeatureProvider;
        mSwitchController = switchController;
        mSwitchController.setListener(this);
...
public void setToggleCallback(SwitchWidgetController.OnSwitchChangeListener listener) {
    mCallback = listener;
}

...

BluetoothEnabler也实现了SwitchWidgetController.OnSwitchChangeListener接口方法onSwitchToggled,它又把自己设置成了

mSwitchController的listener。

SwitchBarController类:

public class SwitchBarController extends SwitchWidgetController implements
    SwitchBar.OnSwitchChangeListener {

    private final SwitchBar mSwitchBar;

...

@Override
public void onSwitchChanged(Switch switchView, boolean isChecked) {
    if (mListener != null) {
        mListener.onSwitchToggled(isChecked);
    }
}

...

当switch的状态发生变化时,会调用监听者的onSwitchToggled函数,也就是BluetoothEnabler自己。

BluetoothEnabler的onSwitchToggled函数如下:

@Override
public boolean onSwitchToggled(boolean isChecked) {
    if (maybeEnforceRestrictions()) {
        triggerParentPreferenceCallback(isChecked);
        return true;
    }
    Log.d(TAG, "onSwitchChanged to " + isChecked);
    // Show toast message if Bluetooth is not allowed in airplane mode
    if (isChecked &&
            !WirelessUtils.isRadioAllowed(mContext, Settings.Global.RADIO_BLUETOOTH)) {
        Toast.makeText(mContext, R.string.wifi_in_airplane_mode, Toast.LENGTH_SHORT).show();
        // Reset switch to off
        mSwitchController.setChecked(false);
        triggerParentPreferenceCallback(false);
        return false;
    }

    mMetricsFeatureProvider.action(mContext, mMetricsEvent, isChecked);

    if (mBluetoothAdapter != null) {
        boolean status = setBluetoothEnabled(isChecked);
        // If we cannot toggle it ON then reset the UI assets:
        // a) The switch should be OFF but it should still be togglable (enabled = True)
        // b) The switch bar should have OFF text.
        if (isChecked && !status) {
            mSwitchController.setChecked(false);
            mSwitchController.setEnabled(true);
            mSwitchController.updateTitle(false);
            triggerParentPreferenceCallback(false);
            return false;
        }
    }
    mSwitchController.setEnabled(false);
    triggerParentPreferenceCallback(isChecked);
    return true;
}

通过mSwitchController去更新一些状态和显示,而mSwitchController又通过自己的成员变量

mSwitchBar去更新,这个mSwitchBar就是从BluetoothDashboardFragment传过来的,也就是SettingsActivity的SwitchBar。

BluetoothEnabler还调用triggerParentPreferenceCallback去调用mCallback的onSwitchToggled:

private void triggerParentPreferenceCallback(boolean isChecked) {

if (mCallback != null) { mCallback.onSwitchToggled(isChecked); }

}

而这个mCallback就是通过 mBluetoothEnabler.setToggleCallback(this);设置的BluetoothSwitchPreferenceController,它的onSwitchToggled函数是这样的:

@Override
public boolean onSwitchToggled(boolean isChecked) {
    updateText(isChecked);
    return true;
}

只是去更新mFooterPreference的文字而已。

 

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值