Android 5.1系统源码Wifi模块中wifiConfigController源码分析

之前看了WifiSettings的源码,大概理解了之后,在点击AP的时候,会显示对应的dialog,

然后经过我查看代码和别人的帮助的情况下,我发现WifiConfigController.java写的还是

很有意思的,简单的总结一下!

  无论是新增网络(add Network),还是点击未连接的ap,还是已经连接的ap,其实用的都是

同一个布局文件,只是通过判断对布局中的控件设置visibility。进而显示不同的界面

在wifiSettings中showdialog的位置:

点击add network

946    /**
947     * Called when "add network" button is pressed.
948     */
949    /* package */ void onAddNetworkPressed() {
950        // No exact access point is selected.
951        mSelectedAccessPoint = null;
952        showDialog(null, true);
953    }

比如连接,修改,之类的都是showdialog,点击ap也会showdialog

点击ap的事件

567    @Override
568    public boolean onPreferenceTreeClick(PreferenceScreen screen, Preference preference) {
569        if (preference instanceof AccessPoint) {
                  ......
581            } else {
582                showDialog(mSelectedAccessPoint, false);
583            }
584        } else {
585            return super.onPreferenceTreeClick(screen, preference);
586        }
587        return true;
588    }

在onCreateDialog会调用showdialog
<pre name="code" class="java">590    private void showDialog(AccessPoint accessPoint, boolean edit) {
                 ......
600        showDialog(WIFI_DIALOG_ID);
601    }
602
603    @Override
604    public Dialog onCreateDialog(int dialogId) {
605        switch (dialogId) {
606            case WIFI_DIALOG_ID:
607                AccessPoint ap = mDlgAccessPoint; // For manual launch
608                if (ap == null) { // For re-launch from saved state
609                    if (mAccessPointSavedState != null) {
610                        ap = new AccessPoint(getActivity(), mAccessPointSavedState);
611                        // For repeated orientation changes
612                        mDlgAccessPoint = ap;
613                        // Reset the saved access point data
614                        mAccessPointSavedState = null;
615                    }
616                }
617                // If it's null, fine, it's for Add Network
618                mSelectedAccessPoint = ap;
619                mDialog = new WifiDialog(getActivity(), this, ap, mDlgEdit);
620                return mDialog;
                         ......
631
632        }
633        return super.onCreateDialog(dialogId);
634    }

之后调用
WifiDialog类,在自定义的wifiDialog中又调用了wifiConfigController,代码如下

  @Override
61    protected void onCreate(Bundle savedInstanceState) {
62        mView = getLayoutInflater().inflate(R.layout.wifi_dialog, null);
63        setView(mView);
64        setInverseBackgroundForced(true);
65        mController = new WifiConfigController(this, mView, mAccessPoint, mEdit);
66        super.onCreate(savedInstanceState);
67
68        if (mHideSubmitButton) {
69            mController.hideSubmitButton();
70        } else {
71            /* During creation, the submit button can be unavailable to determine
72             * visibility. Right after creation, update button visibility */
73            mController.enableSubmitIfAppropriate();
74        }
75    }

<pre name="code" class="java"><span style="color:#FF0000;">WifiConfigController类有1000多行的代码,记录一下自己的学习</span>

1.布局中出现的EditText,这里都先强转成了TextView,(TextView为EditText的父类)如果需要EditText独有的方法的时候,再强转一下就行了例如:对于密码框,在 showSecurityFields()中有初始化

627        if (mPasswordView == null) {
628          mPasswordView = (TextView) mView.findViewById(R.id.password);
629            mPasswordView.addTextChangedListener(this);
630            ((CheckBox) mView.findViewById(R.id.show_password))
631                .setOnCheckedChangeListener(this);               //对于checkbox增加监听
632
633            if (mAccessPoint != null && mAccessPoint.networkId != INVALID_NETWORK_ID) {
634                mPasswordView.setHint(R.string.wifi_unchanged);
635            }
636        }

在判断是否密码可见的时候:

959    @Override
960    public void onCheckedChanged(CompoundButton view, boolean isChecked) {
961        if (view.getId() == R.id.show_password) {
962            int pos = mPasswordView.getSelectionEnd();
963            mPasswordView.setInputType(                                                      //通过判断是否选择checkbox来改变输入类型
964                    InputType.TYPE_CLASS_TEXT | (isChecked ?
965                            InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD :   //为可见密码
966                                InputType.TYPE_TEXT_VARIATION_PASSWORD));
967            if (pos >= 0) {
968                ((EditText)mPasswordView).setSelection(pos);                      //需要用到自己的方法进行了强转
969            }
970        } else if (view.getId() == R.id.wifi_advanced_togglebox) {                    //这是另外一个checkbox
971            if (isChecked) {
972                mView.findViewById(R.id.wifi_advanced_fields).setVisibility(View.VISIBLE);
973            } else {
974                mView.findViewById(R.id.wifi_advanced_fields).setVisibility(View.GONE);
975            }
976        }
977    }

2方法的复用,因为对于同一个布局需要有不同的显示,对控件的visibility的控制就需要很大的代码量,源码中写了这么一个方法

897    private void setVisibility(int id, int visibility) {   //根据id和设置visibility设置对应的控件的可见性
898        final View v = mView.findViewById(id);
899        if (v != null) {
900            v.setVisibility(visibility);
901        }
902    }

说到可见性,不得不说的就是visibility,invisibility,gone的区别

visibility为可见
invisibility不可见,但是会占据一定的空间
gone为消失,不会占据空间(这个学过的js一样啊)
这就保证了不同控件的在同一个布局中的不同显示了

先学习到这了,之后再补充了======================分割线====================

    原文作者:Android源码分析
    原文地址: https://blog.csdn.net/leafact/article/details/44942263
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞