高仿QQ源码 界面(3)
生活随笔
收集整理的這篇文章主要介紹了
高仿QQ源码 界面(3)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
上次的圖片莫名其妙的沒了, 今天補上
分別為主布局, 和主布局的結構, 大致分為三個結構,RelativeLayout, ViewPager, RadioGroup, (這個布局只是能大概的模仿, 無法滿足絕對的一樣,因為之前沒有考慮那么多, 后面會進行修改) 這是RadioButton的Style樣式, 這樣可以減少很多代碼量, 方便后期更改, 最好養成這樣的習慣 這是其中之一的ButtonSelector樣式, , 通過checked屬性來選擇使用哪個drawable資源作為背景,其他幾個類似布局分析:
通過點擊不同的RadioButton可以切換中間顯示的內容布局, qq的不能通過滑動當前的頁面來改變下面RadioButton的狀態, 自己加上了這一點,中間的布局使用ViewPager+Fragment來實現, 通過點擊RadioButton或者滑動pager來改變當前顯示Fragment布局, 另外最上面的title的顯示也是可以跟著聯動的, 最初以為是簡單的聯動,顯示個TextView,沒發現title有一部分也是通過fragment加入, 這點先不去管, 先實現RadioButton, ViewPager,title這三個的聯動就好,第一步: 實現布局中的ViewPager , 不要選錯了要是v4包下的ViewPager, 下面是局部代碼
第二步: ViewPager數據源,由于是使用的ViewPager+Fragment實現的,所以List集合的泛型要用Fragment如下代碼
第三步: 1. 實現ViewPager顯示的Fragment類,這里寫個四個pager ,所以使用了4個類繼承自Fragment,重寫其三個 方法,onCreate,當創建此類的時候執行, 最先執行的方法, 由系統調用,onCreateView,在onCreate之后執行,這個方法返回一個View對象, 這個對象就是要顯示在pager中內容, 可以是任何的View對象, TextView, Button, ListView等等, View的子類對象,通過View的靜態方法View.inflate(Context context, int resource,ViewGroup root), 三個參數分別是要調用該類的對象的Context, 可以直接通過getActivity()方法獲取call此Activity的上下文, resource 是要顯示的布局, 可以是簡單的TextView, 也可以是復雜的ListView等, 這里為了實現分組等頁面使用ListView布局, root是掛載到哪一個父布局之下, 這里填充的就是resource本身, 所以可以傳入null, onActivityCreated() 創建Activity完成的時候調用(從名字推測是這樣子的, 不得不說命名上Google做的還是很好的), 在onCreateView之后執行 對view的初始化就可以放入此方法里執行
附上局部源碼?
activity_plus布局如下 這里因為要實現好友界面的二級折疊樣式, 可以展開的ListView, 使用ExpandableListView控件代碼如下contact布局如下
因為ExpandableListView中也包含一個子ListView, 所以要使用BaseExpandableAdapter對象,創建MyBaseExpandableAdapter類,繼承自BaseExpandableAdapter類, 實現其未實現的方法分別為? 1.getGroupCount(),返回父listView顯示的數目,? 2.getChildrenCount(), 返回一個子ListView顯示的數目 3.getGroup 返回值是Object類型, 需要返回父ListView中的data數據源 4.getChild() 返回值是Object類型, 需要返回子ListView中的data數據源 5.getGroupId() 返回一個long類型的值, 用于標示當前父ListView的item的ID 6.getChildId() 返回是一個long類型的值, 用于標示當前子ListView的timeID 7.hasStableIds() 返回一個boolean值, 返回true表示顯示的布局會根據ID的改變而更新data顯示, 這里返回true 8.getGroupView(), 返回父ListView顯示的對象, 這里利用View.inflate方法, 引入布局并找到布里面的每個控件, 進行初始化, 賦值等操作 8.getChildView()?返回子ListView顯示的對象, 這里利用View.inflate方法, 引入布局并找到布里面的每個控件, 進行初始化, 賦值等操作 9.isChildSelectable(), 設置子控件是否可以進行點擊, 這里當然返回true , 若是返回false則無法點擊展開后的子控件 其實這些方法很多看名字就大概知道方法的用處, ?這里因為要倆個data數據源, 一個是控件的, 一個是展開后的子控件的, 所以adapter的構造器中傳入三個參數, 下面是局部代碼
下面是初始化parentView 的方法, 英語很差 不能做到像Google那樣見名知意,
子布局View初始化方法
設置Children的data數據源
?第三步: 2.設置ViewPager的Adapter , 從前面的MyBaseExpandableAdapter中可以看出Adapter實際上是包含了ExpandableListView要顯示的布局和布局上具體顯示的data數據來源, 所以, 給ViewPager設置Adapter就是設置了布局和要顯示的data數據源, 至于data數據在布局中是以何種方式顯示的這就要看Adapter中對data數據的獲取和設置了, 可以看上面的setChildrenData和initParentView方法, 下面是局部代碼\
設置data數據源的初始化ExpandableListView
第四步: 設置ViewPager的adapter, 看了上面的ExpandableListView設置adapter這個應該就簡單多了
首先注意的是, 用ViewPager+Fragment的時候使用的adapter不一樣, Googl為開發者專門提供了一個FragmentPagerAdapter的抽象類來給開發者使用,下面是我的adapter的代碼初始化ViewPager
第五步:實現邏輯聯動, 因為這里的點擊RadioButton和滑動ViewPager都能改變title的內容, 所以可以把這些都封裝成一個方法, 并且把這三個的對象都放到三個數組中, 注意要讓三個數組中的下標所對應的對象保證是一組的, 這樣就可以通過訪問這三個數組的第幾個元素來實現三者之間的聯動,?
三個數組對象通過改變一個int類型的指示器的值來指向這三個數中的對象,
l利用指示器pointer設置當前顯示的pager
RadioButton的監聽事件
ViewPager的監聽事件
比較懶, 直接把初始化RadioButton寫成了一個方法, 類似的在控件比較多的情況用處還好, 這里體現不大
設置打印自定義的log信息
到此布局就結束了, 中間可能與有理解的錯的, 歡迎討論交流, 另外好多代碼并沒有使用ViewHolder進行優化 總結: 這樣做確實可以實現那樣的效果, 淡水有一點非常不好, 那就是, 每個Pager顯示的標題應該是有沒有Fragment類來決定的,. 不應該放到主的Activity中, 可以看到qq每個頁面對應title顯示的內容, 和右上角的描述也是不一樣的, 所以這些title應該交給每個fragment來實現,可以把這些fragment必須要有的功能定義一個接口, 每個fragment頁面實現這些接口, 自然也會去實現接口中所定義的方法, 這樣比較符合設計模式, 當我后期再需要添加一個Fragment頁面的時候就不需要修改很多的類,只需要實現自己定義的Fragment接口, 并且實現這些抽象方法就可以了, 相反若是沒有對應接口來規范Fragment的話, 沒添加一個pager就要修改與之關聯的類, 引起很多麻煩, 也容易忘記修改造成不必要的bug, 本人學的并不好, 有什么不對的地方歡迎指出改正,一起交流學習進步
總結
以上是生活随笔為你收集整理的高仿QQ源码 界面(3)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: HNB资讯里,中烟加热不燃烧有哪些牌子?
- 下一篇: Android12华为,谷歌“神助攻”!