日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android 4.4 Settings 应用初步分析

發布時間:2025/3/15 Android 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android 4.4 Settings 应用初步分析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一次偶然要在設置里面增加一個菜單,需要修改到settings_headers.xml 文件(res/layout/xml) 文件,所以就覺得要看一下這個流程.就做一下筆記,語言組織能力不行啊.

分析Android 源碼的時候導入單個應用的時候一般是會有很多錯誤的,因為需要導入系統編譯之后生成的jar包才能消除eclipse 里面的哪些紅色xx.

1.Settings的UI


?

?

2.流程分析

從AndroidManifest.xml 中查看

<category android:name="android.intent.category.LAUNCHER" /> 知道Settings.java 是這個應用入口activity.

?

Settings 繼承了PreferenceActivity .他的布局文件是settings_headers.xml

這個文件里面都是這些header,效果可以參考上面的效果圖1和圖2.

Xml代碼??
  • <!--?WIRELESS?and?NETWORKS??分類-->??
  • ????<header?android:id="@+id/wireless_section"??
  • ????????android:title="@string/header_category_wireless_networks"?/>??
  • ??
  • ????<!--?Sim?management?普通項-->??
  • ????<header??
  • ????????android:id="@+id/sim_settings"??
  • ????????android:icon="@drawable/ic_settings_dualsim"??
  • ????????android:fragment="com.mediatek.gemini.SimManagement"??
  • ????????android:title="@string/gemini_sim_management_title"?/>??
  • ?

    ?

    com.android.settings.Settings.java 這個activity 是通過回調onBuildHeaders方法來加載進入應用之后的第一個布局文件的,然后調用 loadHeadersFromResource(R.xml.settings_headers, headers);

    來解析 文件.

    onBuildHeaders 和loadHeadersFromResource 方法都是父類PreferenceActivity 的方法.

    ?

    Settings.java 重寫onBuildHeaders 方法的實現的源碼如下:

    Java代碼??
  • /**?
  • ?????*?Populate?the?activity?with?the?top-level?headers.?
  • ?????*/??
  • ????@Override??
  • ????public?void?onBuildHeaders(List<Header>?headers)?{??
  • ????????if?(!onIsHidingHeaders())?{??
  • ????????????PDebug.Start("loadHeadersFromResource");??
  • ????????????loadHeadersFromResource(R.xml.settings_headers,?headers);??
  • ????????????PDebug.End("loadHeadersFromResource");??
  • ????????????updateHeaderList(headers);??
  • ????????}??
  • ????}??
  • ?

    ?

    loadHeadersFromResource 方法就是解析settings_headers.xml 文件并保持相關的數據到List<Header> headers 里面.

    Header 定義很多變量來和settings_headers.xml 里面節點一一對應,

    public long id = HEADER_ID_UNDEFINED;

    public int titleRes;

    public CharSequence title;

    public String fragment;

    public Bundle fragmentArguments;

    public Intent intent;

    public Bundle extras;

    ………

    ?

    ?

    通過跟蹤Setting.java 的父類(PreferenceActivity)的繼承關系知道他其實也是一個ListActivity.java ,全部的設置項也是使用ListView來顯示的.

    ?

    HeaderAdapter這個適配類是Setting.java 的內部類,它會判斷之后來加載對應的view和數據來顯示UI.

    ?

    HeaderAdapter已經定義了4中類型的View 類型

    Java代碼??
  • static?final?int?HEADER_TYPE_CATEGORY?=?0;//用來分類的??
  • static?final?int?HEADER_TYPE_NORMAL?=?1;//常規項??
  • static?final?int?HEADER_TYPE_SWITCH?=?2;//開關項??
  • static?final?int?HEADER_TYPE_BUTTON?=?3;//按鈕項??
  • ?

    前3種應該都見過,為了讓大家看到第4項,我把稍微修改了一下我的HeaderAdapter源碼(見getview方法的中的有//add的部分),也就是上面圖2中的security 選項.

    HeaderAdapter 的getHeaderType 方法決定了配置在settings_headers.xml 里面的header的類型.

    HeaderAdapter 的getView 方法根據header的類型 來加載對應的布局文件.

    Java代碼??
  • static?int?getHeaderType(Header?header)?{??
  • ????????????if?(header.fragment?==?null?&&?header.intent?==?null)?{??
  • ????????????????return?HEADER_TYPE_CATEGORY;??
  • ????????????}?else?if?(header.id?==?R.id.wifi_settings?||?header.id?==?R.id.bluetooth_settings??
  • ?????????????????????||?header.id?==?R.id.hotknot_settings)?{??
  • ????????????????return?HEADER_TYPE_SWITCH;??
  • ????????????}?else?if?(header.id?==?R.id.security_settings)?{??
  • ????????????????return?HEADER_TYPE_BUTTON;??
  • ????????????}?else?{??
  • ????????????????return?HEADER_TYPE_NORMAL;??
  • ????????????}??
  • ????????}??
  • ?

    但要注意的是在getView方法里面,當發現一個header 的類型是button的時候也會給header 的button增加一個onclick事件的,這個事件和header本事的onHeaderClick 是沒有沖突的,因為2者不受同一個控件.

    Java代碼??
  • @Override??
  • ???????public?View?getView(int?position,?View?convertView,?ViewGroup?parent)?{??
  • ???????????HeaderViewHolder?holder;??
  • ???????????Header?header?=?getItem(position);??
  • ???????????int?headerType?=?getHeaderType(header);??
  • ???????????Log.d("zhangle","getHeaderType"?+?header.title??+?"?headerType="?+?headerType);??
  • ???????????View?view?=?null;??
  • ??
  • ???????????if?(convertView?==?null)?{??
  • ???????????????holder?=?new?HeaderViewHolder();??
  • ???????????????switch?(headerType)?{??
  • ???????????????????case?HEADER_TYPE_CATEGORY:??
  • ???????????????????????view?=?new?TextView(getContext(),?null,??
  • ???????????????????????????????android.R.attr.listSeparatorTextViewStyle);??
  • ???????????????????????holder.title?=?(TextView)?view;??
  • ???????????????????????break;??
  • ??
  • ???????????????????case?HEADER_TYPE_SWITCH:??
  • ???????????????????????view?=?mInflater.inflate(R.layout.preference_header_switch_item,?parent,??
  • ???????????????????????????????false);??
  • ???????????????????????holder.icon?=?(ImageView)?view.findViewById(R.id.icon);??
  • ???????????????????????holder.title?=?(TextView)??
  • ???????????????????????????????view.findViewById(com.android.internal.R.id.title);??
  • ???????????????????????holder.summary?=?(TextView)??
  • ???????????????????????????????view.findViewById(com.android.internal.R.id.summary);??
  • ???????????????????????holder.switch_?=?(Switch)?view.findViewById(R.id.switchWidget);??
  • ???????????????????????break;??
  • ??
  • ???????????????????case?HEADER_TYPE_BUTTON:??
  • ???????????????????????view?=?mInflater.inflate(R.layout.preference_header_button_item,?parent,??
  • ???????????????????????????????false);??
  • ???????????????????????holder.icon?=?(ImageView)?view.findViewById(R.id.icon);??
  • ???????????????????????holder.title?=?(TextView)??
  • ???????????????????????????????view.findViewById(com.android.internal.R.id.title);??
  • ???????????????????????holder.summary?=?(TextView)??
  • ???????????????????????????????view.findViewById(com.android.internal.R.id.summary);??
  • ???????????????????????holder.button_?=?(ImageButton)?view.findViewById(R.id.buttonWidget);??
  • ???????????????????????holder.divider_?=?view.findViewById(R.id.divider);??
  • ???????????????????????break;??
  • ??
  • ???????????????????case?HEADER_TYPE_NORMAL:??
  • ???????????????????????view?=?mInflater.inflate(??
  • ???????????????????????????????R.layout.preference_header_item,?parent,??
  • ???????????????????????????????false);??
  • ???????????????????????holder.icon?=?(ImageView)?view.findViewById(R.id.icon);??
  • ???????????????????????holder.title?=?(TextView)??
  • ???????????????????????????????view.findViewById(com.android.internal.R.id.title);??
  • ???????????????????????holder.summary?=?(TextView)??
  • ???????????????????????????????view.findViewById(com.android.internal.R.id.summary);??
  • ???????????????????????break;??
  • ???????????????}??
  • ???????????????view.setTag(holder);??
  • ???????????}?else?{??
  • ???????????????view?=?convertView;??
  • ???????????????holder?=?(HeaderViewHolder)?view.getTag();??
  • ???????????}??
  • ??
  • ???????????//?All?view?fields?must?be?updated?every?time,?because?the?view?may?be?recycled??
  • ???????????switch?(headerType)?{??
  • ???????????????case?HEADER_TYPE_CATEGORY:??
  • ???????????????????holder.title.setText(header.getTitle(getContext().getResources()));??
  • ???????????????????break;??
  • ??
  • ???????????????case?HEADER_TYPE_SWITCH:??
  • ???????????????????//?Would?need?a?different?treatment?if?the?main?menu?had?more?switches??
  • ???????????????????if?(header.id?==?R.id.wifi_settings)?{??
  • ???????????????????????mWifiEnabler.setSwitch(holder.switch_);??
  • ???????????????????}?else?if?(header.id?==?R.id.bluetooth_settings){??
  • ???????????????????????mBluetoothEnabler.setSwitch(holder.switch_);??
  • ???????????????????}?else?if?(header.id?==?R.id.hotknot_settings){??
  • ???????????????????????mHotKnotEnabler.setSwitch(holder.switch_);??
  • ???????????????????}??
  • ???????????????????updateCommonHeaderView(header,?holder);??
  • ???????????????????break;??
  • ??
  • ???????????????case?HEADER_TYPE_BUTTON:??
  • ???????????????????if?(header.id?==?R.id.security_settings)?{??
  • ???????????????????????boolean?hasCert?=?DevicePolicyManager.hasAnyCaCertsInstalled();??
  • ???????????????????????hasCert?=?true;//add??
  • ???????????????????????if?(hasCert)?{??
  • ???????????????????????????holder.button_.setVisibility(View.VISIBLE);??
  • ???????????????????????????holder.divider_.setVisibility(View.VISIBLE);??
  • ???????????????????????????boolean?isManaged?=?mDevicePolicyManager.getDeviceOwner()?!=?null;??
  • ???????????????????????????isManaged?=?true;?//add??
  • ???????????????????????????if?(isManaged)?{??
  • ???????????????????????????????holder.button_.setImageResource(R.drawable.ic_settings_about);??
  • ???????????????????????????}?else?{??
  • ???????????????????????????????holder.button_.setImageResource(??
  • ???????????????????????????????????????android.R.drawable.stat_notify_error);??
  • ???????????????????????????}??
  • ???????????????????????????holder.button_.setOnClickListener(new?OnClickListener()?{??
  • ???????????????????????????????@Override??
  • ???????????????????????????????public?void?onClick(View?v)?{??
  • ???????????????????????????????????Intent?intent?=?new?Intent(??
  • ???????????????????????????????????????????android.provider.Settings.ACTION_MONITORING_CERT_INFO);??
  • ???????????????????????????????????getContext().startActivity(intent);??
  • ???????????????????????????????}??
  • ???????????????????????????});??
  • ???????????????????????}?else?{??
  • ???????????????????????????holder.button_.setVisibility(View.GONE);??
  • ???????????????????????????holder.divider_.setVisibility(View.GONE);??
  • ???????????????????????}??
  • ???????????????????}??
  • ???????????????????updateCommonHeaderView(header,?holder);??
  • ???????????????????break;??
  • ??
  • ???????????????case?HEADER_TYPE_NORMAL:??
  • ???????????????????updateCommonHeaderView(header,?holder);??
  • ???????????????????break;??
  • ???????????}??
  • ????????//?/M:?add?for?sim?management?feature??
  • ???????????if?(header.id?==?R.id.sim_settings)?{??
  • ???????????????///?M:?Customize?SIM?string??
  • ???????????????holder.title.setText(mExt.customizeSimDisplayString(??
  • ???????????????????getContext().getString(R.string.gemini_sim_management_title),?SLOT_ALL));??
  • ???????????????handleDisableHolder(holder,?view);??
  • ???????????}?else?{??
  • ???????????????handleEnableHolder(holder,?view);??
  • ???????????}??
  • ???????????return?view;??
  • ???????}??
  • ?

    ?

    那么每一個header 是如果響應點擊操作的呢.這個就要看Setting.java的onHeaderClick 方法了, onHeaderClick 方法會調用父類的onHeaderClick方法來打開相關的應用,其父類是根據我們配置在settings_headers.xml里面的fragment和intent 來打開相對應的activity的.

    ?

    Setting.java -- onHeaderClick

    Java代碼??
  • public?void?onHeaderClick(Header?header,?int?position)?{??
  • ????????boolean?revert?=?false;??
  • ????????if?(header.id?==?R.id.account_add)?{??
  • ????????????revert?=?true;??
  • ????????}??
  • ??
  • ????????super.onHeaderClick(header,?position);??
  • ??
  • ????????if?(revert?&&?mLastHeader?!=?null)?{??
  • ????????????highlightHeader((int)?mLastHeader.id);??
  • ????????}?else?{??
  • ????????????mLastHeader?=?header;??
  • ????????}??
  • ????}??
  • ?

    PreferenceActivity -- onHeaderClick

    Java代碼??
  • public?void?onHeaderClick(Header?header,?int?position)?{??
  • ????????if?(header.fragment?!=?null)?{??
  • ????????????if?(mSinglePane)?{??
  • ????????????????Log.d(TAG,?"onHeaderClick,?single?pane?and?startWithFragment.");??
  • ????????????????int?titleRes?=?header.breadCrumbTitleRes;??
  • ????????????????int?shortTitleRes?=?header.breadCrumbShortTitleRes;??
  • ????????????????if?(titleRes?==?0)?{??
  • ????????????????????titleRes?=?header.titleRes;??
  • ????????????????????shortTitleRes?=?0;??
  • ????????????????}??
  • ????????????????startWithFragment(header.fragment,?header.fragmentArguments,?null,?0,??
  • ????????????????????????titleRes,?shortTitleRes);??
  • ????????????}?else?{??
  • ????????????????Log.d(TAG,?"onHeaderClick,?multiple?pane?and?switchToHeader.");??
  • ????????????????switchToHeader(header);??
  • ????????????}??
  • ????????}?else?if?(header.intent?!=?null)?{??
  • ????????????Log.d(TAG,?"onHeaderClick,?start?activity?with?header?intent.");??
  • ????????????startActivity(header.intent);??
  • ????????}??
  • ????}??
  • ?

    ?原文地址:http://862123204-qq-com.iteye.com/blog/2144790

    總結

    以上是生活随笔為你收集整理的Android 4.4 Settings 应用初步分析的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。