当前位置: 首页 > news >正文

学做静态网站官方网站建设合同

学做静态网站,官方网站建设合同,怎么制作微信链接,新区seo整站优化公司为什么80%的码农都做不了架构师#xff1f; 笔者前段时间完成设置的圆角item风格的修改#xff0c;但最近#xff0c;客户新增需求#xff0c;想把设置做成Tab风格的#xff0c;没办法#xff0c;顾客就是上帝#xff0c;咱得改啊。今天算是初步改完了    笔者前段时间完成设置的圆角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标签的就是我的修改 /** Copyright (C) 2007 The Android Open Source Project** Licensed under the Apache License, Version 2.0 (the License);* you may not use this file except in compliance with the License.* You may obtain a copy of the License at** http://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an AS IS BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.*/package android.preference;import java.util.ArrayList; import java.util.Collections; import java.util.List;import android.os.Handler; import android.preference.Preference.OnPreferenceChangeInternalListener; import android.view.View; import android.view.ViewGroup; import android.widget.Adapter; import android.widget.BaseAdapter; import android.widget.ListView;/*** An adapter that returns the {link Preference} contained in this group.* In most cases, this adapter should be the base class for any custom* adapters from {link Preference#getAdapter()}.* p* This adapter obeys the* {link Preference}s adapter rule (the* {link Adapter#getView(int, View, ViewGroup)} should be used instead of* {link Preference#getView(ViewGroup)} if a {link Preference} has an* adapter via {link Preference#getAdapter()}).* p* This adapter also propagates data change/invalidated notifications upward.* p* This adapter does not include this {link PreferenceGroup} in the returned* adapter, use {link PreferenceCategoryAdapter} instead.* * see PreferenceCategoryAdapter*/ class PreferenceGroupAdapter extends BaseAdapter implements OnPreferenceChangeInternalListener {private static final String TAG PreferenceGroupAdapter;/*** The group that we are providing data from.*/private PreferenceGroup mPreferenceGroup;/*** Maps a position into this adapter - {link Preference}. These* {link Preference}s dont have to be direct children of this* {link PreferenceGroup}, they can be grand children or younger)*/private ListPreference mPreferenceList;/*** List of unique Preference and its subclasses names. This is used to find* out how many types of views this adapter can return. Once the count is* returned, this cannot be modified (since the ListView only checks the* count once--when the adapter is being set). We will not recycle views for* Preference subclasses seen after the count has been returned.*/private ArrayListPreferenceLayout mPreferenceLayouts;private PreferenceLayout mTempPreferenceLayout new PreferenceLayout();/*** Blocks the mPreferenceClassNames from being changed anymore.*/private boolean mHasReturnedViewTypeCount false;private volatile boolean mIsSyncing false;private Handler mHandler new Handler(); //start by liweiping 20130826private ArrayListInteger mPreferenceListBackgroundIndex;private final int SINGLE_LINE_ROUND_CORNER_BACKGROUND 1;private final int TOP_ROUND_CORNER_BACKGROUND 2;private final int BOTTOM_ROUND_CORNER_BACKGROUND 3;private final int CENTER_RECTANGLE_BACKGROUND 4;private final int NO_BACKGOUND 5;//end by liweiping 20130826private Runnable mSyncRunnable new Runnable() {public void run() {syncMyPreferences();}};private static class PreferenceLayout implements ComparablePreferenceLayout {private int resId;private int widgetResId;private String name;public int compareTo(PreferenceLayout other) {int compareNames name.compareTo(other.name);if (compareNames 0) {if (resId other.resId) {if (widgetResId other.widgetResId) {return 0;} else {return widgetResId - other.widgetResId;}} else {return resId - other.resId;}} else {return compareNames;}}}public PreferenceGroupAdapter(PreferenceGroup preferenceGroup) {mPreferenceGroup preferenceGroup;// If this group gets or loses any children, let us knowmPreferenceGroup.setOnPreferenceChangeInternalListener(this);mPreferenceList new ArrayListPreference();mPreferenceLayouts new ArrayListPreferenceLayout();syncMyPreferences();}private void syncMyPreferences() {synchronized(this) {if (mIsSyncing) {return;}mIsSyncing true;}ListPreference newPreferenceList new ArrayListPreference(mPreferenceList.size());mPreferenceListBackgroundIndex new ArrayListInteger(mPreferenceList.size());//add by liweiping 20130826flattenPreferenceGroup(newPreferenceList, mPreferenceGroup);mPreferenceList newPreferenceList;notifyDataSetChanged();synchronized(this) {mIsSyncing false;notifyAll();}}private void flattenPreferenceGroup(ListPreference preferences, PreferenceGroup group) {// TODO: shouldnt always?group.sortPreferences();final int groupSize group.getPreferenceCount();final int[] tempIndexOfPrefrence calcItemsBetweenCategory(group);//add by liweiping 20130826for (int i 0; i groupSize; i) {final Preference preference group.getPreference(i);preferences.add(preference);//start by liweiping 20130826 if(tempIndexOfPrefrence[i] 0){mPreferenceListBackgroundIndex.add(NO_BACKGOUND);} else if (tempIndexOfPrefrence[i] 1 (i 0 ? true : tempIndexOfPrefrence[i - 1] 1)){if(i (groupSize - 1) ? true : tempIndexOfPrefrence[i 1] 1){mPreferenceListBackgroundIndex.add(SINGLE_LINE_ROUND_CORNER_BACKGROUND);}else {mPreferenceListBackgroundIndex.add(TOP_ROUND_CORNER_BACKGROUND);}}else if(tempIndexOfPrefrence[i] 1){if(i (groupSize - 1) ? true : tempIndexOfPrefrence[i 1] 1){mPreferenceListBackgroundIndex.add(BOTTOM_ROUND_CORNER_BACKGROUND);}else {mPreferenceListBackgroundIndex.add(CENTER_RECTANGLE_BACKGROUND);}}//end by liweiping 20130826if (!mHasReturnedViewTypeCount !preference.hasSpecifiedLayout()) {addPreferenceClassName(preference);}if (preference instanceof PreferenceGroup) {final PreferenceGroup preferenceAsGroup (PreferenceGroup) preference;if (preferenceAsGroup.isOnSameScreenAsChildren()) {flattenPreferenceGroup(preferences, preferenceAsGroup);}}preference.setOnPreferenceChangeInternalListener(this);}}/*** Creates a string that includes the preference name, layout id and widget layout id.* If a particular preference type uses 2 different resources, they will be treated as* different view types.*/private PreferenceLayout createPreferenceLayout(Preference preference, PreferenceLayout in) {PreferenceLayout pl in ! null? in : new PreferenceLayout();pl.name preference.getClass().getName();pl.resId preference.getLayoutResource();pl.widgetResId preference.getWidgetLayoutResource();return pl;}private void addPreferenceClassName(Preference preference) {final PreferenceLayout pl createPreferenceLayout(preference, null);int insertPos Collections.binarySearch(mPreferenceLayouts, pl);// Only insert if it doesnt exist (when it is negative).if (insertPos 0) {// Convert to insert indexinsertPos insertPos * -1 - 1;mPreferenceLayouts.add(insertPos, pl);}}public int getCount() {return mPreferenceList.size();}public Preference getItem(int position) {if (position 0 || position getCount()) return null;return mPreferenceList.get(position);}public long getItemId(int position) {if (position 0 || position getCount()) return ListView.INVALID_ROW_ID;return this.getItem(position).getId();}public View getView(int position, View convertView, ViewGroup parent) {final Preference preference this.getItem(position);// Build a PreferenceLayout to compare with known ones that are cacheable.mTempPreferenceLayout createPreferenceLayout(preference, mTempPreferenceLayout);// If its not one of the cached ones, set the convertView to null so that // the layout gets re-created by the Preference.if (Collections.binarySearch(mPreferenceLayouts, mTempPreferenceLayout) 0) {convertView null;}// start by liweiping 20130826 //return preference.getView(convertView, parent);View mView preference.getView(convertView, parent);mView.setBackgroundResource(com.android.internal.R.color.transparent);if(mPreferenceListBackgroundIndex.get(position) SINGLE_LINE_ROUND_CORNER_BACKGROUND){mView.setBackgroundResource(com.android.internal.R.drawable.easy_pref_item_single);}else if(mPreferenceListBackgroundIndex.get(position) TOP_ROUND_CORNER_BACKGROUND){mView.setBackgroundResource(com.android.internal.R.drawable.easy_pref_item_top);}else if(mPreferenceListBackgroundIndex.get(position) CENTER_RECTANGLE_BACKGROUND){mView.setBackgroundResource(com.android.internal.R.drawable.easy_pref_item_center);}else if(mPreferenceListBackgroundIndex.get(position) BOTTOM_ROUND_CORNER_BACKGROUND){mView.setBackgroundResource(com.android.internal.R.drawable.easy_pref_item_bottom);}return mView;//end by liweiping 20130826}Overridepublic boolean isEnabled(int position) {if (position 0 || position getCount()) return true;return this.getItem(position).isSelectable();}Overridepublic boolean areAllItemsEnabled() {// There should always be a preference group, and these groups are always// disabledreturn false;}public void onPreferenceChange(Preference preference) {notifyDataSetChanged();}public void onPreferenceHierarchyChange(Preference preference) {mHandler.removeCallbacks(mSyncRunnable);mHandler.post(mSyncRunnable);}Overridepublic boolean hasStableIds() {return true;}Overridepublic int getItemViewType(int position) {if (!mHasReturnedViewTypeCount) {mHasReturnedViewTypeCount true;}final Preference preference this.getItem(position);if (preference.hasSpecifiedLayout()) {return IGNORE_ITEM_VIEW_TYPE;}mTempPreferenceLayout createPreferenceLayout(preference, mTempPreferenceLayout);int viewType Collections.binarySearch(mPreferenceLayouts, mTempPreferenceLayout);if (viewType 0) {// This is a class that was seen after we returned the count, so// dont recycle it.return IGNORE_ITEM_VIEW_TYPE;} else {return viewType;}}Overridepublic int getViewTypeCount() {if (!mHasReturnedViewTypeCount) {mHasReturnedViewTypeCount true;}return Math.max(1, mPreferenceLayouts.size());}//start by liweiping 20130826private int[] calcItemsBetweenCategory(PreferenceGroup group){final int groupSize group.getPreferenceCount();int[] indexOfPreference new int[groupSize];for (int i 0; i groupSize; i) {final Preference preference group.getPreference(i);if (preference instanceof PreferenceCategory) {indexOfPreference[i] 0 ;}else if(i 0){indexOfPreference[i] 1 ;}else {indexOfPreference[i] indexOfPreference[i - 1] 1;}}return indexOfPreference;}//end by liweiping 20130826 } tab风格的实现tab风格的实现有两种方法一种是传统的TabHost另外一种就是从3.0开始的ActionBar中的tab我最开始使用的就是TabHost也大概实现了但是最后的Bug让我头疼死了因此果断放弃选择了ActionBar的tab其实一开始就应该选择这个的由于笔者过度自信对TabHost的使用熟练度因此结果就是不得不返工浪费时间精力。其实用ActionBar的tab对代码的改动应该是最小的。下面来看看我修改过后的Settings.java的源码(我的修改也是打过liweiping标签的) /** Copyright (C) 2008 The Android Open Source Project** Licensed under the Apache License, Version 2.0 (the License);* you may not use this file except in compliance with the License.* You may obtain a copy of the License at** http://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an AS IS BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.*/package com.android.settings;import com.android.settings.accounts.AccountSyncSettings; import com.android.settings.bluetooth.BluetoothEnabler; import com.android.settings.fuelgauge.PowerUsageSummary; import com.android.settings.wifi.WifiEnabler; //import static com.sprd.android.config.OptConfig.LC_RAM_SUPPORT;import android.app.ActionBar; import android.app.ActionBar.Tab; import android.app.ActionBar.TabListener; import android.app.FragmentTransaction; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.os.Bundle; import android.os.SystemProperties; import android.os.TopwiseProp; import android.preference.Preference; import android.preference.PreferenceActivity; import android.preference.PreferenceFragment; import android.preference.PreferenceManager; import android.telephony.TelephonyManager; import android.text.TextUtils; import android.util.Log; import android.util.SparseArray; import android.view.LayoutInflater; import android.view.View; import android.view.MenuItem; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.ImageView; import android.widget.ListAdapter; import android.widget.ListView; import android.widget.Switch; import android.widget.TextView;import java.util.ArrayList; import java.util.HashMap; import java.util.List;/*** Top-level settings activity to handle single pane and double pane UI layout.*/ public class Settings extends PreferenceActivity implements ButtonBarHandler {private static final String LOG_TAG Settings;private static final String META_DATA_KEY_HEADER_ID com.android.settings.TOP_LEVEL_HEADER_ID;private static final String META_DATA_KEY_FRAGMENT_CLASS com.android.settings.FRAGMENT_CLASS;private static final String META_DATA_KEY_PARENT_TITLE com.android.settings.PARENT_FRAGMENT_TITLE;private static final String META_DATA_KEY_PARENT_FRAGMENT_CLASS com.android.settings.PARENT_FRAGMENT_CLASS;private static final String EXTRA_CLEAR_UI_OPTIONS settings:remove_ui_options;private static final String SAVE_KEY_CURRENT_HEADER com.android.settings.CURRENT_HEADER;private static final String SAVE_KEY_PARENT_HEADER com.android.settings.PARENT_HEADER;public static boolean UNIVERSEUI_SUPPORT SystemProperties.getBoolean(universe_ui_support,false);private String mFragmentClass;private int mTopLevelHeaderId;private Header mFirstHeader;private Header mCurrentHeader;private Header mParentHeader;private boolean mInLocalHeaderSwitch;// TODO: Update Call Settings based on airplane mode state.protected HashMapInteger, Integer mHeaderIndexMap new HashMapInteger, Integer();private ListHeader mHeaders;//start by liweiping 20140103private int mTabFlag;private static final int FLAG_TAB_WIRELESS_NETWORKS 0;private static final int FLAG_TAB_DEVICE 1;private static final int FLAG_TAB_PERSONAL 2;private static final int FLAG_TAB_SYSTEM 3;private final TabListener mTabListener new TabListener() {Overridepublic void onTabUnselected(Tab tab, FragmentTransaction ft) {// TODO Auto-generated method stub}Overridepublic void onTabSelected(Tab tab, FragmentTransaction ft) {//Log.i(lwp-log, tab.getContentDescription().toString() tab.getContentDescription().toString());if (tab.getContentDescription().toString().equals(getResources().getString(R.string.header_category_wireless_networks))){mTabFlag FLAG_TAB_WIRELESS_NETWORKS;}else if(tab.getContentDescription().toString().equals(getResources().getString(R.string.header_category_personal))) {mTabFlag FLAG_TAB_PERSONAL;} else if (tab.getContentDescription().toString().equals(getResources().getString(R.string.header_category_system))) {mTabFlag FLAG_TAB_SYSTEM;} else if (tab.getContentDescription().toString().equals(getResources().getString(R.string.header_category_device))) {mTabFlag FLAG_TAB_DEVICE;}Log.i(lwp-log, onTabSelected mTabFlag mTabFlag); invalidateHeaders();}Overridepublic void onTabReselected(Tab tab, FragmentTransaction ft) {}};private void setupWirelessNetworks(ActionBar bar) {final Tab tab bar.newTab();View view mInflater.inflate(R.layout.tab_widget_view, null);ImageView dialView (ImageView)view.findViewById(R.id.main_activity_tab_image);if(dialView ! null){dialView.setImageResource(R.drawable.ic_tab_wireless);}TextView dialText (TextView) view.findViewById(R.id.main_activity_tab_text);if(dialText!null){dialText.setText(R.string.header_category_wireless_networks);}tab.setCustomView(view);tab.setTabListener(mTabListener);tab.setContentDescription(R.string.header_category_wireless_networks);bar.addTab(tab);}private void setupDevice(ActionBar bar) {final Tab tab bar.newTab();View view mInflater.inflate(R.layout.tab_widget_view, null);ImageView dialView (ImageView)view.findViewById(R.id.main_activity_tab_image);if(dialView ! null){dialView.setImageResource(R.drawable.ic_tab_device);}TextView dialText (TextView) view.findViewById(R.id.main_activity_tab_text);if(dialText!null){dialText.setText(R.string.header_category_device);}tab.setCustomView(view);tab.setTabListener(mTabListener);tab.setContentDescription(R.string.header_category_device);bar.addTab(tab);}private void setupPersonal(ActionBar bar) {final Tab tab bar.newTab();View view mInflater.inflate(R.layout.tab_widget_view, null);ImageView dialView (ImageView)view.findViewById(R.id.main_activity_tab_image);if(dialView ! null){dialView.setImageResource(R.drawable.ic_tab_personal);}TextView dialText (TextView) view.findViewById(R.id.main_activity_tab_text);if(dialText!null){dialText.setText(R.string.header_category_personal);}tab.setCustomView(view);tab.setTabListener(mTabListener);tab.setContentDescription(R.string.header_category_personal);bar.addTab(tab);}private void setupSystem(ActionBar bar) {final Tab tab bar.newTab();View view mInflater.inflate(R.layout.tab_widget_view, null);ImageView dialView (ImageView)view.findViewById(R.id.main_activity_tab_image);if(dialView ! null){dialView.setImageResource(R.drawable.ic_tab_system);}TextView dialText (TextView) view.findViewById(R.id.main_activity_tab_text);if(dialText!null){dialText.setText(R.string.header_category_system);}tab.setCustomView(view);tab.setTabListener(mTabListener);tab.setContentDescription(R.string.header_category_system);bar.addTab(tab);}private LayoutInflater mInflater;//end by liweiping 20140103Overrideprotected void onCreate(Bundle savedInstanceState) {if(UNIVERSEUI_SUPPORT){this.setTheme(R.style.Theme_Holo_new_ui);}if (getIntent().getBooleanExtra(EXTRA_CLEAR_UI_OPTIONS, false)) {getWindow().setUiOptions(0);}//start by liweiping 20140103setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);mInflater getLayoutInflater();mTabFlag FLAG_TAB_WIRELESS_NETWORKS;//end by liweiping 20140103getMetaData();mInLocalHeaderSwitch true;super.onCreate(savedInstanceState);mInLocalHeaderSwitch false;//For LowCost case, define the list selector by itself// if (LC_RAM_SUPPORT) {//ListView list getListView();//list.setSelector(R.drawable.list_selector_holo_dark);// list.setOverScrollMode(View.OVER_SCROLL_NEVER);// }if (!onIsHidingHeaders() onIsMultiPane()) {highlightHeader();// Force the title so that it doesnt get overridden by a direct launch of// a specific settings screen.setTitle(R.string.settings_label);}// Retrieve any saved stateif (savedInstanceState ! null) {mCurrentHeader savedInstanceState.getParcelable(SAVE_KEY_CURRENT_HEADER);mParentHeader savedInstanceState.getParcelable(SAVE_KEY_PARENT_HEADER);}// If the current header was saved, switch to itif (savedInstanceState ! null mCurrentHeader ! null) {//switchToHeaderLocal(mCurrentHeader);showBreadCrumbs(mCurrentHeader.title, null);}if (mParentHeader ! null) {setParentTitle(mParentHeader.title, null, new OnClickListener() {public void onClick(View v) {switchToParent(mParentHeader.fragment);}});}}/* Set ActionBar with popup function */protected void setActionBarStyle() {ActionBar actionBar getActionBar();if (actionBar null){return;}//start by liweiping 20140106Log.i(lwp-log, this.toString() this.toString());//if ( this.toString().contains(SubSettings) ) {if ( this.toString().contains(SubSettings) || this.toString().contains($)) {//end by liweiping 20140106actionBar.setDisplayOptions(ActionBar.DISPLAY_HOME_AS_UP, ActionBar.DISPLAY_HOME_AS_UP);actionBar.setDisplayHomeAsUpEnabled(true);}else {actionBar.setDisplayOptions(ActionBar.DISPLAY_HOME_AS_UP^ ActionBar.DISPLAY_HOME_AS_UP, ActionBar.DISPLAY_HOME_AS_UP);actionBar.setDisplayHomeAsUpEnabled(false);//start by liweiping 20140103actionBar.setAlternativeTabStyle(true);actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);if(actionBar.getTabCount() 0){setupWirelessNetworks(actionBar);setupDevice(actionBar);setupPersonal(actionBar);setupSystem(actionBar);}final SharedPreferences settings PreferenceManager.getDefaultSharedPreferences(this);mTabFlag settings.getInt(tab, FLAG_TAB_WIRELESS_NETWORKS);Log.i(lwp-log, setActionBarStyle mTabFlag mTabFlag);actionBar.selectTab(actionBar.getTabAt(mTabFlag));//end by liweiping 20140103}}Overridepublic boolean onOptionsItemSelected(MenuItem item) {// TODO Add support for android.R.id.home in all Settings onOptionsItemSelected// getActionBar().setDisplayOptions(ActionBar.DISPLAY_HOME_AS_UP,// ActionBar.DISPLAY_HOME_AS_UP);// Now its done.if (item.getItemId() android.R.id.home) {finish();return true;}return super.onOptionsItemSelected(item);}Overrideprotected void onSaveInstanceState(Bundle outState) {super.onSaveInstanceState(outState);// Save the current fragment, if it is the same as originally launchedif (mCurrentHeader ! null) {outState.putParcelable(SAVE_KEY_CURRENT_HEADER, mCurrentHeader);}if (mParentHeader ! null) {outState.putParcelable(SAVE_KEY_PARENT_HEADER, mParentHeader);}}Overridepublic void onResume() {ListAdapter listAdapter getListAdapter();if (listAdapter instanceof HeaderAdapter) {((HeaderAdapter) listAdapter).resume();}setActionBarStyle();super.onResume();}Overridepublic void onPause() {super.onPause();ListAdapter listAdapter getListAdapter();if (listAdapter instanceof HeaderAdapter) {((HeaderAdapter) listAdapter).pause();}//start by liweiping 20140106final SharedPreferences settings PreferenceManager.getDefaultSharedPreferences(this);settings.edit().putInt(tab, settings.getInt(tab, FLAG_TAB_WIRELESS_NETWORKS)).commit();//end by liweiping 20140106 }//start by liweiping 20140106Overrideprotected void onDestroy() {super.onDestroy();//final SharedPreferences settings PreferenceManager// .getDefaultSharedPreferences(this);//settings.edit().putInt(tab, FLAG_TAB_WIRELESS_NETWORKS).commit();}//end by liweiping 20140106 Overridepublic void onBackPressed() {if (!moveTaskToBack(false)) {super.onBackPressed();}}private void switchToHeaderLocal(Header header) {mInLocalHeaderSwitch true;switchToHeader(header);mInLocalHeaderSwitch false;}Overridepublic void switchToHeader(Header header) {if (!mInLocalHeaderSwitch) {mCurrentHeader null;mParentHeader null;}super.switchToHeader(header);}/*** Switch to parent fragment and store the grand parents info* param className name of the activity wrapper for the parent fragment.*/private void switchToParent(String className) {final ComponentName cn new ComponentName(this, className);try {final PackageManager pm getPackageManager();final ActivityInfo parentInfo pm.getActivityInfo(cn, PackageManager.GET_META_DATA);if (parentInfo ! null parentInfo.metaData ! null) {String fragmentClass parentInfo.metaData.getString(META_DATA_KEY_FRAGMENT_CLASS);CharSequence fragmentTitle parentInfo.loadLabel(pm);Header parentHeader new Header();parentHeader.fragment fragmentClass;parentHeader.title fragmentTitle;mCurrentHeader parentHeader;switchToHeaderLocal(parentHeader);highlightHeader();mParentHeader new Header();mParentHeader.fragment parentInfo.metaData.getString(META_DATA_KEY_PARENT_FRAGMENT_CLASS);mParentHeader.title parentInfo.metaData.getString(META_DATA_KEY_PARENT_TITLE);}} catch (NameNotFoundException nnfe) {Log.w(LOG_TAG, Could not find parent activity : className);}}Overridepublic void onNewIntent(Intent intent) {super.onNewIntent(intent);// If it is not launched from history, then reset to top-levelif ((intent.getFlags() Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) 0 mFirstHeader ! null !onIsHidingHeaders() onIsMultiPane()) {switchToHeaderLocal(mFirstHeader);}}private void highlightHeader() {if (mTopLevelHeaderId ! 0) {Integer index mHeaderIndexMap.get(mTopLevelHeaderId);if (index ! null) {getListView().setItemChecked(index, true);getListView().smoothScrollToPosition(index);}}}Overridepublic Intent getIntent() {Intent superIntent super.getIntent();String startingFragment getStartingFragmentClass(superIntent);// This is called from super.onCreate, isMultiPane() is not yet reliable// Do not use onIsHidingHeaders either, which relies itself on this methodif (startingFragment ! null !onIsMultiPane()) {Intent modIntent new Intent(superIntent);modIntent.putExtra(EXTRA_SHOW_FRAGMENT, startingFragment);Bundle args superIntent.getExtras();if (args ! null) {args new Bundle(args);} else {args new Bundle();}args.putParcelable(intent, superIntent);modIntent.putExtra(EXTRA_SHOW_FRAGMENT_ARGUMENTS, superIntent.getExtras());return modIntent;}return superIntent;}/*** Checks if the component name in the intent is different from the Settings class and* returns the class name to load as a fragment.*/protected String getStartingFragmentClass(Intent intent) {if (mFragmentClass ! null) return mFragmentClass;String intentClass intent.getComponent().getClassName();if (intentClass.equals(getClass().getName())) return null;if (com.android.settings.ManageApplications.equals(intentClass)|| com.android.settings.RunningServices.equals(intentClass)|| com.android.settings.applications.StorageUse.equals(intentClass)) {// Old names of manage apps.intentClass com.android.settings.applications.ManageApplications.class.getName();}return intentClass;}/*** Override initial header when an activity-alias is causing Settings to be launched* for a specific fragment encoded in the android:name parameter.*/Overridepublic Header onGetInitialHeader() {String fragmentClass getStartingFragmentClass(super.getIntent());if (fragmentClass ! null) {Header header new Header();header.fragment fragmentClass;header.title getTitle();header.fragmentArguments getIntent().getExtras();mCurrentHeader header;return header;}return mFirstHeader;}Overridepublic Intent onBuildStartFragmentIntent(String fragmentName, Bundle args,int titleRes, int shortTitleRes) {Intent intent super.onBuildStartFragmentIntent(fragmentName, args,titleRes, shortTitleRes);// some fragments want to avoid split actionbarif (DataUsageSummary.class.getName().equals(fragmentName) ||PowerUsageSummary.class.getName().equals(fragmentName) ||AccountSyncSettings.class.getName().equals(fragmentName) ||UserDictionarySettings.class.getName().equals(fragmentName)) {intent.putExtra(EXTRA_CLEAR_UI_OPTIONS, true);}intent.setClass(this, SubSettings.class);return intent;}/*** Populate the activity with the top-level headers.*/Overridepublic void onBuildHeaders(ListHeader headers) {//start by liweiping 20130103//if(UNIVERSEUI_SUPPORT){// loadHeadersFromResource(R.xml.settings_headers_uui, headers);//}else{// loadHeadersFromResource(R.xml.settings_headers, headers);//}Log.i(lwp, mTabFlag mTabFlag , headers.size() headers.size() );if (mTabFlag FLAG_TAB_WIRELESS_NETWORKS){loadHeadersFromResource(R.xml.settings_headers_wireless_networks, headers);}else if(mTabFlag FLAG_TAB_DEVICE){loadHeadersFromResource(R.xml.settings_headers_device, headers);}else if(mTabFlag FLAG_TAB_PERSONAL){loadHeadersFromResource(R.xml.settings_headers_personal, headers);}else{loadHeadersFromResource(R.xml.settings_headers_system, headers);}//end by liweiping 20130103updateHeaderList(headers);//start by liweiping 20130107 for bug 1146//mHeaders headers;if(mHeaders ! null){mHeaders.clear();mHeaders.addAll(headers);}//end by liweiping 20130107}private void updateHeaderList(ListHeader target) {int i 0;while (i target.size()) {Header header target.get(i);// Ids are integers, so downcastingint id (int) header.id;if (id R.id.dock_settings) {if (!needsDockSettings())target.remove(header);} else if (id R.id.operator_settings || id R.id.manufacturer_settings) {Utils.updateHeaderToSpecificActivityFromMetaDataOrRemove(this, target, header);} else if (id R.id.wifi_settings) {// Remove WiFi Settings if WiFi service is not available.// modified by zhangguixin// if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI)) {if (!SystemProperties.getBoolean(ro.device.support.wifi, true)) {// if (0.equals(SystemProperties.getBoolean(ro.device.support.wifi, 1))) {target.remove(header);}} else if (id R.id.bluetooth_settings) {// Remove Bluetooth Settings if Bluetooth service is not available.// modified by zhangguixin// if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH)) {if (!SystemProperties.getBoolean(ro.device.support.bt, true)) {// if (0.equals(SystemProperties.getBoolean(ro.device.support.bt, 1))) {target.remove(header);}} else if (id R.id.dual_sim_settings) {if (!TelephonyManager.isMultiSim()) {target.remove(header);}} else if (id R.id.data_usage_settings sc8825.equalsIgnoreCase(SystemProperties.get(ro.board.platform, sc8825))) {//fix bug182500target.remove(header);}//add by huangweiwei, topwise, 2013-10-12else if (id R.id.development_settings) {if (android.os.TopwiseProp.getDefaultSettingBoolean(settings_remove_development, false)) {target.remove(header);}}//add end by huangweiwei, topwise, 2013-10-12// Increment if the current one wasnt removed by the Utils code.if (target.get(i) header) {// Hold on to the first header, when we need to reset to the top-levelif (mFirstHeader null HeaderAdapter.getHeaderType(header) ! HeaderAdapter.HEADER_TYPE_CATEGORY) {mFirstHeader header;}mHeaderIndexMap.put(id, i);i;}}}private boolean needsDockSettings() {return getResources().getBoolean(R.bool.has_dock_settings);}private void getMetaData() {try {ActivityInfo ai getPackageManager().getActivityInfo(getComponentName(),PackageManager.GET_META_DATA);if (ai null || ai.metaData null) return;mTopLevelHeaderId ai.metaData.getInt(META_DATA_KEY_HEADER_ID);mFragmentClass ai.metaData.getString(META_DATA_KEY_FRAGMENT_CLASS);// Check if it has a parent specified and create a Header objectfinal int parentHeaderTitleRes ai.metaData.getInt(META_DATA_KEY_PARENT_TITLE);String parentFragmentClass ai.metaData.getString(META_DATA_KEY_PARENT_FRAGMENT_CLASS);if (parentFragmentClass ! null) {mParentHeader new Header();mParentHeader.fragment parentFragmentClass;if (parentHeaderTitleRes ! 0) {mParentHeader.title getResources().getString(parentHeaderTitleRes);}}} catch (NameNotFoundException nnfe) {// No recovery}}Overridepublic boolean hasNextButton() {return super.hasNextButton();}Overridepublic Button getNextButton() {return super.getNextButton();}private static class HeaderAdapter extends ArrayAdapterHeader {static final int HEADER_TYPE_CATEGORY 0;static final int HEADER_TYPE_NORMAL 1;static final int HEADER_TYPE_SWITCH 2;private static final int HEADER_TYPE_COUNT HEADER_TYPE_SWITCH 1;private final WifiEnabler mWifiEnabler;private final BluetoothEnabler mBluetoothEnabler;private SparseArrayView mViewCache;private static class HeaderViewHolder {ImageView icon;TextView title;TextView summary;Switch switch_;}private LayoutInflater mInflater;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) {return HEADER_TYPE_SWITCH;} else {return HEADER_TYPE_NORMAL;}}Overridepublic int getItemViewType(int position) {Header header getItem(position);return getHeaderType(header);}//start by liweiping 20140106Overridepublic void notifyDataSetChanged() {// TODO Auto-generated method stubsuper.notifyDataSetChanged();mViewCache new SparseArrayView(getCount());}//end by liweiping 20140106Overridepublic boolean areAllItemsEnabled() {return false; // because of categories}Overridepublic boolean isEnabled(int position) {return getItemViewType(position) ! HEADER_TYPE_CATEGORY;}Overridepublic int getViewTypeCount() {return HEADER_TYPE_COUNT;}Overridepublic boolean hasStableIds() {return true;}public HeaderAdapter(Context context, ListHeader objects) {super(context, 0, objects);mInflater (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);// Temp Switches provided as placeholder until the adapter replaces these with actual// Switches inflated from their layouts. Must be done before adapter is set in supermWifiEnabler new WifiEnabler(context, new Switch(context));mBluetoothEnabler new BluetoothEnabler(context, new Switch(context));mViewCache new SparseArrayView(objects.size());}Overridepublic View getView(int position, View convertView, ViewGroup parent) {HeaderViewHolder holder;Header header getItem(position);int headerType getHeaderType(header);View view null;convertView mViewCache.get(position);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_NORMAL:view mInflater.inflate(com.android.internal.R.layout.preference_header_item, parent,false);holder.icon (ImageView) view.findViewById(com.android.internal.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.setBackgroundDrawable(null);view.setTag(holder);mViewCache.put(position, view);} else {view convertView;holder (HeaderViewHolder) view.getTag();return view;}// All view fields must be updated every time, because the view may be recycledswitch (headerType) {case HEADER_TYPE_CATEGORY:holder.title.setText(header.getTitle(getContext().getResources()));holder.title.setTextColor(android.R.color.transparent);//add by liweiping 20130826break;case HEADER_TYPE_SWITCH:// Would need a different treatment if the main menu had more switchesif (header.id R.id.wifi_settings) {mWifiEnabler.setSwitch(holder.switch_);} else {mBluetoothEnabler.setSwitch(holder.switch_);}// No break, fall through on purpose to update common fields//$FALL-THROUGH$case HEADER_TYPE_NORMAL:holder.icon.setImageResource(header.iconRes);holder.title.setText(header.getTitle(getContext().getResources()));CharSequence summary header.getSummary(getContext().getResources());if (!TextUtils.isEmpty(summary)) {holder.summary.setVisibility(View.VISIBLE);holder.summary.setText(summary);} else {holder.summary.setVisibility(View.GONE);}break;}//start by liweiping 20130826if (header.fragment null header.intent null) {view.setBackgroundColor(android.R.color.transparent); }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){view.setBackgroundResource(com.android.internal.R.drawable.easy_pref_item_top);}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){view.setBackgroundResource(com.android.internal.R.drawable.easy_pref_item_bottom);}else {view.setBackgroundResource(com.android.internal.R.drawable.easy_pref_item_center);}//end by liweiping 20130826return view;}public void resume() {mWifiEnabler.resume();mBluetoothEnabler.resume();}public void pause() {mWifiEnabler.pause();mBluetoothEnabler.pause();}}Overridepublic boolean onPreferenceStartFragment(PreferenceFragment caller, Preference pref) {// Override the fragment title for Wallpaper settingsint titleRes pref.getTitleRes();if (pref.getFragment().equals(WallpaperTypeSettings.class.getName())) {titleRes R.string.wallpaper_settings_fragment_title;}startPreferencePanel(pref.getFragment(), pref.getExtras(), titleRes, null, null, 0);return true;}//start,added by topwise hehuadong in 2013.10.24Overridepublic void onHeaderClick(Header header, int position) {// TODO Auto-generated method stub//start by liweiping 20140105final SharedPreferences settings PreferenceManager.getDefaultSharedPreferences(this);settings.edit().putInt(tab, mTabFlag).commit();Log.i(lwp-log, onHeaderClick... settings.getInt(tab, -1));//end by liweiping 20140105if (TopwiseProp.getDefaultSettingString(default_customize_about_device)!null){if (header ! null header.fragment !null header.fragment.equals(com.android.settings.DeviceInfoSettings)){header.fragmentcom.android.settings.AboutDeviceSettings;}}super.onHeaderClick(header, position);}//end,added by topwise hehuadong in 2013.10.24Overridepublic void setListAdapter(ListAdapter adapter) {if (mHeaders null) {mHeaders new ArrayListHeader();// When the saved state provides the list of headers, onBuildHeaders is not called// Copy the list of Headers from the adapter, preserving their orderfor (int i 0; i adapter.getCount(); i) {mHeaders.add((Header) adapter.getItem(i));}}// Ignore the adapter provided by PreferenceActivity and substitute ours insteadsuper.setListAdapter(new HeaderAdapter(this, mHeaders));}/** Settings subclasses for launching independently.*/public static class BluetoothSettingsActivity extends Settings { /* empty */ }public static class WirelessSettingsActivity extends Settings { /* empty */ }public static class TetherSettingsActivity extends Settings { /* empty */ }public static class VpnSettingsActivity extends Settings { /* empty */ }public static class DateTimeSettingsActivity extends Settings { /* empty */ }public static class StorageSettingsActivity extends Settings { /* empty */ }public static class WifiSettingsActivity extends Settings { /* empty */ }public static class WifiP2pSettingsActivity extends Settings { /* empty */ }public static class InputMethodAndLanguageSettingsActivity extends Settings { /* empty */ }public static class InputMethodAndSubtypeEnablerActivity extends Settings { /* empty */ }public static class SpellCheckersSettingsActivity extends Settings { /* empty */ }public static class LocalePickerActivity extends Settings { /* empty */ }public static class UserDictionarySettingsActivity extends Settings { /* empty */ }public static class SoundSettingsActivity extends Settings { /* empty */ }public static class DisplaySettingsActivity extends Settings { /* empty */ }public static class DeviceInfoSettingsActivity extends Settings { /* empty */ }public static class ApplicationSettingsActivity extends Settings { /* empty */ }public static class ManageApplicationsActivity extends Settings { /* empty */ }public static class StorageUseActivity extends Settings { /* empty */ }public static class DevelopmentSettingsActivity extends Settings { /* empty */ }public static class AccessibilitySettingsActivity extends Settings { /* empty */ }public static class SecuritySettingsActivity extends Settings { /* empty */ }public static class LocationSettingsActivity extends Settings { /* empty */ }public static class PrivacySettingsActivity extends Settings { /* empty */ }public static class DockSettingsActivity extends Settings { /* empty */ }public static class RunningServicesActivity extends Settings { /* empty */ }public static class ManageAccountsSettingsActivity extends Settings { /* empty */ }public static class PowerUsageSummaryActivity extends Settings { /* empty */ }public static class AccountSyncSettingsActivity extends Settings { /* empty */ }public static class AccountSyncSettingsInAddAccountActivity extends Settings { /* empty */ }public static class CryptKeeperSettingsActivity extends Settings { /* empty */ }public static class DeviceAdminSettingsActivity extends Settings { /* empty */ }public static class DataUsageSummaryActivity extends Settings { /* empty */ }public static class AdvancedWifiSettingsActivity extends Settings { /* empty */ }public static class TextToSpeechSettingsActivity extends Settings { /* empty */ }public static class AndroidBeamSettingsActivity extends Settings { /* empty */ } } 简单分析一下 ①.首先我们在onResume中找到setActionBarStyle这个函数这就是设置每次恢复时的必经之路在这里我们改变ActionBar的样式如果是一级界面就加上tab风格二级界面就去掉tab风格显示返回键。 /* Set ActionBar with popup function */protected void setActionBarStyle() {ActionBar actionBar getActionBar();if (actionBar null){return;}//start by liweiping 20140106Log.i(lwp-log, this.toString() this.toString());//if ( this.toString().contains(SubSettings) ) {if ( this.toString().contains(SubSettings) || this.toString().contains($)) {//end by liweiping 20140106actionBar.setDisplayOptions(ActionBar.DISPLAY_HOME_AS_UP, ActionBar.DISPLAY_HOME_AS_UP);actionBar.setDisplayHomeAsUpEnabled(true);}else {actionBar.setDisplayOptions(ActionBar.DISPLAY_HOME_AS_UP^ ActionBar.DISPLAY_HOME_AS_UP, ActionBar.DISPLAY_HOME_AS_UP);actionBar.setDisplayHomeAsUpEnabled(false);//start by liweiping 20140103actionBar.setAlternativeTabStyle(true);actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);if(actionBar.getTabCount() 0){setupWirelessNetworks(actionBar);setupDevice(actionBar);setupPersonal(actionBar);setupSystem(actionBar);}final SharedPreferences settings PreferenceManager.getDefaultSharedPreferences(this);mTabFlag settings.getInt(tab, FLAG_TAB_WIRELESS_NETWORKS);Log.i(lwp-log, setActionBarStyle mTabFlag mTabFlag);actionBar.selectTab(actionBar.getTabAt(mTabFlag));//end by liweiping 20140103}} ②.监听tab的选择事件点击每一个tab产生对应的事件然后把选择项存为全局变量mTabFlag中最后调用invalidateHeaders()函数刷新界面替换成不同的Header list。 private final TabListener mTabListener new TabListener() {Overridepublic void onTabUnselected(Tab tab, FragmentTransaction ft) {// TODO Auto-generated method stub}Overridepublic void onTabSelected(Tab tab, FragmentTransaction ft) {//Log.i(lwp-log, tab.getContentDescription().toString() tab.getContentDescription().toString());if (tab.getContentDescription().toString().equals(getResources().getString(R.string.header_category_wireless_networks))){mTabFlag FLAG_TAB_WIRELESS_NETWORKS;}else if(tab.getContentDescription().toString().equals(getResources().getString(R.string.header_category_personal))) {mTabFlag FLAG_TAB_PERSONAL;} else if (tab.getContentDescription().toString().equals(getResources().getString(R.string.header_category_system))) {mTabFlag FLAG_TAB_SYSTEM;} else if (tab.getContentDescription().toString().equals(getResources().getString(R.string.header_category_device))) {mTabFlag FLAG_TAB_DEVICE;}Log.i(lwp-log, onTabSelected mTabFlag mTabFlag);invalidateHeaders();}Overridepublic void onTabReselected(Tab tab, FragmentTransaction ft) {}}; ③.当调用invalidateHeaders()函数时就进入了onBuildHeaders(ListHeader headers)函数在这里我们需要根据mTabFlag来loadHeadersFromResource对应的布局文件最后一定要记住用新的headers将全局变量mHeaders替换掉。 /*** Populate the activity with the top-level headers.*/Overridepublic void onBuildHeaders(ListHeader headers) {//start by liweiping 20130103//if(UNIVERSEUI_SUPPORT){// loadHeadersFromResource(R.xml.settings_headers_uui, headers);//}else{// loadHeadersFromResource(R.xml.settings_headers, headers);//}Log.i(lwp, mTabFlag mTabFlag , headers.size() headers.size() );if (mTabFlag FLAG_TAB_WIRELESS_NETWORKS){loadHeadersFromResource(R.xml.settings_headers_wireless_networks, headers);}else if(mTabFlag FLAG_TAB_DEVICE){loadHeadersFromResource(R.xml.settings_headers_device, headers);}else if(mTabFlag FLAG_TAB_PERSONAL){loadHeadersFromResource(R.xml.settings_headers_personal, headers);}else{loadHeadersFromResource(R.xml.settings_headers_system, headers);}//end by liweiping 20130103updateHeaderList(headers);//start by liweiping 20130107 for bug 1146//mHeaders headers;if(mHeaders ! null){mHeaders.clear();mHeaders.addAll(headers);}//end by liweiping 20130107} OK今天就大概这样了。 转载于:https://my.oschina.net/cjkall/blog/195789
http://www.zqtcl.cn/news/515354/

相关文章:

  • 专门做私人定制旅游的网站专做韩餐网站
  • 网站 续费wordpress首页调用指定分类
  • 2008系统怎么做网站免费设计软件下载
  • 做电音的软件的专业下载网站宁波俄语网站建设
  • 北?? 网站建设旅游手机网站开发
  • 乐清做网站的网站备案容易通过吗
  • 网站qq登录 开发一个小型网站开发成本
  • 湖北网络建设公司网站js跳转到别的网站
  • 郑州网站app开发的汽车网站 源码
  • 河南网站建设企业做网站多少钱西宁君博示范
  • 沈阳有做网站的吗青浦手机网站制作
  • 腾讯云免费建站建立一个网站英语
  • 沙漠风网站建设怎么样官方网站建设银行2010年存款利息
  • 360报危险网站微信代码小程序
  • 网站维护报价单国外 做励志视频的网站
  • 用源码做自己的网站公司网站建设哪家公司好
  • 网站运营做seohtml前端网站开发PPT
  • 上海网站定制设计图wordpress网站在线安装
  • 互动网站的核心技术wordpress不用插件
  • 厦门市建设工程交易中心网站怎么自己做游戏软件的app
  • 网站论文参考文献人力资源公司名称大全简单大气
  • 射阳做企业网站哪家好wordpress 进销存
  • 青海个人旅游网站建设wordpress用户名密码加密方式
  • 安徽平台网站建设找哪家wordpress首页加登录
  • 雅安市住房和城乡建设局网站湖南全程电子化服务平台官网
  • dw做的上传网站打不开网页制作培训价格
  • 工程网站怎么做广州做网站平台
  • 成都网站建设 全美深圳定制网站建设
  • 邢台网站建设与制作陕西高速公路建设集团网站
  • 太原 招聘 网站建设 技术经理关于 建设 二级网站