1.使用Fragment搭建ui框架java
參考分析圖android
1.1,Fragment生命週期面試
Is added(被添加以後)數據庫
>>onAttach()>>onCreate()>>onCreateView()//建立佈局>>onActivityCreated();//當activity建立好後(onCreate()執行完了以後)>>onStart()>>onResume()>>onPause()>>onStop()>>onDestory()json
1.2 建立一個Fragment的基類:參考名baseFragment(用v4保持版本兼容)數組
onCreate()//Fragment建立緩存
能夠拿到這個Fragment所在的Activity對象tomcat
mActivity = getActivity();//成員變量通常加m性能優化
onCreateView()//初始化Fragment的佈局服務器
返回的View就是Fragment對應的佈局
但由於這個類是基類,因此不該該直接返回View
建立一個抽象方法讓子類去實現,傳入View並返回它
而後在onCreateView()中返回這個View便可
onActivityCreate()//fragment所依賴的acitivity的onCreate()方法執行完畢
能夠用來初始化數據
一樣寫一個抽象方法,讓子類實現,在這個方法裏重寫數據
1.3 建立兩個子Fragment
①LeftMenuFragment的建立,繼承基類,重寫抽象的方法
可是在這裏View.inflate()中,不能直接用this,由於Fragment是不繼承上下文的,可是能夠經過基類中獲取的mActivity當作上下文傳入
②ContentFragment的建立,步驟基本上同樣
重寫該重寫的方法,返回對應的佈局文件
1.4,在主界面的側邊欄和主菜單中,設置的佈局文件清空(通常根節點用FrameLayout,乾淨)
在主界面的activity中,建立一個方法用來初始化Fragment
①拿到Fragment管理器>>
fm = getSupportFragmentManager()//兼容低版本的管理器
transaction = fm.beginTransaction();//開始事務
Transaction.replace(id,fragment)//id,給fragment提供的位置,fragment對象
若是參數異常就寫個配置文件,名稱與jar包一致(包含後綴名.properties)
內容爲src=XXXX//源碼的路徑(在sdk/extras/android/xxx下 v4包的源碼)
而後重啓Eclipse便可
//兩個Fragment能夠一塊兒替換
Transaction.commit()//提交事務
在Activity的onCreate()時調用
Transaction.Replasc()也有三個參數的,tag(String)第三個參數,之後找起來會比較方便
fm.findFragmentByTag(String tag)//經過Fragment管理器找到標記獲取Fragment的對象.
2,主頁面
2.1 主頁面分析:從上至下(先不看內容填充)
上面是一個Viewpager
下面是一個RadioGroup + RadioButton
2.2 在ContentFragment中,搭建ui框架
2.2.1底部導航欄
RadioButton中 能夠設置屬性Button = @null//去掉能夠被選中的小圓框
圖片是經過drawableTop設置出來的
RadioButton背景設置全透明(由於有的手機上會有顯示問題)
一樣的,要設置狀態選擇器(選中的(state_checked)狀態選擇器)
記得要設置ID,不設置ID的話,所有都會被選中
默認設置首頁被選中
2.2.2 ViewPager顯示
①界面分析:
每個ViewPager頁面都有共同的地方,
因此抽取一個佈局基類base_pager
抽取一個標題的佈局title_bar
在base_pager 中include導入這個佈局
② 建立一個類(base包下)(單純的類,什麼都不繼承)
BasePager表示ViewPager每個頁面的基類
這個類表明五個標籤頁的基本類
建立方法:initView()//初始化佈局,在構造中把Activity傳進來便可
在這裏把佈局View找到,找到中間關心的控件
//返回這個佈局對應的View便可,在構造中把這個View用成員變量記錄下來
initData()//初始化數據
③建立實現類(impl包):
建立一個首頁類繼承base_pager類
重寫的初始化數據方法中,new一個TextView(根據頁面內容來,這裏首頁內容就只是一個TextView,因此只要new 一個TextView就能夠了)
拿到空的幀佈局對象(在Base_pager已經找到它了,能夠以直接使用)
而後依次把其它幾個標籤頁的建立出來(這裏先不用填充數據)
3.填充標籤頁,禁用ViewPager的滑動事件
3.1 建立ViewPager適配器
3.2 初始化5個標籤頁
建立一個集合保存五個BasePager對象
PagerAdapter中instantiateItem()初始化一個View對象的時候
經過BasePager.mRootView獲取到這個標籤頁對應的View對象,返回它
記得調用一下initData()讓它生效
而後添加到ViewPager上面
額外:右擊方法名,Open Call Hierachy能夠看到調用的層級結構
3.3 禁用ViewPager的滑動換頁(自定義一個ViewPager)參考:noScrollViewPager
重寫一下onTouchEvent(event)直接返回true便可
由於google的工程師就是在觸摸事件裏讓頁面滑動的,因此返回true就能夠了
3.4 點擊標籤切換頁面&&性能優化
①拿到RadioGroup對象,設置切換監聽器
②經過重寫的方法裏checkedId對應的選項,判斷是哪個標籤卡被選中了.
mViewPager.setCurrentItem(對應的索引就能夠了,是否要平緩滑動效果(flase));
一個參數的就默認帶有動畫效果了
③ViewPager會提早加載下一個標籤,在這裏是沒有必要預加載的.
ViewPager原生的方法修改起來很麻煩,因此在初始化數據的時候,不要直接調用initData()方法,由於初始化數據再有些標籤卡中很耗時間
解決方式:設置ViewPager的頁面監聽,或在RadioButton中裏面寫
這裏用ViewPager的頁面監聽來寫,代碼更簡練一些?
在監聽方法中,經過頁面被選中的方法,參數Position來初始化數據
額外:進入界面的時候沒有數據
在接入界面的時候加載上默認的數據
4,側邊欄的開啓和禁用(在中間三個選項卡能夠劃出來側邊欄,第一個和最後一個標籤沒有側邊欄,這個根據狀況來的)
4.1 隱藏側邊欄的按鈕,在每個標籤的實現類中,隱藏對應的按鈕
4.2 當第一個頁面和最後一個頁面被選中的時候
在ViewPager的監聽器中,當選中的position爲第一個或最後一個的時候
禁用掉側邊欄
獲取側邊欄對象
在ContentFragment中經過mActivity(SlidingMenuFragmentActivity)強轉拿到
而後獲取到側邊欄對象
設置滑動模式
SlidingMenu.setTouchMode(SlidingMenu.TOUCHMODE_NONE);//設置模式
5,新聞中心頁面的開發
①新聞中心的數據都是網絡傳遞過來的,包括側邊欄的內容也是解析網絡數據獲得的(使用服務器數據,把zhbj的文件夾丟到tomcat服務器的root下訪問)
訪問地址:服務器//zhbj/categories.json
工具:HiJson,把JSON串拷貝進來,能夠格式化JSON字符串,方便閱讀
解析JSON串[]表明JSON數組,{}表明JSON對象
有的JSON串最後會有retcode 表示這個JSON串是否獲取成功
②使用XUtils請求數據
在須要請求服務器的標籤類中initData()中請求網絡
XUtils開源框架,四大模塊
DBUtils,ViewUtils,HttpUtils,BitMapUtils(這裏會用到後面三個模塊)
6,Xutils使用
獲取Xutils對象
HttpUtils utils = new HttpUtils();
Utils.send(HttpMethod.GET,url(不寫死,寫到一個類中),new RequestCallBackXX())
GlobalConstans類下
Public static final String SERVER_URL=」服務器主域名」
http://10.0.2.2(模擬器訪問本機ip):8080/zhbj
Public static final String categories_URL=SERVER_URL + 」/cetgories.json」;//類別
在回調方法中,
請求成功的方法,獲取結果response.result.
請求失敗的方法參數error,msg
error.printStackTrace()//打印錯誤信息
msg String錯誤信息
7,使用Gson解析Json
Gson:google爲了提升json解析效率搞出來的玩意(jar包)
Gson gson = new Gson();
gson.fromjson(String,clazz);//clazz是保存服務器數據的javaBean
建立一個JSON封裝類(照着JSON串來寫)
遇到大括號,就是一個對象,遇到中括號就是一個集合
最外層的大對象就
public int retcode;
Public ArrayList<Integer> extend //由於下面是一堆數據,通常用集合裝下來
Public ArrayList data//只要是中括號,大部分狀況下能夠用集合表示
遇到大括號,在這個類中建立一個類,表示這個對象的內容
若是是單個的字段(用不上的不用解析)直接建立成員變量就行
Public int id ;
若是又是一個大括號,再建立一個平行的內部類
依次建立下去便可
使用JSON解析時,對象書寫技巧:
逢{}建立對象,逢[]建立和,全部名稱要和JSON字段高度一致(類名無所謂)
建立完畢後
gson.fromJson(json.clazz)//返回的就是這個clazz 對象
8,網絡緩存
原理:將JSON數據做爲緩存的內容,標示爲:URL路徑
緩存的東西就是JSON字符串.因此要保持URL與 JSON串相互對應的關係
①寫一個工具類 CacheUtils
應該有兩個方法,
寫緩存setCache(String url,String json,Context,context)
以url爲key,以json爲value,保存在本地
這裏保存在sp中比較方便
讀緩存getCache(String url);//經過sp讀到緩存內容,返回緩存便可(默認爲null)
②使用方式:
須要請求數據的標籤,先判斷有沒有緩存(是否爲null)
若是有的話,就直接解析數據,不然就訪問網絡,獲取數據
寫緩存的位置,在請求完數據以後寫入
細節1:URL可能不是一直對應這個JSON串
解決1:給緩存設置有效期(一個禮拜或一天,必須刷新一次)
解決2:讀緩存的時候(讀取完了緩存,調用一下解析數據的方法),不論是否有緩存都請求一次服務器(不用擔憂新舊緩存的問題,這樣既有老的數據,可讓用戶先看到一些數據,用戶體驗好一些,而後網絡加載完以後更新,用戶耐心更好)
細節2:儲存在sp中會致使sp可讀性太差
解決1:數據庫
解決2:用文件儲存
以URL爲文件名,以JSON爲文件內容,讀緩存的時候就直接查找有沒有緩存文件便可.
可是URL有可能有特殊字符,因此能夠用MD5轉換一下,就能夠做爲文件名
注意:網絡緩存通常就是緩存的JSON,面試問到也就是緩存JSON
若是URL後面帶參數,也是一樣要帶參數的(路徑拼接便可)
9,設置新聞中心的側邊欄數據
重點是如何拿到側邊欄對象
在這裏MainActivity其實已經獲取到了,就是mActivity;
在解析數據的方法裏
經過mActivity強轉獲得MainActivity
在MainActivity中,建立一個方法,找到側邊欄對象
FragmentManager .findFragmentByTag()//經過前面設置的標籤獲取Fragment對象
而後在新聞中心的Pager類中,拿到側邊欄對象
在側邊欄Fragment類中,建立一個方法設置數據,在新聞中心類中,把須要傳遞的數據經過參數傳遞過去(JSON串中的新聞中心數據)
這裏的側邊欄其實就是一個ListView
把傳遞過來的新聞中心數據解析出來,傳遞到ListView上
這裏使用ViewUtils模塊,使用註解的方法替代fbc和onClick;
①注入View和事件
ViewUtils.inject(this,view);
②建立須要替代的成員變量:
@ViewInject(id)
Private ListView mListView;
ViewUtils底層其實也是fbc,不過是經過註解的方式封裝好了.
③建立適配器,設置數據
getItem()能夠直接返回一個與position相關的對象(這裏能夠把它的返回值對象改了)
getItemId()能夠直接把position返回
getView()方法
須要再寫一個item的佈局文件
這裏的側邊欄條目狀態選擇器,經過enabled是否可用來設置狀態
(由於LIstView不像 RadioButton,有選中和不被選中的選擇)
定義一個成員變量記錄被點擊(也就是被選中的條目)就讓它設置可用,不然設置不可用
④設置ListView點擊事件監聽器
更新被點擊的條目,而後刷新適配器(由於側邊欄條目比較少,因此不影響太多效率)
⑤優化:點擊了其它條目,應該收集側邊欄
建立一個方法,toggle()//開關的方法
經過mainActivity(mainUi)拿到側邊欄對象
slidingMenu.toggle()//調用以後會根據當前狀態自動判斷是否顯示
額外:設置左上角的按鈕事件
10,點擊側邊欄切換菜單詳情頁
側邊欄點擊以後,要修改Fragment裏面的內容
搭建詳情頁Ui框架
①抽取一個菜單詳情頁的基類BaseMenuDetailPager
一樣的,在構造方法裏獲取到mActivity.調用initView()方法獲得返回的View
這個基類的initView()由於每一個孩子的都不同,因此讓子類去強制實現
initData()//這個方法能夠強制,也能夠不強制
而後把四個詳情頁都建立出來
這裏爲了觀察方便,先返回四個簡單的TextView
②在側邊欄頁面中設置當前的菜單詳情頁(抽取方法)setCurrentDetailPager()
重點是拿到菜單詳情頁對象
先拿到MainActivity(mainUi),同拿到側邊欄同樣,拿到主頁
經過主頁的mPagers集合,拿到新聞中心的對象
參考名getNewsCenterPager()
而後在NewsCenterPager類中建立方法setCurrentDetailPager(int position)索引傳遞
在側邊欄中,經過它的對象調用這個方法
11.,實現側邊欄詳情頁的切換
在NewsCenterPager建立的方法setCurrentDetailPager(int position)中,
從新給它所在的Fragment設置內容
建立一個集合保存下這四個菜單詳情頁pager.
在上面的方法裏,拿到對應索引的pager對象,拿到佈局
而後把view添加到幀佈局中
添加的同時,也要初始化數據
額外1:添加以前要把幀佈局中以前的View清理掉,removeAllViews();
額外2:新聞中心默認應該顯示新聞菜單pager的內容
解析完數據,切換新聞詳情頁
額外3:更新標題,最簡單方法,就是解析數據時候把網絡數據的信息直接傳進來
額外4:下方導航欄切換以後,再切換到新聞中心,側邊欄數據不變
須要在每次切換到新聞中心以後,會調用側邊欄設置數據的方法裏,在這個方法裏把側邊欄的索引歸零(修改記錄選中的變量便可)