Android4.0设置界面修改总结(一)

转载:http://blog.csdn.net/way_ping_li/article/details/18076001

================================================================================================

笔者前段时间完成设置的圆角item风格的修改,但最近,客户新增需求,想把设置做成Tab风格的,没办法,顾客就是上帝,咱得改啊。今天算是初步改完了,趁着测试紧张测试的空隙,赶紧写写博客,梳理一下,一来是给自己记个笔记,二来希望给有需要的朋友一点帮助。

修改主要是两个点:

①.圆角item的实现。

②.Tab风格的实现。


先来看看下面粗糙的效果图:

  


我们都知道,Android从3.0开始加入了Fragment,这大大的减少了Activity的使用,在4.0的设置中尤其发挥的淋漓尽致,几乎整个设置应用的一级、二级设置菜单就属于一个Activity即Settings.java。我们能看到不同的设置项,其实就是更换不同的Fragment,表面上是显得很简洁明了,但是修改起来还是有点蛋疼了,一点小改动就有可能牵扯一大部分功能,引起一堆bug。

  • 圆角item的实现:

其实这种圆角的item有两种类型,一种是一直都有的Preference,另外一种是从3.0开始添加的Header。比如设置的第一个主界面使用的就是Header(第一、二张图片所示),其二级、三级菜单就是Preference(第三张图片所示)了,不管是哪种类型,他们都是基于ListView实现的,理解了这个原理,修改起来就简单了,只用在ListView的Adapter的getView函数中,修改对应item项的背景图片即可。观察圆角item的背景图片我们可以发现,先要准备四种背景图片:顶部(上圆下方)、中间(上下都方)、底部(上方下圆)和单独(上下都圆)。

由于Header和Preference还是有一点区别的,Header使用频率没有Preference高,因此,我这里就没有在framework层修改Header,只是在需要用到的地方再修改。所以重点说一下Preference。

在源码中找到:frameworks/base/core/java/android/preference/PreferenceGroupAdapter.java,这个就是Preference的Adapter,首先声明4种类型的背景,然后通过计算得知那一项需要替换成对应的背景图片,最后在getView函数中,把对应的item的背景替换成我们需要的,下面是源码,加上liweiping标签的就是我的修改:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. /* 
  2.  * Copyright (C) 2007 The Android Open Source Project 
  3.  * 
  4.  * Licensed under the Apache License, Version 2.0 (the "License"); 
  5.  * you may not use this file except in compliance with the License. 
  6.  * You may obtain a copy of the License at 
  7.  * 
  8.  *      http://www.apache.org/licenses/LICENSE-2.0 
  9.  * 
  10.  * Unless required by applicable law or agreed to in writing, software 
  11.  * distributed under the License is distributed on an "AS IS" BASIS, 
  12.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
  13.  * See the License for the specific language governing permissions and 
  14.  * limitations under the License. 
  15.  */  
  16.   
  17. package android.preference;  
  18.   
  19. import java.util.ArrayList;  
  20. import java.util.Collections;  
  21. import java.util.List;  
  22.   
  23. import android.os.Handler;  
  24. import android.preference.Preference.OnPreferenceChangeInternalListener;  
  25. import android.view.View;  
  26. import android.view.ViewGroup;  
  27. import android.widget.Adapter;  
  28. import android.widget.BaseAdapter;  
  29. import android.widget.ListView;  
  30.   
  31. /** 
  32.  * An adapter that returns the {@link Preference} contained in this group. 
  33.  * In most cases, this adapter should be the base class for any custom 
  34.  * adapters from {@link Preference#getAdapter()}. 
  35.  * <p> 
  36.  * This adapter obeys the 
  37.  * {@link Preference}'s adapter rule (the 
  38.  * {@link Adapter#getView(int, View, ViewGroup)} should be used instead of 
  39.  * {@link Preference#getView(ViewGroup)} if a {@link Preference} has an 
  40.  * adapter via {@link Preference#getAdapter()}). 
  41.  * <p> 
  42.  * This adapter also propagates data change/invalidated notifications upward. 
  43.  * <p> 
  44.  * This adapter does not include this {@link PreferenceGroup} in the returned 
  45.  * adapter, use {@link PreferenceCategoryAdapter} instead. 
  46.  *  
  47.  * @see PreferenceCategoryAdapter 
  48.  */  
  49. class PreferenceGroupAdapter extends BaseAdapter implements OnPreferenceChangeInternalListener {  
  50.       
  51.     private static final String TAG = "PreferenceGroupAdapter";  
  52.   
  53.     /** 
  54.      * The group that we are providing data from. 
  55.      */  
  56.     private PreferenceGroup mPreferenceGroup;  
  57.       
  58.     /** 
  59.      * Maps a position into this adapter -> {@link Preference}. These 
  60.      * {@link Preference}s don't have to be direct children of this 
  61.      * {@link PreferenceGroup}, they can be grand children or younger) 
  62.      */  
  63.     private List<Preference> mPreferenceList;  
  64.       
  65.     /** 
  66.      * List of unique Preference and its subclasses' names. This is used to find 
  67.      * out how many types of views this adapter can return. Once the count is 
  68.      * returned, this cannot be modified (since the ListView only checks the 
  69.      * count once--when the adapter is being set). We will not recycle views for 
  70.      * Preference subclasses seen after the count has been returned. 
  71.      */  
  72.     private ArrayList<PreferenceLayout> mPreferenceLayouts;  
  73.   
  74.     private PreferenceLayout mTempPreferenceLayout = new PreferenceLayout();  
  75.   
  76.     /** 
  77.      * Blocks the mPreferenceClassNames from being changed anymore. 
  78.      */  
  79.     private boolean mHasReturnedViewTypeCount = false;  
  80.       
  81.     private volatile boolean mIsSyncing = false;  
  82.       
  83.     private Handler mHandler = new Handler();   
  84.       
  85.     //start by liweiping 20130826  
  86.     private ArrayList<Integer> mPreferenceListBackgroundIndex;  
  87.     private final int SINGLE_LINE_ROUND_CORNER_BACKGROUND = 1;  
  88.     private final int TOP_ROUND_CORNER_BACKGROUND = 2;  
  89.     private final int BOTTOM_ROUND_CORNER_BACKGROUND = 3;  
  90.     private final int CENTER_RECTANGLE_BACKGROUND = 4;  
  91.     private final int NO_BACKGOUND = 5;  
  92.     //end by liweiping 20130826  
  93.       
  94.     private Runnable mSyncRunnable = new Runnable() {  
  95.         public void run() {  
  96.             syncMyPreferences();  
  97.         }  
  98.     };  
  99.   
  100.     private static class PreferenceLayout implements Comparable<PreferenceLayout> {  
  101.         private int resId;  
  102.         private int widgetResId;  
  103.         private String name;  
  104.   
  105.         public int compareTo(PreferenceLayout other) {  
  106.             int compareNames = name.compareTo(other.name);  
  107.             if (compareNames == 0) {  
  108.                 if (resId == other.resId) {  
  109.                     if (widgetResId == other.widgetResId) {  
  110.                         return 0;  
  111.                     } else {  
  112.                         return widgetResId - other.widgetResId;  
  113.                     }  
  114.                 } else {  
  115.                     return resId - other.resId;  
  116.                 }  
  117.             } else {  
  118.                 return compareNames;  
  119.             }  
  120.         }  
  121.     }  
  122.   
  123.     public PreferenceGroupAdapter(PreferenceGroup preferenceGroup) {  
  124.         mPreferenceGroup = preferenceGroup;  
  125.         // If this group gets or loses any children, let us know  
  126.         mPreferenceGroup.setOnPreferenceChangeInternalListener(this);  
  127.   
  128.         mPreferenceList = new ArrayList<Preference>();  
  129.         mPreferenceLayouts = new ArrayList<PreferenceLayout>();  
  130.   
  131.         syncMyPreferences();  
  132.     }  
  133.   
  134.     private void syncMyPreferences() {  
  135.         synchronized(this) {  
  136.             if (mIsSyncing) {  
  137.                 return;  
  138.             }  
  139.   
  140.             mIsSyncing = true;  
  141.         }  
  142.   
  143.         List<Preference> newPreferenceList = new ArrayList<Preference>(mPreferenceList.size());  
  144.         mPreferenceListBackgroundIndex = new ArrayList<Integer>(mPreferenceList.size());//add by liweiping 20130826  
  145.         flattenPreferenceGroup(newPreferenceList, mPreferenceGroup);  
  146.         mPreferenceList = newPreferenceList;  
  147.           
  148.         notifyDataSetChanged();  
  149.   
  150.         synchronized(this) {  
  151.             mIsSyncing = false;  
  152.             notifyAll();  
  153.         }  
  154.     }  
  155.       
  156.     private void flattenPreferenceGroup(List<Preference> preferences, PreferenceGroup group) {  
  157.         // TODO: shouldn't always?  
  158.         group.sortPreferences();  
  159.   
  160.         final int groupSize = group.getPreferenceCount();  
  161.         final int[] tempIndexOfPrefrence  = calcItemsBetweenCategory(group);//add by liweiping 20130826  
  162.           
  163.         for (int i = 0; i < groupSize; i++) {  
  164.             final Preference preference = group.getPreference(i);  
  165.               
  166.             preferences.add(preference);  
  167.            //start by liweiping 20130826   
  168.             if(tempIndexOfPrefrence[i] == 0){  
  169.                   
  170.                 mPreferenceListBackgroundIndex.add(NO_BACKGOUND);  
  171.             } else if (tempIndexOfPrefrence[i] == 1  
  172.                     && (i == 0 ? true : tempIndexOfPrefrence[i - 1] <= 1)){  
  173.                 if(i == (groupSize - 1) ? true  : tempIndexOfPrefrence[i + 1] <= 1){  
  174.                     mPreferenceListBackgroundIndex.add(SINGLE_LINE_ROUND_CORNER_BACKGROUND);  
  175.                 }else {  
  176.                     mPreferenceListBackgroundIndex.add(TOP_ROUND_CORNER_BACKGROUND);  
  177.                 }  
  178.             }else if(tempIndexOfPrefrence[i] > 1){  
  179.                 if(i == (groupSize - 1) ? true  : tempIndexOfPrefrence[i + 1] <= 1){  
  180.                     mPreferenceListBackgroundIndex.add(BOTTOM_ROUND_CORNER_BACKGROUND);  
  181.                 }else {  
  182.                     mPreferenceListBackgroundIndex.add(CENTER_RECTANGLE_BACKGROUND);  
  183.                 }  
  184.             }  
  185.             //end by liweiping 20130826  
  186.             if (!mHasReturnedViewTypeCount && !preference.hasSpecifiedLayout()) {  
  187.                 addPreferenceClassName(preference);  
  188.             }  
  189.               
  190.             if (preference instanceof PreferenceGroup) {  
  191.                 final PreferenceGroup preferenceAsGroup = (PreferenceGroup) preference;  
  192.                 if (preferenceAsGroup.isOnSameScreenAsChildren()) {  
  193.                     flattenPreferenceGroup(preferences, preferenceAsGroup);  
  194.                 }  
  195.             }  
  196.   
  197.             preference.setOnPreferenceChangeInternalListener(this);  
  198.         }  
  199.     }  
  200.   
  201.     /** 
  202.      * Creates a string that includes the preference name, layout id and widget layout id. 
  203.      * If a particular preference type uses 2 different resources, they will be treated as 
  204.      * different view types. 
  205.      */  
  206.     private PreferenceLayout createPreferenceLayout(Preference preference, PreferenceLayout in) {  
  207.         PreferenceLayout pl = in != null? in : new PreferenceLayout();  
  208.         pl.name = preference.getClass().getName();  
  209.         pl.resId = preference.getLayoutResource();  
  210.         pl.widgetResId = preference.getWidgetLayoutResource();  
  211.         return pl;  
  212.     }  
  213.   
  214.     private void addPreferenceClassName(Preference preference) {  
  215.         final PreferenceLayout pl = createPreferenceLayout(preference, null);  
  216.         int insertPos = Collections.binarySearch(mPreferenceLayouts, pl);  
  217.   
  218.         // Only insert if it doesn't exist (when it is negative).  
  219.         if (insertPos < 0) {  
  220.             // Convert to insert index  
  221.             insertPos = insertPos * -1 - 1;  
  222.             mPreferenceLayouts.add(insertPos, pl);  
  223.         }  
  224.     }  
  225.       
  226.     public int getCount() {  
  227.         return mPreferenceList.size();  
  228.     }  
  229.   
  230.     public Preference getItem(int position) {  
  231.         if (position < 0 || position >= getCount()) return null;  
  232.         return mPreferenceList.get(position);  
  233.     }  
  234.   
  235.     public long getItemId(int position) {  
  236.         if (position < 0 || position >= getCount()) return ListView.INVALID_ROW_ID;  
  237.         return this.getItem(position).getId();  
  238.     }  
  239.   
  240.     public View getView(int position, View convertView, ViewGroup parent) {  
  241.         final Preference preference = this.getItem(position);  
  242.         // Build a PreferenceLayout to compare with known ones that are cacheable.  
  243.         mTempPreferenceLayout = createPreferenceLayout(preference, mTempPreferenceLayout);  
  244.   
  245.         // If it's not one of the cached ones, set the convertView to null so that   
  246.         // the layout gets re-created by the Preference.  
  247.         if (Collections.binarySearch(mPreferenceLayouts, mTempPreferenceLayout) < 0) {  
  248.             convertView = null;  
  249.         }  
  250.         // start by liweiping 20130826              
  251.         //return preference.getView(convertView, parent);  
  252.         View mView = preference.getView(convertView, parent);  
  253.         mView.setBackgroundResource(com.android.internal.R.color.transparent);  
  254.         if(mPreferenceListBackgroundIndex.get(position) == SINGLE_LINE_ROUND_CORNER_BACKGROUND){  
  255.             mView.setBackgroundResource(com.android.internal.R.drawable.easy_pref_item_single);  
  256.         }else if(mPreferenceListBackgroundIndex.get(position) == TOP_ROUND_CORNER_BACKGROUND){  
  257.             mView.setBackgroundResource(com.android.internal.R.drawable.easy_pref_item_top);  
  258.         }else if(mPreferenceListBackgroundIndex.get(position) == CENTER_RECTANGLE_BACKGROUND){  
  259.             mView.setBackgroundResource(com.android.internal.R.drawable.easy_pref_item_center);  
  260.         }else if(mPreferenceListBackgroundIndex.get(position) == BOTTOM_ROUND_CORNER_BACKGROUND){  
  261.             mView.setBackgroundResource(com.android.internal.R.drawable.easy_pref_item_bottom);  
  262.         }  
  263.         return mView;  
  264.         //end by liweiping 20130826  
  265.     }  
  266.   
  267.     @Override  
  268.     public boolean isEnabled(int position) {  
  269.         if (position < 0 || position >= getCount()) return true;  
  270.         return this.getItem(position).isSelectable();  
  271.     }  
  272.   
  273.     @Override  
  274.     public boolean areAllItemsEnabled() {  
  275.         // There should always be a preference group, and these groups are always  
  276.         // disabled  
  277.         return false;  
  278.     }  
  279.   
  280.     public void onPreferenceChange(Preference preference) {  
  281.         notifyDataSetChanged();  
  282.     }  
  283.   
  284.     public void onPreferenceHierarchyChange(Preference preference) {  
  285.         mHandler.removeCallbacks(mSyncRunnable);  
  286.         mHandler.post(mSyncRunnable);  
  287.     }  
  288.   
  289.     @Override  
  290.     public boolean hasStableIds() {  
  291.         return true;  
  292.     }  
  293.   
  294.     @Override  
  295.     public int getItemViewType(int position) {  
  296.         if (!mHasReturnedViewTypeCount) {  
  297.             mHasReturnedViewTypeCount = true;  
  298.         }  
  299.           
  300.         final Preference preference = this.getItem(position);  
  301.         if (preference.hasSpecifiedLayout()) {  
  302.             return IGNORE_ITEM_VIEW_TYPE;  
  303.         }  
  304.   
  305.         mTempPreferenceLayout = createPreferenceLayout(preference, mTempPreferenceLayout);  
  306.   
  307.         int viewType = Collections.binarySearch(mPreferenceLayouts, mTempPreferenceLayout);  
  308.         if (viewType < 0) {  
  309.             // This is a class that was seen after we returned the count, so  
  310.             // don't recycle it.  
  311.             return IGNORE_ITEM_VIEW_TYPE;  
  312.         } else {  
  313.             return viewType;  
  314.         }  
  315.     }  
  316.   
  317.     @Override  
  318.     public int getViewTypeCount() {  
  319.         if (!mHasReturnedViewTypeCount) {  
  320.             mHasReturnedViewTypeCount = true;  
  321.         }  
  322.           
  323.         return Math.max(1, mPreferenceLayouts.size());  
  324.     }  
  325.   
  326.     //start by liweiping 20130826  
  327.     private int[] calcItemsBetweenCategory(PreferenceGroup group){  
  328.         final int groupSize = group.getPreferenceCount();  
  329.           
  330.         int[] indexOfPreference = new int[groupSize];  
  331.         for (int i = 0; i < groupSize; i++) {  
  332.             final Preference preference = group.getPreference(i);  
  333.              if (preference instanceof PreferenceCategory) {  
  334.                      indexOfPreference[i]  = 0 ;  
  335.              }else if(i == 0){  
  336.                  indexOfPreference[i]  = 1 ;  
  337.              }else {  
  338.                  indexOfPreference[i] = indexOfPreference[i - 1] + 1;  
  339.              }  
  340.         }  
  341.         return indexOfPreference;  
  342.     }  
  343.     //end by liweiping 20130826  
  344. }  


  • tab风格的实现

tab风格的实现有两种方法,一种是传统的TabHost,另外一种就是从3.0开始的ActionBar中的tab,我最开始使用的就是TabHost,也大概实现了,但是最后的Bug让我头疼死了,因此果断放弃,选择了ActionBar的tab,其实一开始就应该选择这个的,由于笔者过度自信对TabHost的使用熟练度,因此结果就是不得不返工,浪费时间精力。其实用ActionBar的tab对代码的改动应该是最小的。下面来看看我修改过后的Settings.java的源码(我的修改也是打过liweiping标签的):

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. /* 
  2.  * Copyright (C) 2008 The Android Open Source Project 
  3.  * 
  4.  * Licensed under the Apache License, Version 2.0 (the "License"); 
  5.  * you may not use this file except in compliance with the License. 
  6.  * You may obtain a copy of the License at 
  7.  * 
  8.  *      http://www.apache.org/licenses/LICENSE-2.0 
  9.  * 
  10.  * Unless required by applicable law or agreed to in writing, software 
  11.  * distributed under the License is distributed on an "AS IS" BASIS, 
  12.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
  13.  * See the License for the specific language governing permissions and 
  14.  * limitations under the License. 
  15.  */  
  16.   
  17. package com.android.settings;  
  18.   
  19. import com.android.settings.accounts.AccountSyncSettings;  
  20. import com.android.settings.bluetooth.BluetoothEnabler;  
  21. import com.android.settings.fuelgauge.PowerUsageSummary;  
  22. import com.android.settings.wifi.WifiEnabler;  
  23. //import static com.sprd.android.config.OptConfig.LC_RAM_SUPPORT;  
  24.   
  25. import android.app.ActionBar;  
  26. import android.app.ActionBar.Tab;  
  27. import android.app.ActionBar.TabListener;  
  28. import android.app.FragmentTransaction;  
  29. import android.content.ComponentName;  
  30. import android.content.Context;  
  31. import android.content.Intent;  
  32. import android.content.SharedPreferences;  
  33. import android.content.pm.ActivityInfo;  
  34. import android.content.pm.PackageManager;  
  35. import android.content.pm.PackageManager.NameNotFoundException;  
  36. import android.os.Bundle;  
  37. import android.os.SystemProperties;  
  38. import android.os.TopwiseProp;  
  39. import android.preference.Preference;  
  40. import android.preference.PreferenceActivity;  
  41. import android.preference.PreferenceFragment;  
  42. import android.preference.PreferenceManager;  
  43. import android.telephony.TelephonyManager;  
  44. import android.text.TextUtils;  
  45. import android.util.Log;  
  46. import android.util.SparseArray;  
  47. import android.view.LayoutInflater;  
  48. import android.view.View;  
  49. import android.view.MenuItem;  
  50. import android.view.View.OnClickListener;  
  51. import android.view.ViewGroup;  
  52. import android.widget.ArrayAdapter;  
  53. import android.widget.Button;  
  54. import android.widget.ImageView;  
  55. import android.widget.ListAdapter;  
  56. import android.widget.ListView;  
  57. import android.widget.Switch;  
  58. import android.widget.TextView;  
  59.   
  60. import java.util.ArrayList;  
  61. import java.util.HashMap;  
  62. import java.util.List;  
  63.   
  64. /** 
  65.  * Top-level settings activity to handle single pane and double pane UI layout. 
  66.  */  
  67. public class Settings extends PreferenceActivity implements ButtonBarHandler {  
  68.   
  69.     private static final String LOG_TAG = "Settings";  
  70.     private static final String META_DATA_KEY_HEADER_ID =  
  71.         "com.android.settings.TOP_LEVEL_HEADER_ID";  
  72.     private static final String META_DATA_KEY_FRAGMENT_CLASS =  
  73.         "com.android.settings.FRAGMENT_CLASS";  
  74.     private static final String META_DATA_KEY_PARENT_TITLE =  
  75.         "com.android.settings.PARENT_FRAGMENT_TITLE";  
  76.     private static final String META_DATA_KEY_PARENT_FRAGMENT_CLASS =  
  77.         "com.android.settings.PARENT_FRAGMENT_CLASS";  
  78.   
  79.     private static final String EXTRA_CLEAR_UI_OPTIONS = "settings:remove_ui_options";  
  80.   
  81.     private static final String SAVE_KEY_CURRENT_HEADER = "com.android.settings.CURRENT_HEADER";  
  82.     private static final String SAVE_KEY_PARENT_HEADER = "com.android.settings.PARENT_HEADER";  
  83.   
  84.     public static boolean UNIVERSEUI_SUPPORT = SystemProperties.getBoolean("universe_ui_support",false);  
  85.   
  86.     private String mFragmentClass;  
  87.     private int mTopLevelHeaderId;  
  88.     private Header mFirstHeader;  
  89.     private Header mCurrentHeader;  
  90.     private Header mParentHeader;  
  91.     private boolean mInLocalHeaderSwitch;  
  92.   
  93.     // TODO: Update Call Settings based on airplane mode state.  
  94.   
  95.     protected HashMap<Integer, Integer> mHeaderIndexMap = new HashMap<Integer, Integer>();  
  96.     private List<Header> mHeaders;  
  97.       
  98.     //start by liweiping 20140103  
  99.     private int mTabFlag;  
  100.     private static final int FLAG_TAB_WIRELESS_NETWORKS = 0;  
  101.     private static final int FLAG_TAB_DEVICE = 1;  
  102.     private static final int FLAG_TAB_PERSONAL = 2;  
  103.     private static final int FLAG_TAB_SYSTEM = 3;  
  104.     private final TabListener mTabListener = new TabListener() {  
  105.           
  106.         @Override  
  107.         public void onTabUnselected(Tab tab, FragmentTransaction ft) {  
  108.             // TODO Auto-generated method stub  
  109.               
  110.         }  
  111.           
  112.         @Override  
  113.         public void onTabSelected(Tab tab, FragmentTransaction ft) {  
  114.             //Log.i("lwp-log", "tab.getContentDescription().toString() = "+tab.getContentDescription().toString());  
  115.             if (tab.getContentDescription().toString().equals(getResources().getString(R.string.header_category_wireless_networks))){  
  116.                 mTabFlag = FLAG_TAB_WIRELESS_NETWORKS;  
  117.             }else if(tab.getContentDescription().toString().equals(getResources().getString(R.string.header_category_personal))) {  
  118.                 mTabFlag = FLAG_TAB_PERSONAL;  
  119.             } else if (tab.getContentDescription().toString().equals(getResources().getString(R.string.header_category_system))) {  
  120.                 mTabFlag = FLAG_TAB_SYSTEM;  
  121.             } else if (tab.getContentDescription().toString().equals(getResources().getString(R.string.header_category_device))) {  
  122.                 mTabFlag = FLAG_TAB_DEVICE;  
  123.             }  
  124.             Log.i("lwp-log""onTabSelected mTabFlag = " + mTabFlag);   
  125.             invalidateHeaders();  
  126.         }  
  127.           
  128.         @Override  
  129.         public void onTabReselected(Tab tab, FragmentTransaction ft) {  
  130.         }  
  131.     };  
  132.   
  133.     private void setupWirelessNetworks(ActionBar bar) {  
  134.          final Tab tab = bar.newTab();  
  135.          View view = mInflater.inflate(R.layout.tab_widget_view, null);  
  136.          ImageView dialView =  (ImageView)view.findViewById(R.id.main_activity_tab_image);  
  137.          if(dialView != null){  
  138.              dialView.setImageResource(R.drawable.ic_tab_wireless);  
  139.          }  
  140.          TextView dialText = (TextView) view.findViewById(R.id.main_activity_tab_text);  
  141.          if(dialText!=null){  
  142.              dialText.setText(R.string.header_category_wireless_networks);  
  143.          }  
  144.          tab.setCustomView(view);  
  145.          tab.setTabListener(mTabListener);  
  146.          tab.setContentDescription(R.string.header_category_wireless_networks);  
  147.             bar.addTab(tab);  
  148.     }  
  149.   
  150.     private void setupDevice(ActionBar bar) {  
  151.          final Tab tab = bar.newTab();  
  152.          View view = mInflater.inflate(R.layout.tab_widget_view, null);  
  153.          ImageView dialView =  (ImageView)view.findViewById(R.id.main_activity_tab_image);  
  154.          if(dialView != null){  
  155.              dialView.setImageResource(R.drawable.ic_tab_device);  
  156.          }  
  157.          TextView dialText = (TextView) view.findViewById(R.id.main_activity_tab_text);  
  158.          if(dialText!=null){  
  159.              dialText.setText(R.string.header_category_device);  
  160.          }  
  161.          tab.setCustomView(view);  
  162.          tab.setTabListener(mTabListener);  
  163.          tab.setContentDescription(R.string.header_category_device);  
  164.             bar.addTab(tab);  
  165.     }  
  166.   
  167.     private void setupPersonal(ActionBar bar) {  
  168.          final Tab tab = bar.newTab();  
  169.          View view = mInflater.inflate(R.layout.tab_widget_view, null);  
  170.          ImageView dialView =  (ImageView)view.findViewById(R.id.main_activity_tab_image);  
  171.          if(dialView != null){  
  172.              dialView.setImageResource(R.drawable.ic_tab_personal);  
  173.          }  
  174.          TextView dialText = (TextView) view.findViewById(R.id.main_activity_tab_text);  
  175.          if(dialText!=null){  
  176.              dialText.setText(R.string.header_category_personal);  
  177.          }  
  178.          tab.setCustomView(view);  
  179.          tab.setTabListener(mTabListener);  
  180.          tab.setContentDescription(R.string.header_category_personal);  
  181.             bar.addTab(tab);  
  182.     }  
  183.   
  184.     private void setupSystem(ActionBar bar) {  
  185.          final Tab tab = bar.newTab();  
  186.          View view = mInflater.inflate(R.layout.tab_widget_view, null);  
  187.          ImageView dialView =  (ImageView)view.findViewById(R.id.main_activity_tab_image);  
  188.          if(dialView != null){  
  189.              dialView.setImageResource(R.drawable.ic_tab_system);  
  190.          }  
  191.          TextView dialText = (TextView) view.findViewById(R.id.main_activity_tab_text);  
  192.          if(dialText!=null){  
  193.              dialText.setText(R.string.header_category_system);  
  194.          }  
  195.          tab.setCustomView(view);  
  196.          tab.setTabListener(mTabListener);  
  197.          tab.setContentDescription(R.string.header_category_system);  
  198.             bar.addTab(tab);  
  199.     }  
  200.     private LayoutInflater mInflater;  
  201.     //end by liweiping 20140103  
  202.   
  203.     @Override  
  204.     protected void onCreate(Bundle savedInstanceState) {  
  205.         if(UNIVERSEUI_SUPPORT){  
  206.             this.setTheme(R.style.Theme_Holo_new_ui);  
  207.         }  
  208.         if (getIntent().getBooleanExtra(EXTRA_CLEAR_UI_OPTIONS, false)) {  
  209.             getWindow().setUiOptions(0);  
  210.         }  
  211.           
  212.         //start by liweiping 20140103  
  213.         setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);  
  214.         mInflater = getLayoutInflater();  
  215.         mTabFlag = FLAG_TAB_WIRELESS_NETWORKS;  
  216.         //end by liweiping 20140103  
  217.         getMetaData();  
  218.         mInLocalHeaderSwitch = true;  
  219.         super.onCreate(savedInstanceState);  
  220.         mInLocalHeaderSwitch = false;  
  221.   
  222.         //For LowCost case, define the list selector by itself  
  223.       //  if (LC_RAM_SUPPORT) {  
  224.             //ListView list = getListView();  
  225.             //list.setSelector(R.drawable.list_selector_holo_dark);  
  226.            // list.setOverScrollMode(View.OVER_SCROLL_NEVER);  
  227.       //  }  
  228.   
  229.         if (!onIsHidingHeaders() && onIsMultiPane()) {  
  230.             highlightHeader();  
  231.             // Force the title so that it doesn't get overridden by a direct launch of  
  232.             // a specific settings screen.  
  233.             setTitle(R.string.settings_label);  
  234.         }  
  235.   
  236.         // Retrieve any saved state  
  237.         if (savedInstanceState != null) {  
  238.             mCurrentHeader = savedInstanceState.getParcelable(SAVE_KEY_CURRENT_HEADER);  
  239.             mParentHeader = savedInstanceState.getParcelable(SAVE_KEY_PARENT_HEADER);  
  240.         }  
  241.   
  242.         // If the current header was saved, switch to it  
  243.         if (savedInstanceState != null && mCurrentHeader != null) {  
  244.             //switchToHeaderLocal(mCurrentHeader);  
  245.             showBreadCrumbs(mCurrentHeader.title, null);  
  246.         }  
  247.   
  248.         if (mParentHeader != null) {  
  249.             setParentTitle(mParentHeader.title, nullnew OnClickListener() {  
  250.                 public void onClick(View v) {  
  251.                     switchToParent(mParentHeader.fragment);  
  252.                 }  
  253.             });  
  254.         }  
  255.   
  256.   
  257.     }  
  258.   
  259.     /* Set ActionBar with popup function */  
  260.     protected void setActionBarStyle() {  
  261.         ActionBar actionBar = getActionBar();  
  262.         if (actionBar == null){  
  263.             return;  
  264.         }  
  265.         //start by liweiping 20140106  
  266.         Log.i("lwp-log""this.toString() = " + this.toString());  
  267.         //if ( this.toString().contains("SubSettings") ) {  
  268.         if ( this.toString().contains("SubSettings") || this.toString().contains("$")) {  
  269.         //end by liweiping 20140106  
  270.             actionBar.setDisplayOptions(ActionBar.DISPLAY_HOME_AS_UP, ActionBar.DISPLAY_HOME_AS_UP);  
  271.             actionBar.setDisplayHomeAsUpEnabled(true);  
  272.         }  
  273.         else {  
  274.             actionBar.setDisplayOptions(ActionBar.DISPLAY_HOME_AS_UP  
  275.                     ^ ActionBar.DISPLAY_HOME_AS_UP  
  276.                     , ActionBar.DISPLAY_HOME_AS_UP);  
  277.             actionBar.setDisplayHomeAsUpEnabled(false);  
  278.             //start by liweiping 20140103  
  279.             actionBar.setAlternativeTabStyle(true);  
  280.             actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);  
  281.             if(actionBar.getTabCount() == 0){  
  282.                 setupWirelessNetworks(actionBar);  
  283.                 setupDevice(actionBar);  
  284.                 setupPersonal(actionBar);  
  285.                 setupSystem(actionBar);  
  286.             }  
  287.             final SharedPreferences settings = PreferenceManager  
  288.                 .getDefaultSharedPreferences(this);  
  289.             mTabFlag = settings.getInt("tab", FLAG_TAB_WIRELESS_NETWORKS);  
  290.             Log.i("lwp-log""setActionBarStyle mTabFlag = " + mTabFlag);  
  291.             actionBar.selectTab(actionBar.getTabAt(mTabFlag));  
  292.             //end by liweiping 20140103  
  293.         }  
  294.     }  
  295.   
  296.     @Override  
  297.     public boolean onOptionsItemSelected(MenuItem item) {  
  298.     // TODO Add support for android.R.id.home in all Setting's onOptionsItemSelected  
  299.     // getActionBar().setDisplayOptions(ActionBar.DISPLAY_HOME_AS_UP,  
  300.     // ActionBar.DISPLAY_HOME_AS_UP);  
  301.     // Now it's done.  
  302.         if (item.getItemId() == android.R.id.home) {  
  303.             finish();  
  304.             return true;  
  305.         }  
  306.   
  307.         return super.onOptionsItemSelected(item);  
  308.     }  
  309.   
  310.     @Override  
  311.     protected void onSaveInstanceState(Bundle outState) {  
  312.         super.onSaveInstanceState(outState);  
  313.   
  314.         // Save the current fragment, if it is the same as originally launched  
  315.         if (mCurrentHeader != null) {  
  316.             outState.putParcelable(SAVE_KEY_CURRENT_HEADER, mCurrentHeader);  
  317.         }  
  318.         if (mParentHeader != null) {  
  319.             outState.putParcelable(SAVE_KEY_PARENT_HEADER, mParentHeader);  
  320.         }  
  321.     }  
  322.   
  323.     @Override  
  324.     public void onResume() {  
  325.         ListAdapter listAdapter = getListAdapter();  
  326.         if (listAdapter instanceof HeaderAdapter) {  
  327.             ((HeaderAdapter) listAdapter).resume();  
  328.         }  
  329.         setActionBarStyle();  
  330.         super.onResume();  
  331.     }  
  332.   
  333.     @Override  
  334.     public void onPause() {  
  335.         super.onPause();  
  336.   
  337.         ListAdapter listAdapter = getListAdapter();  
  338.         if (listAdapter instanceof HeaderAdapter) {  
  339.             ((HeaderAdapter) listAdapter).pause();  
  340.         }  
  341.       //start by liweiping 20140106  
  342.         final SharedPreferences settings = PreferenceManager  
  343.                 .getDefaultSharedPreferences(this);  
  344.         settings.edit().putInt("tab", settings.getInt("tab", FLAG_TAB_WIRELESS_NETWORKS)).commit();  
  345.       //end by liweiping 20140106   
  346.     }  
  347.   
  348.     //start by liweiping 20140106  
  349.     @Override  
  350.     protected void onDestroy() {  
  351.         super.onDestroy();  
  352.           //final SharedPreferences settings = PreferenceManager  
  353.           //      .getDefaultSharedPreferences(this);  
  354.         //settings.edit().putInt("tab", FLAG_TAB_WIRELESS_NETWORKS).commit();  
  355.     }  
  356.     //end by liweiping 20140106   
  357.   
  358.     @Override  
  359.     public void onBackPressed() {  
  360.         if (!moveTaskToBack(false)) {  
  361.             super.onBackPressed();  
  362.         }  
  363.     }  
  364.   
  365.     private void switchToHeaderLocal(Header header) {  
  366.         mInLocalHeaderSwitch = true;  
  367.         switchToHeader(header);  
  368.         mInLocalHeaderSwitch = false;  
  369.     }  
  370.   
  371.     @Override  
  372.     public void switchToHeader(Header header) {  
  373.         if (!mInLocalHeaderSwitch) {  
  374.             mCurrentHeader = null;  
  375.             mParentHeader = null;  
  376.         }  
  377.         super.switchToHeader(header);  
  378.     }  
  379.   
  380.     /** 
  381.      * Switch to parent fragment and store the grand parent's info 
  382.      * @param className name of the activity wrapper for the parent fragment. 
  383.      */  
  384.     private void switchToParent(String className) {  
  385.         final ComponentName cn = new ComponentName(this, className);  
  386.         try {  
  387.             final PackageManager pm = getPackageManager();  
  388.             final ActivityInfo parentInfo = pm.getActivityInfo(cn, PackageManager.GET_META_DATA);  
  389.   
  390.             if (parentInfo != null && parentInfo.metaData != null) {  
  391.                 String fragmentClass = parentInfo.metaData.getString(META_DATA_KEY_FRAGMENT_CLASS);  
  392.                 CharSequence fragmentTitle = parentInfo.loadLabel(pm);  
  393.                 Header parentHeader = new Header();  
  394.                 parentHeader.fragment = fragmentClass;  
  395.                 parentHeader.title = fragmentTitle;  
  396.                 mCurrentHeader = parentHeader;  
  397.   
  398.                 switchToHeaderLocal(parentHeader);  
  399.                 highlightHeader();  
  400.   
  401.                 mParentHeader = new Header();  
  402.                 mParentHeader.fragment  
  403.                         = parentInfo.metaData.getString(META_DATA_KEY_PARENT_FRAGMENT_CLASS);  
  404.                 mParentHeader.title = parentInfo.metaData.getString(META_DATA_KEY_PARENT_TITLE);  
  405.             }  
  406.         } catch (NameNotFoundException nnfe) {  
  407.             Log.w(LOG_TAG, "Could not find parent activity : " + className);  
  408.         }  
  409.     }  
  410.   
  411.     @Override  
  412.     public void onNewIntent(Intent intent) {  
  413.         super.onNewIntent(intent);  
  414.   
  415.         // If it is not launched from history, then reset to top-level  
  416.         if ((intent.getFlags() & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) == 0  
  417.                 && mFirstHeader != null && !onIsHidingHeaders() && onIsMultiPane()) {  
  418.             switchToHeaderLocal(mFirstHeader);  
  419.         }  
  420.     }  
  421.   
  422.     private void highlightHeader() {  
  423.         if (mTopLevelHeaderId != 0) {  
  424.             Integer index = mHeaderIndexMap.get(mTopLevelHeaderId);  
  425.             if (index != null) {  
  426.                 getListView().setItemChecked(index, true);  
  427.                 getListView().smoothScrollToPosition(index);  
  428.             }  
  429.         }  
  430.     }  
  431.   
  432.     @Override  
  433.     public Intent getIntent() {  
  434.         Intent superIntent = super.getIntent();  
  435.         String startingFragment = getStartingFragmentClass(superIntent);  
  436.         // This is called from super.onCreate, isMultiPane() is not yet reliable  
  437.         // Do not use onIsHidingHeaders either, which relies itself on this method  
  438.         if (startingFragment != null && !onIsMultiPane()) {  
  439.             Intent modIntent = new Intent(superIntent);  
  440.             modIntent.putExtra(EXTRA_SHOW_FRAGMENT, startingFragment);  
  441.             Bundle args = superIntent.getExtras();  
  442.             if (args != null) {  
  443.                 args = new Bundle(args);  
  444.             } else {  
  445.                 args = new Bundle();  
  446.             }  
  447.             args.putParcelable("intent", superIntent);  
  448.             modIntent.putExtra(EXTRA_SHOW_FRAGMENT_ARGUMENTS, superIntent.getExtras());  
  449.             return modIntent;  
  450.         }  
  451.         return superIntent;  
  452.     }  
  453.   
  454.     /** 
  455.      * Checks if the component name in the intent is different from the Settings class and 
  456.      * returns the class name to load as a fragment. 
  457.      */  
  458.     protected String getStartingFragmentClass(Intent intent) {  
  459.         if (mFragmentClass != nullreturn mFragmentClass;  
  460.   
  461.         String intentClass = intent.getComponent().getClassName();  
  462.         if (intentClass.equals(getClass().getName())) return null;  
  463.   
  464.         if ("com.android.settings.ManageApplications".equals(intentClass)  
  465.                 || "com.android.settings.RunningServices".equals(intentClass)  
  466.                 || "com.android.settings.applications.StorageUse".equals(intentClass)) {  
  467.             // Old names of manage apps.  
  468.             intentClass = com.android.settings.applications.ManageApplications.class.getName();  
  469.         }  
  470.   
  471.         return intentClass;  
  472.     }  
  473.   
  474.     /** 
  475.      * Override initial header when an activity-alias is causing Settings to be launched 
  476.      * for a specific fragment encoded in the android:name parameter. 
  477.      */  
  478.     @Override  
  479.     public Header onGetInitialHeader() {  
  480.         String fragmentClass = getStartingFragmentClass(super.getIntent());  
  481.         if (fragmentClass != null) {  
  482.             Header header = new Header();  
  483.             header.fragment = fragmentClass;  
  484.             header.title = getTitle();  
  485.             header.fragmentArguments = getIntent().getExtras();  
  486.             mCurrentHeader = header;  
  487.             return header;  
  488.         }  
  489.   
  490.         return mFirstHeader;  
  491.     }  
  492.   
  493.     @Override  
  494.     public Intent onBuildStartFragmentIntent(String fragmentName, Bundle args,  
  495.             int titleRes, int shortTitleRes) {  
  496.         Intent intent = super.onBuildStartFragmentIntent(fragmentName, args,  
  497.                 titleRes, shortTitleRes);  
  498.   
  499.         // some fragments want to avoid split actionbar  
  500.         if (DataUsageSummary.class.getName().equals(fragmentName) ||  
  501.                 PowerUsageSummary.class.getName().equals(fragmentName) ||  
  502.                 AccountSyncSettings.class.getName().equals(fragmentName) ||  
  503.                 UserDictionarySettings.class.getName().equals(fragmentName)) {  
  504.             intent.putExtra(EXTRA_CLEAR_UI_OPTIONS, true);  
  505.         }  
  506.   
  507.         intent.setClass(this, SubSettings.class);  
  508.         return intent;  
  509.     }  
  510.   
  511.     /** 
  512.      * Populate the activity with the top-level headers. 
  513.      */  
  514.     @Override  
  515.     public void onBuildHeaders(List<Header> headers) {  
  516.         //start by liweiping 20130103  
  517.         //if(UNIVERSEUI_SUPPORT){  
  518.         //    loadHeadersFromResource(R.xml.settings_headers_uui, headers);  
  519.         //}else{  
  520.         //    loadHeadersFromResource(R.xml.settings_headers, headers);  
  521.         //}  
  522.         Log.i("lwp""mTabFlag = "+mTabFlag + ", headers.size() = "+ headers.size() );  
  523.          if (mTabFlag == FLAG_TAB_WIRELESS_NETWORKS){  
  524.              loadHeadersFromResource(R.xml.settings_headers_wireless_networks, headers);  
  525.          }else if(mTabFlag == FLAG_TAB_DEVICE){  
  526.              loadHeadersFromResource(R.xml.settings_headers_device, headers);  
  527.          }else if(mTabFlag == FLAG_TAB_PERSONAL){  
  528.              loadHeadersFromResource(R.xml.settings_headers_personal, headers);  
  529.          }else{  
  530.              loadHeadersFromResource(R.xml.settings_headers_system, headers);  
  531.          }  
  532.         //end by liweiping 20130103  
  533.   
  534.         updateHeaderList(headers);  
  535.   
  536.         //start by liweiping 20130107 for bug 1146  
  537.         //mHeaders = headers;  
  538.         if(mHeaders != null){  
  539.             mHeaders.clear();  
  540.             mHeaders.addAll(headers);  
  541.         }  
  542.         //end by liweiping 20130107  
  543.     }  
  544.   
  545.     private void updateHeaderList(List<Header> target) {  
  546.         int i = 0;  
  547.         while (i < target.size()) {  
  548.             Header header = target.get(i);  
  549.             // Ids are integers, so downcasting  
  550.             int id = (int) header.id;  
  551.             if (id == R.id.dock_settings) {  
  552.                 if (!needsDockSettings())  
  553.                     target.remove(header);  
  554.             } else if (id == R.id.operator_settings || id == R.id.manufacturer_settings) {  
  555.                 Utils.updateHeaderToSpecificActivityFromMetaDataOrRemove(this, target, header);  
  556.             } else if (id == R.id.wifi_settings) {  
  557.                 // Remove WiFi Settings if WiFi service is not available.  
  558.                 // modified by zhangguixin  
  559.                 // if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI)) {  
  560.                 if (!SystemProperties.getBoolean("ro.device.support.wifi"true)) {  
  561.                 // if ("0".equals(SystemProperties.getBoolean("ro.device.support.wifi", "1"))) {  
  562.                     target.remove(header);  
  563.                 }  
  564.             } else if (id == R.id.bluetooth_settings) {  
  565.                 // Remove Bluetooth Settings if Bluetooth service is not available.  
  566.                 // modified by zhangguixin  
  567.                 // if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH)) {  
  568.                 if (!SystemProperties.getBoolean("ro.device.support.bt"true)) {  
  569.                 // if ("0".equals(SystemProperties.getBoolean("ro.device.support.bt", "1"))) {  
  570.                     target.remove(header);  
  571.                 }  
  572.             } else if (id == R.id.dual_sim_settings) {  
  573.                 if (!TelephonyManager.isMultiSim()) {  
  574.                     target.remove(header);  
  575.                 }  
  576.             } else if (id == R.id.data_usage_settings &&  
  577.                     "sc8825".equalsIgnoreCase(SystemProperties.get("ro.board.platform""sc8825"))) {//fix bug182500  
  578.                 target.remove(header);  
  579.             }  
  580.             //add by huangweiwei, topwise, 2013-10-12  
  581.             else if (id == R.id.development_settings) {  
  582.                 if (android.os.TopwiseProp.getDefaultSettingBoolean("settings_remove_development"false)) {  
  583.                     target.remove(header);  
  584.                 }  
  585.             }  
  586.             //add end by huangweiwei, topwise, 2013-10-12  
  587.   
  588.             // Increment if the current one wasn't removed by the Utils code.  
  589.             if (target.get(i) == header) {  
  590.                 // Hold on to the first header, when we need to reset to the top-level  
  591.                 if (mFirstHeader == null &&  
  592.                         HeaderAdapter.getHeaderType(header) != HeaderAdapter.HEADER_TYPE_CATEGORY) {  
  593.                     mFirstHeader = header;  
  594.                 }  
  595.                 mHeaderIndexMap.put(id, i);  
  596.                 i++;  
  597.             }  
  598.         }  
  599.     }  
  600.   
  601.     private boolean needsDockSettings() {  
  602.         return getResources().getBoolean(R.bool.has_dock_settings);  
  603.     }  
  604.   
  605.     private void getMetaData() {  
  606.         try {  
  607.             ActivityInfo ai = getPackageManager().getActivityInfo(getComponentName(),  
  608.                     PackageManager.GET_META_DATA);  
  609.             if (ai == null || ai.metaData == nullreturn;  
  610.             mTopLevelHeaderId = ai.metaData.getInt(META_DATA_KEY_HEADER_ID);  
  611.             mFragmentClass = ai.metaData.getString(META_DATA_KEY_FRAGMENT_CLASS);  
  612.   
  613.             // Check if it has a parent specified and create a Header object  
  614.             final int parentHeaderTitleRes = ai.metaData.getInt(META_DATA_KEY_PARENT_TITLE);  
  615.             String parentFragmentClass = ai.metaData.getString(META_DATA_KEY_PARENT_FRAGMENT_CLASS);  
  616.             if (parentFragmentClass != null) {  
  617.                 mParentHeader = new Header();  
  618.                 mParentHeader.fragment = parentFragmentClass;  
  619.                 if (parentHeaderTitleRes != 0) {  
  620.                     mParentHeader.title = getResources().getString(parentHeaderTitleRes);  
  621.                 }  
  622.             }  
  623.         } catch (NameNotFoundException nnfe) {  
  624.             // No recovery  
  625.         }  
  626.     }  
  627.   
  628.     @Override  
  629.     public boolean hasNextButton() {  
  630.         return super.hasNextButton();  
  631.     }  
  632.   
  633.     @Override  
  634.     public Button getNextButton() {  
  635.         return super.getNextButton();  
  636.     }  
  637.   
  638.     private static class HeaderAdapter extends ArrayAdapter<Header> {  
  639.         static final int HEADER_TYPE_CATEGORY = 0;  
  640.         static final int HEADER_TYPE_NORMAL = 1;  
  641.         static final int HEADER_TYPE_SWITCH = 2;  
  642.         private static final int HEADER_TYPE_COUNT = HEADER_TYPE_SWITCH + 1;  
  643.   
  644.         private final WifiEnabler mWifiEnabler;  
  645.         private final BluetoothEnabler mBluetoothEnabler;  
  646.   
  647.         private SparseArray<View> mViewCache;  
  648.         private static class HeaderViewHolder {  
  649.             ImageView icon;  
  650.             TextView title;  
  651.             TextView summary;  
  652.             Switch switch_;  
  653.         }  
  654.   
  655.         private LayoutInflater mInflater;  
  656.   
  657.         static int getHeaderType(Header header) {  
  658.             if (header.fragment == null && header.intent == null) {  
  659.                 return HEADER_TYPE_CATEGORY;  
  660.             } else if (header.id == R.id.wifi_settings || header.id == R.id.bluetooth_settings) {  
  661.                 return HEADER_TYPE_SWITCH;  
  662.             } else {  
  663.                 return HEADER_TYPE_NORMAL;  
  664.             }  
  665.         }  
  666.   
  667.         @Override  
  668.         public int getItemViewType(int position) {  
  669.             Header header = getItem(position);  
  670.             return getHeaderType(header);  
  671.         }  
  672.         //start by liweiping 20140106  
  673.         @Override  
  674.         public void notifyDataSetChanged() {  
  675.             // TODO Auto-generated method stub  
  676.             super.notifyDataSetChanged();  
  677.             mViewCache = new SparseArray<View>(getCount());  
  678.         }  
  679.         //end by liweiping 20140106  
  680.           
  681.         @Override  
  682.         public boolean areAllItemsEnabled() {  
  683.             return false// because of categories  
  684.         }  
  685.   
  686.         @Override  
  687.         public boolean isEnabled(int position) {  
  688.             return getItemViewType(position) != HEADER_TYPE_CATEGORY;  
  689.         }  
  690.   
  691.         @Override  
  692.         public int getViewTypeCount() {  
  693.             return HEADER_TYPE_COUNT;  
  694.         }  
  695.   
  696.         @Override  
  697.         public boolean hasStableIds() {  
  698.             return true;  
  699.         }  
  700.   
  701.         public HeaderAdapter(Context context, List<Header> objects) {  
  702.             super(context, 0, objects);  
  703.             mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);  
  704.   
  705.             // Temp Switches provided as placeholder until the adapter replaces these with actual  
  706.             // Switches inflated from their layouts. Must be done before adapter is set in super  
  707.             mWifiEnabler = new WifiEnabler(context, new Switch(context));  
  708.             mBluetoothEnabler = new BluetoothEnabler(context, new Switch(context));  
  709.             mViewCache = new SparseArray<View>(objects.size());  
  710.         }  
  711.   
  712.         @Override  
  713.         public View getView(int position, View convertView, ViewGroup parent) {  
  714.             HeaderViewHolder holder;  
  715.             Header header = getItem(position);  
  716.             int headerType = getHeaderType(header);  
  717.             View view = null;  
  718.             convertView = mViewCache.get(position);  
  719.             if (convertView == null) {  
  720.                 holder = new HeaderViewHolder();  
  721.                 switch (headerType) {  
  722.                     case HEADER_TYPE_CATEGORY:  
  723.                         view = new TextView(getContext(), null,  
  724.                                 android.R.attr.listSeparatorTextViewStyle);  
  725.                         holder.title = (TextView) view;  
  726.                         break;  
  727.   
  728.                     case HEADER_TYPE_SWITCH:  
  729.                         view = mInflater.inflate(R.layout.preference_header_switch_item, parent,  
  730.                                 false);  
  731.                         holder.icon = (ImageView) view.findViewById(R.id.icon);  
  732.                         holder.title = (TextView)  
  733.                                 view.findViewById(com.android.internal.R.id.title);  
  734.                         holder.summary = (TextView)  
  735.                                 view.findViewById(com.android.internal.R.id.summary);  
  736.                         holder.switch_ = (Switch) view.findViewById(R.id.switchWidget);  
  737.                         break;  
  738.   
  739.                     case HEADER_TYPE_NORMAL:  
  740.                         view = mInflater.inflate(  
  741.                                 com.android.internal.R.layout.preference_header_item, parent,  
  742.                                 false);  
  743.                         holder.icon = (ImageView) view.findViewById(com.android.internal.R.id.icon);  
  744.                         holder.title = (TextView)  
  745.                                 view.findViewById(com.android.internal.R.id.title);  
  746.                         holder.summary = (TextView)  
  747.                                 view.findViewById(com.android.internal.R.id.summary);  
  748.                         break;  
  749.                 }  
  750.                 view.setBackgroundDrawable(null);  
  751.                 view.setTag(holder);  
  752.                 mViewCache.put(position, view);  
  753.             } else {  
  754.                 view = convertView;  
  755.                 holder = (HeaderViewHolder) view.getTag();  
  756.                 return view;  
  757.             }  
  758.   
  759.             // All view fields must be updated every time, because the view may be recycled  
  760.             switch (headerType) {  
  761.                 case HEADER_TYPE_CATEGORY:  
  762.                     holder.title.setText(header.getTitle(getContext().getResources()));  
  763.                     holder.title.setTextColor(android.R.color.transparent);//add by liweiping 20130826  
  764.                     break;  
  765.   
  766.                 case HEADER_TYPE_SWITCH:  
  767.                     // Would need a different treatment if the main menu had more switches  
  768.                     if (header.id == R.id.wifi_settings) {  
  769.                         mWifiEnabler.setSwitch(holder.switch_);  
  770.                     } else {  
  771.                         mBluetoothEnabler.setSwitch(holder.switch_);  
  772.                     }  
  773.                     // No break, fall through on purpose to update common fields  
  774.   
  775.                     //$FALL-THROUGH$  
  776.                 case HEADER_TYPE_NORMAL:  
  777.                     holder.icon.setImageResource(header.iconRes);  
  778.                     holder.title.setText(header.getTitle(getContext().getResources()));  
  779.                     CharSequence summary = header.getSummary(getContext().getResources());  
  780.                     if (!TextUtils.isEmpty(summary)) {  
  781.                         holder.summary.setVisibility(View.VISIBLE);  
  782.                         holder.summary.setText(summary);  
  783.                     } else {  
  784.                         holder.summary.setVisibility(View.GONE);  
  785.                     }  
  786.                     break;  
  787.             }  
  788.             //start by liweiping 20130826  
  789.             if (header.fragment == null && header.intent == null) {  
  790.                view.setBackgroundColor(android.R.color.transparent);   
  791.             }else if(header.id == R.id.dual_sim_settings || header.id == R.id.sound_settings || header.id == R.id.sync_settings || header.id == R.id.dock_settings || header.id == R.id.date_time_settings){  
  792.                 view.setBackgroundResource(com.android.internal.R.drawable.easy_pref_item_top);  
  793.             }else if(header.id == R.id.wireless_settings || header.id == R.id.manufacturer_settings || header.id == R.id.privacy_settings || header.id == R.id.about_settings || header.id == R.id.application_settings){  
  794.                 view.setBackgroundResource(com.android.internal.R.drawable.easy_pref_item_bottom);  
  795.             }else {  
  796.                 view.setBackgroundResource(com.android.internal.R.drawable.easy_pref_item_center);  
  797.             }  
  798.             //end by liweiping 20130826  
  799.               
  800.             return view;  
  801.         }  
  802.   
  803.         public void resume() {  
  804.             mWifiEnabler.resume();  
  805.             mBluetoothEnabler.resume();  
  806.         }  
  807.   
  808.         public void pause() {  
  809.             mWifiEnabler.pause();  
  810.             mBluetoothEnabler.pause();  
  811.         }  
  812.     }  
  813.   
  814.     @Override  
  815.     public boolean onPreferenceStartFragment(PreferenceFragment caller, Preference pref) {  
  816.         // Override the fragment title for Wallpaper settings  
  817.         int titleRes = pref.getTitleRes();  
  818.         if (pref.getFragment().equals(WallpaperTypeSettings.class.getName())) {  
  819.             titleRes = R.string.wallpaper_settings_fragment_title;  
  820.         }  
  821.   
  822.         startPreferencePanel(pref.getFragment(), pref.getExtras(), titleRes, nullnull0);  
  823.         return true;  
  824.     }  
  825.       
  826.     //start,added by topwise hehuadong in 2013.10.24  
  827.     @Override  
  828.     public void onHeaderClick(Header header, int position) {  
  829.         // TODO Auto-generated method stub  
  830.          //start by liweiping 20140105  
  831.         final SharedPreferences settings = PreferenceManager  
  832.                 .getDefaultSharedPreferences(this);  
  833.         settings.edit().putInt("tab", mTabFlag).commit();  
  834.         Log.i("lwp-log""onHeaderClick..." + settings.getInt("tab", -1));  
  835.         //end by liweiping 20140105  
  836.         if (TopwiseProp.getDefaultSettingString("default_customize_about_device")!=null){  
  837.             if (header != null && header.fragment !=null && header.fragment.equals("com.android.settings.DeviceInfoSettings")){  
  838.                 header.fragment="com.android.settings.AboutDeviceSettings";  
  839.             }  
  840.         }  
  841.         super.onHeaderClick(header, position);  
  842.     }  
  843.     //end,added by topwise hehuadong in 2013.10.24  
  844.       
  845.     @Override  
  846.     public void setListAdapter(ListAdapter adapter) {  
  847.         if (mHeaders == null) {  
  848.             mHeaders = new ArrayList<Header>();  
  849.             // When the saved state provides the list of headers, onBuildHeaders is not called  
  850.             // Copy the list of Headers from the adapter, preserving their order  
  851.             for (int i = 0; i < adapter.getCount(); i++) {  
  852.                 mHeaders.add((Header) adapter.getItem(i));  
  853.             }  
  854.         }  
  855.   
  856.         // Ignore the adapter provided by PreferenceActivity and substitute ours instead  
  857.         super.setListAdapter(new HeaderAdapter(this, mHeaders));  
  858.     }  
  859.   
  860.     /* 
  861.      * Settings subclasses for launching independently. 
  862.      */  
  863.     public static class BluetoothSettingsActivity extends Settings { /* empty */ }  
  864.     public static class WirelessSettingsActivity extends Settings { /* empty */ }  
  865.     public static class TetherSettingsActivity extends Settings { /* empty */ }  
  866.     public static class VpnSettingsActivity extends Settings { /* empty */ }  
  867.     public static class DateTimeSettingsActivity extends Settings { /* empty */ }  
  868.     public static class StorageSettingsActivity extends Settings { /* empty */ }  
  869.     public static class WifiSettingsActivity extends Settings { /* empty */ }  
  870.     public static class WifiP2pSettingsActivity extends Settings { /* empty */ }  
  871.     public static class InputMethodAndLanguageSettingsActivity extends Settings { /* empty */ }  
  872.     public static class InputMethodAndSubtypeEnablerActivity extends Settings { /* empty */ }  
  873.     public static class SpellCheckersSettingsActivity extends Settings { /* empty */ }  
  874.     public static class LocalePickerActivity extends Settings { /* empty */ }  
  875.     public static class UserDictionarySettingsActivity extends Settings { /* empty */ }  
  876.     public static class SoundSettingsActivity extends Settings { /* empty */ }  
  877.     public static class DisplaySettingsActivity extends Settings { /* empty */ }  
  878.     public static class DeviceInfoSettingsActivity extends Settings { /* empty */ }  
  879.     public static class ApplicationSettingsActivity extends Settings { /* empty */ }  
  880.     public static class ManageApplicationsActivity extends Settings { /* empty */ }  
  881.     public static class StorageUseActivity extends Settings { /* empty */ }  
  882.     public static class DevelopmentSettingsActivity extends Settings { /* empty */ }  
  883.     public static class AccessibilitySettingsActivity extends Settings { /* empty */ }  
  884.     public static class SecuritySettingsActivity extends Settings { /* empty */ }  
  885.     public static class LocationSettingsActivity extends Settings { /* empty */ }  
  886.     public static class PrivacySettingsActivity extends Settings { /* empty */ }  
  887.     public static class DockSettingsActivity extends Settings { /* empty */ }  
  888.     public static class RunningServicesActivity extends Settings { /* empty */ }  
  889.     public static class ManageAccountsSettingsActivity extends Settings { /* empty */ }  
  890.     public static class PowerUsageSummaryActivity extends Settings { /* empty */ }  
  891.     public static class AccountSyncSettingsActivity extends Settings { /* empty */ }  
  892.     public static class AccountSyncSettingsInAddAccountActivity extends Settings { /* empty */ }  
  893.     public static class CryptKeeperSettingsActivity extends Settings { /* empty */ }  
  894.     public static class DeviceAdminSettingsActivity extends Settings { /* empty */ }  
  895.     public static class DataUsageSummaryActivity extends Settings { /* empty */ }  
  896.     public static class AdvancedWifiSettingsActivity extends Settings { /* empty */ }  
  897.     public static class TextToSpeechSettingsActivity extends Settings { /* empty */ }  
  898.     public static class AndroidBeamSettingsActivity extends Settings { /* empty */ }  
  899. }  

简单分析一下:

①.首先我们在onResume中找到setActionBarStyle这个函数,这就是设置每次恢复时的必经之路,在这里,我们改变ActionBar的样式,如果是一级界面,就加上tab风格,二级界面就去掉tab风格,显示返回键。

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. /* Set ActionBar with popup function */  
  2. protected void setActionBarStyle() {  
  3.     ActionBar actionBar = getActionBar();  
  4.     if (actionBar == null){  
  5.         return;  
  6.     }  
  7.     //start by liweiping 20140106  
  8.     Log.i("lwp-log""this.toString() = " + this.toString());  
  9.     //if ( this.toString().contains("SubSettings") ) {  
  10.     if ( this.toString().contains("SubSettings") || this.toString().contains("$")) {  
  11.     //end by liweiping 20140106  
  12.         actionBar.setDisplayOptions(ActionBar.DISPLAY_HOME_AS_UP, ActionBar.DISPLAY_HOME_AS_UP);  
  13.         actionBar.setDisplayHomeAsUpEnabled(true);  
  14.     }  
  15.     else {  
  16.         actionBar.setDisplayOptions(ActionBar.DISPLAY_HOME_AS_UP  
  17.                 ^ ActionBar.DISPLAY_HOME_AS_UP  
  18.                 , ActionBar.DISPLAY_HOME_AS_UP);  
  19.         actionBar.setDisplayHomeAsUpEnabled(false);  
  20.         //start by liweiping 20140103  
  21.         actionBar.setAlternativeTabStyle(true);  
  22.         actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);  
  23.         if(actionBar.getTabCount() == 0){  
  24.             setupWirelessNetworks(actionBar);  
  25.             setupDevice(actionBar);  
  26.             setupPersonal(actionBar);  
  27.             setupSystem(actionBar);  
  28.         }  
  29.         final SharedPreferences settings = PreferenceManager  
  30.             .getDefaultSharedPreferences(this);  
  31.         mTabFlag = settings.getInt("tab", FLAG_TAB_WIRELESS_NETWORKS);  
  32.         Log.i("lwp-log""setActionBarStyle mTabFlag = " + mTabFlag);  
  33.         actionBar.selectTab(actionBar.getTabAt(mTabFlag));  
  34.         //end by liweiping 20140103  
  35.     }  
  36. }  

②.监听tab的选择事件,点击每一个tab产生对应的事件,然后把选择项存为全局变量mTabFlag中,最后调用invalidateHeaders()函数刷新界面,替换成不同的Header list。

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. private final TabListener mTabListener = new TabListener() {  
  2.   
  3.     @Override  
  4.     public void onTabUnselected(Tab tab, FragmentTransaction ft) {  
  5.         // TODO Auto-generated method stub  
  6.   
  7.     }  
  8.   
  9.     @Override  
  10.     public void onTabSelected(Tab tab, FragmentTransaction ft) {  
  11.         //Log.i("lwp-log", "tab.getContentDescription().toString() = "+tab.getContentDescription().toString());  
  12.         if (tab.getContentDescription().toString().equals(getResources().getString(R.string.header_category_wireless_networks))){  
  13.             mTabFlag = FLAG_TAB_WIRELESS_NETWORKS;  
  14.         }else if(tab.getContentDescription().toString().equals(getResources().getString(R.string.header_category_personal))) {  
  15.             mTabFlag = FLAG_TAB_PERSONAL;  
  16.         } else if (tab.getContentDescription().toString().equals(getResources().getString(R.string.header_category_system))) {  
  17.             mTabFlag = FLAG_TAB_SYSTEM;  
  18.         } else if (tab.getContentDescription().toString().equals(getResources().getString(R.string.header_category_device))) {  
  19.             mTabFlag = FLAG_TAB_DEVICE;  
  20.         }  
  21.         Log.i("lwp-log""onTabSelected mTabFlag = " + mTabFlag);  
  22.         invalidateHeaders();  
  23.     }  
  24.   
  25.     @Override  
  26.     public void onTabReselected(Tab tab, FragmentTransaction ft) {  
  27.     }  
  28. };  

③.当调用invalidateHeaders()函数时,就进入了onBuildHeaders(List<Header> headers)函数,在这里,我们需要根据mTabFlag来loadHeadersFromResource对应的布局文件,最后一定要记住用新的headers将全局变量mHeaders替换掉。

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. /** 
  2.  * Populate the activity with the top-level headers. 
  3.  */  
  4. @Override  
  5. public void onBuildHeaders(List<Header> headers) {  
  6.     //start by liweiping 20130103  
  7.     //if(UNIVERSEUI_SUPPORT){  
  8.     //    loadHeadersFromResource(R.xml.settings_headers_uui, headers);  
  9.     //}else{  
  10.     //    loadHeadersFromResource(R.xml.settings_headers, headers);  
  11.     //}  
  12.     Log.i("lwp""mTabFlag = "+mTabFlag + ", headers.size() = "+ headers.size() );  
  13.      if (mTabFlag == FLAG_TAB_WIRELESS_NETWORKS){  
  14.          loadHeadersFromResource(R.xml.settings_headers_wireless_networks, headers);  
  15.      }else if(mTabFlag == FLAG_TAB_DEVICE){  
  16.          loadHeadersFromResource(R.xml.settings_headers_device, headers);  
  17.      }else if(mTabFlag == FLAG_TAB_PERSONAL){  
  18.          loadHeadersFromResource(R.xml.settings_headers_personal, headers);  
  19.      }else{  
  20.          loadHeadersFromResource(R.xml.settings_headers_system, headers);  
  21.      }  
  22.     //end by liweiping 20130103  
  23.   
  24.     updateHeaderList(headers);  
  25.   
  26.     //start by liweiping 20130107 for bug 1146  
  27.     //mHeaders = headers;  
  28.     if(mHeaders != null){  
  29.         mHeaders.clear();  
  30.         mHeaders.addAll(headers);  
  31.     }  
  32.     //end by liweiping 20130107  
  33. }  

OK,今天就大概这样了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值