智慧北京02_初步ui框架_ 主界面_viewPager事件_xUtils_slidingMenu_网络缓存_数据传递...
1.使用Fragment搭建ui框架
參考分析圖
?
?
1.1,Fragment生命周期
Is added(被添加之后)
>>onAttach()>>onCreate()>>onCreateView()//創(chuàng)建布局>>onActivityCreated();//當(dāng)activity創(chuàng)建好后(onCreate()執(zhí)行完了之后)>>onStart()>>onResume()>>onPause()>>onStop()>>onDestory()
?
1.2 創(chuàng)建一個(gè)Fragment的基類:參考名baseFragment(用v4保持版本兼容)
onCreate()//Fragment創(chuàng)建
可以拿到這個(gè)Fragment所在的Activity對(duì)象
mActivity = getActivity();//成員變量一般加m
?
onCreateView()//初始化Fragment的布局
返回的View就是Fragment對(duì)應(yīng)的布局
但因?yàn)檫@個(gè)類是基類,所以不應(yīng)該直接返回View
創(chuàng)建一個(gè)抽象方法讓子類去實(shí)現(xiàn),傳入View并返回它
然后在onCreateView()中返回這個(gè)View即可
?
onActivityCreate()//fragment所依賴的acitivity的onCreate()方法執(zhí)行完畢
可以用來(lái)初始化數(shù)據(jù)
同樣寫一個(gè)抽象方法,讓子類實(shí)現(xiàn),在這個(gè)方法里重寫數(shù)據(jù)
?
1.3 創(chuàng)建兩個(gè)子Fragment
?①LeftMenuFragment的創(chuàng)建,繼承基類,重寫抽象的方法
但是在這里View.inflate()中,不能直接用this,因?yàn)?/span>Fragment是不繼承上下文的,但是可以通過(guò)基類中獲取的mActivity當(dāng)做上下文傳入
?
②ContentFragment的創(chuàng)建,步驟基本上一樣
重寫該重寫的方法,返回對(duì)應(yīng)的布局文件
?
1.4,在主界面的側(cè)邊欄和主菜單中,設(shè)置的布局文件清空(一般根節(jié)點(diǎn)用FrameLayout,干凈)
在主界面的activity中,創(chuàng)建一個(gè)方法用來(lái)初始化Fragment
①拿到Fragment管理器>>
fm = getSupportFragmentManager()//兼容低版本的管理器
transaction = fm.beginTransaction();//開(kāi)始事務(wù)
Transaction.replace(id,fragment)//id,給fragment提供的位置,fragment對(duì)象
如果參數(shù)異常就寫個(gè)配置文件,名稱與jar包一致(包含后綴名.properties)
內(nèi)容為src=XXXX//源碼的路徑(在sdk/extras/android/xxx下 v4包的源碼)
然后重啟Eclipse即可
//兩個(gè)Fragment可以一起替換
Transaction.commit()//提交事務(wù)
在Activity的onCreate()時(shí)調(diào)用
Transaction.Replasc()也有三個(gè)參數(shù)的,tag(String)第三個(gè)參數(shù),以后找起來(lái)會(huì)比較方便
?
fm.findFragmentByTag(String tag)//通過(guò)Fragment管理器找到標(biāo)記獲取Fragment的對(duì)象.
?
2,主頁(yè)面
?
?
?
2.1 主頁(yè)面分析:從上至下(先不看內(nèi)容填充)
上面是一個(gè)Viewpager
下面是一個(gè)RadioGroup + RadioButton
?
2.2 在ContentFragment中,搭建ui框架
2.2.1底部導(dǎo)航欄
RadioButton中 可以設(shè)置屬性Button = @null//去掉可以被選中的小圓框
圖片是通過(guò)drawableTop設(shè)置出來(lái)的
RadioButton背景設(shè)置全透明(因?yàn)橛械氖謾C(jī)上會(huì)有顯示問(wèn)題)
同樣的,要設(shè)置狀態(tài)選擇器(選中的(state_checked)狀態(tài)選擇器)
記得要設(shè)置ID,不設(shè)置ID的話,全部都會(huì)被選中
默認(rèn)設(shè)置首頁(yè)被選中
?
2.2.2 ViewPager顯示
①界面分析:
?
?
每一個(gè)ViewPager頁(yè)面都有共同的地方,
所以抽取一個(gè)布局基類base_pager
抽取一個(gè)標(biāo)題的布局title_bar
在base_pager 中include導(dǎo)入這個(gè)布局
② 創(chuàng)建一個(gè)類(base包下)(單純的類,什么都不繼承)
BasePager表示ViewPager每一個(gè)頁(yè)面的基類
這個(gè)類代表五個(gè)標(biāo)簽頁(yè)的基本類
創(chuàng)建方法:initView()//初始化布局,在構(gòu)造中把Activity傳進(jìn)來(lái)即可
在這里把布局View找到,找到中間關(guān)心的控件
//返回這個(gè)布局對(duì)應(yīng)的View即可,在構(gòu)造中把這個(gè)View用成員變量記錄下來(lái)
?
initData()//初始化數(shù)據(jù)
?
③創(chuàng)建實(shí)現(xiàn)類(impl包):
創(chuàng)建一個(gè)首頁(yè)類繼承base_pager類
重寫的初始化數(shù)據(jù)方法中,new一個(gè)TextView(根據(jù)頁(yè)面內(nèi)容來(lái),這里首頁(yè)內(nèi)容就只是一個(gè)TextView,所以只要new 一個(gè)TextView就可以了)
拿到空的幀布局對(duì)象(在Base_pager已經(jīng)找到它了,可以以直接使用)
?
然后依次把其它幾個(gè)標(biāo)簽頁(yè)的創(chuàng)建出來(lái)(這里先不用填充數(shù)據(jù))
?
3.填充標(biāo)簽頁(yè),禁用ViewPager的滑動(dòng)事件
3.1 創(chuàng)建ViewPager適配器
?
3.2 初始化5個(gè)標(biāo)簽頁(yè)
創(chuàng)建一個(gè)集合保存五個(gè)BasePager對(duì)象
PagerAdapter中instantiateItem()初始化一個(gè)View對(duì)象的時(shí)候
通過(guò)BasePager.mRootView獲取到這個(gè)標(biāo)簽頁(yè)對(duì)應(yīng)的View對(duì)象,返回它
記得調(diào)用一下initData()讓它生效
然后添加到ViewPager上面
額外:右擊方法名,Open Call Hierachy可以看到調(diào)用的層級(jí)結(jié)構(gòu)
3.3 禁用ViewPager的滑動(dòng)換頁(yè)(自定義一個(gè)ViewPager)參考:noScrollViewPager
重寫一下onTouchEvent(event)直接返回true即可
因?yàn)?span style="font-family:Calibri;">google的工程師就是在觸摸事件里讓頁(yè)面滑動(dòng)的,所以返回true就可以了
?
3.4 點(diǎn)擊標(biāo)簽切換頁(yè)面&&性能優(yōu)化
①拿到RadioGroup對(duì)象,設(shè)置切換監(jiān)聽(tīng)器
②通過(guò)重寫的方法里checkedId對(duì)應(yīng)的選項(xiàng),判斷是哪一個(gè)標(biāo)簽卡被選中了.
mViewPager.setCurrentItem(對(duì)應(yīng)的索引就可以了,是否要平緩滑動(dòng)效果(flase));
一個(gè)參數(shù)的就默認(rèn)帶有動(dòng)畫(huà)效果了
③ViewPager會(huì)提前加載下一個(gè)標(biāo)簽,在這里是沒(méi)有必要預(yù)加載的.
ViewPager原生的方法修改起來(lái)很麻煩,所以在初始化數(shù)據(jù)的時(shí)候,不要直接調(diào)用initData()方法,因?yàn)槌跏蓟瘮?shù)據(jù)再有些標(biāo)簽卡中很耗時(shí)間
解決方式:設(shè)置ViewPager的頁(yè)面監(jiān)聽(tīng),或在RadioButton中里面寫
這里用ViewPager的頁(yè)面監(jiān)聽(tīng)來(lái)寫,代碼更簡(jiǎn)練一些?
在監(jiān)聽(tīng)方法中,通過(guò)頁(yè)面被選中的方法,參數(shù)Position來(lái)初始化數(shù)據(jù)
?
額外:進(jìn)入界面的時(shí)候沒(méi)有數(shù)據(jù)
在接入界面的時(shí)候加載上默認(rèn)的數(shù)據(jù)
?
4,側(cè)邊欄的開(kāi)啟和禁用(在中間三個(gè)選項(xiàng)卡可以劃出來(lái)側(cè)邊欄,第一個(gè)和最后一個(gè)標(biāo)簽沒(méi)有側(cè)邊欄,這個(gè)根據(jù)情況來(lái)的)
4.1 隱藏側(cè)邊欄的按鈕,在每一個(gè)標(biāo)簽的實(shí)現(xiàn)類中,隱藏對(duì)應(yīng)的按鈕
4.2 當(dāng)?shù)谝粋€(gè)頁(yè)面和最后一個(gè)頁(yè)面被選中的時(shí)候
在ViewPager的監(jiān)聽(tīng)器中,當(dāng)選中的position為第一個(gè)或最后一個(gè)的時(shí)候
禁用掉側(cè)邊欄
獲取側(cè)邊欄對(duì)象
在ContentFragment中通過(guò)mActivity(SlidingMenuFragmentActivity)強(qiáng)轉(zhuǎn)拿到
然后獲取到側(cè)邊欄對(duì)象
設(shè)置滑動(dòng)模式
SlidingMenu.setTouchMode(SlidingMenu.TOUCHMODE_NONE);//設(shè)置模式
?
5,新聞中心頁(yè)面的開(kāi)發(fā)
?
?
①新聞中心的數(shù)據(jù)都是網(wǎng)絡(luò)傳遞過(guò)來(lái)的,包括側(cè)邊欄的內(nèi)容也是解析網(wǎng)絡(luò)數(shù)據(jù)得到的(使用服務(wù)器數(shù)據(jù),把zhbj的文件夾丟到tomcat服務(wù)器的root下訪問(wèn))
訪問(wèn)地址:服務(wù)器//zhbj/categories.json
工具:HiJson,把JSON串拷貝進(jìn)來(lái),可以格式化JSON字符串,方便閱讀
解析JSON串[]代表JSON數(shù)組,{}代表JSON對(duì)象
有的JSON串最后會(huì)有retcode 表示這個(gè)JSON串是否獲取成功
?
②使用XUtils請(qǐng)求數(shù)據(jù)
在需要請(qǐng)求服務(wù)器的標(biāo)簽類中initData()中請(qǐng)求網(wǎng)絡(luò)
XUtils開(kāi)源框架,四大模塊
DBUtils,ViewUtils,HttpUtils,BitMapUtils(這里會(huì)用到后面三個(gè)模塊)
?
6,Xutils使用
獲取Xutils對(duì)象
HttpUtils utils = new HttpUtils();
Utils.send(HttpMethod.GET,url(不寫死,寫到一個(gè)類中),new RequestCallBackXX())
GlobalConstans類下
Public static final String SERVER_URL=”服務(wù)器主域名”
http://10.0.2.2(模擬器訪問(wèn)本機(jī)ip):8080/zhbj
Public static final String categories_URL=SERVER_URL + ”/cetgories.json”;//類別
?
在回調(diào)方法中,
請(qǐng)求成功的方法,獲取結(jié)果response.result.
請(qǐng)求失敗的方法參數(shù)error,msg
error.printStackTrace()//打印錯(cuò)誤信息
msg String錯(cuò)誤信息
?
7,使用Gson解析Json
Gson:google為了提高json解析效率搞出來(lái)的玩意(jar包)
Gson gson = new Gson();
gson.fromjson(String,clazz);//clazz是保存服務(wù)器數(shù)據(jù)的javaBean
創(chuàng)建一個(gè)JSON封裝類(照著JSON串來(lái)寫)
遇到大括號(hào),就是一個(gè)對(duì)象,遇到中括號(hào)就是一個(gè)集合
最外層的大對(duì)象就
public int retcode;
Public ArrayList<Integer> extend //因?yàn)橄旅媸且欢褦?shù)據(jù),一般用集合裝下來(lái)
Public ArrayList data//只要是中括號(hào),大部分情況下可以用集合表示
?
遇到大括號(hào),在這個(gè)類中創(chuàng)建一個(gè)類,表示這個(gè)對(duì)象的內(nèi)容
如果是單個(gè)的字段(用不上的不用解析)直接創(chuàng)建成員變量就行
Public int id ;
如果又是一個(gè)大括號(hào),再創(chuàng)建一個(gè)平行的內(nèi)部類
依次創(chuàng)建下去即可
?
使用JSON解析時(shí),對(duì)象書(shū)寫技巧:
逢{}創(chuàng)建對(duì)象,逢[]創(chuàng)建和,所有名稱要和JSON字段高度一致(類名無(wú)所謂)
創(chuàng)建完畢后
gson.fromJson(json.clazz)//返回的就是這個(gè)clazz 對(duì)象
?
8,網(wǎng)絡(luò)緩存
原理:將JSON數(shù)據(jù)作為緩存的內(nèi)容,標(biāo)示為:URL路徑
緩存的東西就是JSON字符串.所以要保持URL與 JSON串相互對(duì)應(yīng)的關(guān)系
?
①寫一個(gè)工具類 CacheUtils
應(yīng)該有兩個(gè)方法,
寫緩存setCache(String url,String json,Context,context)
以url為key,以json為value,保存在本地
這里保存在sp中比較方便
?
讀緩存getCache(String url);//通過(guò)sp讀到緩存內(nèi)容,返回緩存即可(默認(rèn)為null)
?
②使用方式:
需要請(qǐng)求數(shù)據(jù)的標(biāo)簽,先判斷有沒(méi)有緩存(是否為null)
如果有的話,就直接解析數(shù)據(jù),否則就訪問(wèn)網(wǎng)絡(luò),獲取數(shù)據(jù)
寫緩存的位置,在請(qǐng)求完數(shù)據(jù)之后寫入
?
細(xì)節(jié)1:URL可能不是一直對(duì)應(yīng)這個(gè)JSON串
解決1:給緩存設(shè)置有效期(一個(gè)禮拜或一天,必須刷新一次)
解決2:讀緩存的時(shí)候(讀取完了緩存,調(diào)用一下解析數(shù)據(jù)的方法),不管是否有緩存都請(qǐng)求一次服務(wù)器(不用擔(dān)心新舊緩存的問(wèn)題,這樣既有老的數(shù)據(jù),可以讓用戶先看到一些數(shù)據(jù),用戶體驗(yàn)好一些,然后網(wǎng)絡(luò)加載完之后更新,用戶耐心更好)
?
細(xì)節(jié)2:儲(chǔ)存在sp中會(huì)導(dǎo)致sp可讀性太差
解決1:數(shù)據(jù)庫(kù)
解決2:用文件儲(chǔ)存
以URL為文件名,以JSON為文件內(nèi)容,讀緩存的時(shí)候就直接查找有沒(méi)有緩存文件即可.
但是URL有可能有特殊字符,所以可以用MD5轉(zhuǎn)換一下,就可以作為文件名
?
注意:網(wǎng)絡(luò)緩存一般就是緩存的JSON,面試問(wèn)到也就是緩存JSON
如果URL后面帶參數(shù),也是同樣要帶參數(shù)的(路徑拼接即可)
?
9,設(shè)置新聞中心的側(cè)邊欄數(shù)據(jù)
重點(diǎn)是如何拿到側(cè)邊欄對(duì)象
?
?
在這里MainActivity其實(shí)已經(jīng)獲取到了,就是mActivity;
在解析數(shù)據(jù)的方法里
通過(guò)mActivity強(qiáng)轉(zhuǎn)得到MainActivity
?
在MainActivity中,創(chuàng)建一個(gè)方法,找到側(cè)邊欄對(duì)象
FragmentManager .findFragmentByTag()//通過(guò)前面設(shè)置的標(biāo)簽獲取Fragment對(duì)象
?
然后在新聞中心的Pager類中,拿到側(cè)邊欄對(duì)象
?
在側(cè)邊欄Fragment類中,創(chuàng)建一個(gè)方法設(shè)置數(shù)據(jù),在新聞中心類中,把需要傳遞的數(shù)據(jù)通過(guò)參數(shù)傳遞過(guò)去(JSON串中的新聞中心數(shù)據(jù))
?
這里的側(cè)邊欄其實(shí)就是一個(gè)ListView
把傳遞過(guò)來(lái)的新聞中心數(shù)據(jù)解析出來(lái),傳遞到ListView上
這里使用ViewUtils模塊,使用注解的方法替代fbc和onClick;
①注入View和事件
ViewUtils.inject(this,view);
②創(chuàng)建需要替代的成員變量:
@ViewInject(id)
Private ListView mListView;
?
ViewUtils底層其實(shí)也是fbc,不過(guò)是通過(guò)注解的方式封裝好了.
③創(chuàng)建適配器,設(shè)置數(shù)據(jù)
getItem()可以直接返回一個(gè)與position相關(guān)的對(duì)象(這里可以把它的返回值對(duì)象改了)
getItemId()可以直接把position返回
getView()方法
需要再寫一個(gè)item的布局文件
?
這里的側(cè)邊欄條目狀態(tài)選擇器,通過(guò)enabled是否可用來(lái)設(shè)置狀態(tài)
(因?yàn)?/span>LIstView不像 RadioButton,有選中和不被選中的選擇)
定義一個(gè)成員變量記錄被點(diǎn)擊(也就是被選中的條目)就讓它設(shè)置可用,否則設(shè)置不可用
?
④設(shè)置ListView點(diǎn)擊事件監(jiān)聽(tīng)器
更新被點(diǎn)擊的條目,然后刷新適配器(因?yàn)閭?cè)邊欄條目比較少,所以不影響太多效率)
?
⑤優(yōu)化:點(diǎn)擊了其它條目,應(yīng)該收集側(cè)邊欄
創(chuàng)建一個(gè)方法,toggle()//開(kāi)關(guān)的方法
通過(guò)mainActivity(mainUi)拿到側(cè)邊欄對(duì)象
slidingMenu.toggle()//調(diào)用之后會(huì)根據(jù)當(dāng)前狀態(tài)自動(dòng)判斷是否顯示
?
額外:設(shè)置左上角的按鈕事件
?
10,點(diǎn)擊側(cè)邊欄切換菜單詳情頁(yè)
側(cè)邊欄點(diǎn)擊之后,要修改Fragment里面的內(nèi)容
搭建詳情頁(yè)Ui框架
?
?
①抽取一個(gè)菜單詳情頁(yè)的基類BaseMenuDetailPager
同樣的,在構(gòu)造方法里獲取到mActivity.調(diào)用initView()方法得到返回的View
這個(gè)基類的initView()因?yàn)槊總€(gè)孩子的都不一樣,所以讓子類去強(qiáng)制實(shí)現(xiàn)
??initData()//這個(gè)方法可以強(qiáng)制,也可以不強(qiáng)制
然后把四個(gè)詳情頁(yè)都創(chuàng)建出來(lái)
這里為了觀察方便,先返回四個(gè)簡(jiǎn)單的TextView
?
②在側(cè)邊欄頁(yè)面中設(shè)置當(dāng)前的菜單詳情頁(yè)(抽取方法)setCurrentDetailPager()
重點(diǎn)是拿到菜單詳情頁(yè)對(duì)象
?
?
先拿到MainActivity(mainUi),同拿到側(cè)邊欄一樣,拿到主頁(yè)
通過(guò)主頁(yè)的mPagers集合,拿到新聞中心的對(duì)象
參考名getNewsCenterPager()
然后在NewsCenterPager類中創(chuàng)建方法setCurrentDetailPager(int position)索引傳遞
在側(cè)邊欄中,通過(guò)它的對(duì)象調(diào)用這個(gè)方法
?
11.,實(shí)現(xiàn)側(cè)邊欄詳情頁(yè)的切換
在NewsCenterPager創(chuàng)建的方法setCurrentDetailPager(int position)中,
重新給它所在的Fragment設(shè)置內(nèi)容
創(chuàng)建一個(gè)集合保存下這四個(gè)菜單詳情頁(yè)pager.
在上面的方法里,拿到對(duì)應(yīng)索引的pager對(duì)象,拿到布局
然后把view添加到幀布局中
添加的同時(shí),也要初始化數(shù)據(jù)
?
額外1:添加之前要把幀布局中之前的View清理掉,removeAllViews();
額外2:新聞中心默認(rèn)應(yīng)該顯示新聞菜單pager的內(nèi)容
解析完數(shù)據(jù),切換新聞詳情頁(yè)
額外3:更新標(biāo)題,最簡(jiǎn)單方法,就是解析數(shù)據(jù)時(shí)候把網(wǎng)絡(luò)數(shù)據(jù)的信息直接傳進(jìn)來(lái)
額外4:下方導(dǎo)航欄切換之后,再切換到新聞中心,側(cè)邊欄數(shù)據(jù)不變
需要在每次切換到新聞中心之后,會(huì)調(diào)用側(cè)邊欄設(shè)置數(shù)據(jù)的方法里,在這個(gè)方法里把側(cè)邊欄的索引歸零(修改記錄選中的變量即可)
?
posted on 2016-07-12 11:13 抓根寶 閱讀(...) 評(píng)論(...) 編輯 收藏轉(zhuǎn)載于:https://www.cnblogs.com/adventurer/p/5662848.html
總結(jié)
以上是生活随笔為你收集整理的智慧北京02_初步ui框架_ 主界面_viewPager事件_xUtils_slidingMenu_网络缓存_数据传递...的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 编写JQuery插件-2
- 下一篇: PlayerDir