智慧北京02_初步ui框架_ 主界面_viewPager事件_xUtils_slidingMenu_网络缓存_数据传递...
1.使用Fragment搭建ui框架
參考分析圖
?
?
1.1,Fragment生命周期
Is added(被添加之后)
>>onAttach()>>onCreate()>>onCreateView()//創建布局>>onActivityCreated();//當activity創建好后(onCreate()執行完了之后)>>onStart()>>onResume()>>onPause()>>onStop()>>onDestory()
?
1.2 創建一個Fragment的基類:參考名baseFragment(用v4保持版本兼容)
onCreate()//Fragment創建
可以拿到這個Fragment所在的Activity對象
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:下方導航欄切換之后,再切換到新聞中心,側邊欄數據不變
需要在每次切換到新聞中心之后,會調用側邊欄設置數據的方法里,在這個方法里把側邊欄的索引歸零(修改記錄選中的變量即可)
?
posted on 2016-07-12 11:13 抓根寶 閱讀(...) 評論(...) 編輯 收藏轉載于:https://www.cnblogs.com/adventurer/p/5662848.html
總結
以上是生活随笔為你收集整理的智慧北京02_初步ui框架_ 主界面_viewPager事件_xUtils_slidingMenu_网络缓存_数据传递...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 编写JQuery插件-2
- 下一篇: PlayerDir