国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

安卓開發筆記——Fragment+ViewPager組件(高仿微信界面)

2019-11-14 21:10:51
字體:
來源:轉載
供稿:網友
安卓開發筆記——Fragment+ViewPager組件(高仿微信界面)

什么是ViewPager?

  關于ViewPager的介紹和使用,在之前我寫過一篇相關的文章《安卓開發復習筆記——ViewPager組件(仿微信引導界面)》,不清楚的朋友可以看看,這里就不再重復。

什么是Fragment?

Fragment是Android3.0后新增的概念,Fragment名為碎片,不過卻和Activity十分相似,具有自己的生命周期,它是用來描述一些行為或一部分用戶界面在一個Activity中,我們可以合并多個Fragment在一個單獨的activity中建立多個UI面板,或者重用Fragment在多個activity中。

關于Fragment的生命周期,由于Fragment需要依賴Activity,也就是說當一個Activity的生命周期結束之后,那么Fragment的生命周期也自然結束。如果把一個Activiy比作一座大宅子的話,那么Fragment就可以比作大宅子里的房間,大宅子里的房間其中一間倒塌了,并不會引起整個大宅子的倒塌,但如果大宅子倒塌了,那么大宅里的房間也就都倒塌了。

下面來看下Fragment的生命周期:                    Activity和Fragment生命周期對比(相似):

            

為了更好的理解Fragment,我找了下面的一張圖:

  看左邊這張圖,它是我們傳統的手機界面,假設它現在呈現的是一個新聞列表頁,那么當我們點擊列表項中,我們將會跳轉到新聞詳細頁中,上面是標題,下面是正文,這里是2個Activity。

  再看看右邊的圖,左邊是新聞列表頁,右邊是新聞詳細頁,我們可以動態的點擊左邊的列表項,使得右邊的新聞詳細頁動態變化,這里只有1個Activity里面嵌套了2個Fragment,左邊一個,右邊一個。

好了,做了簡單的介紹后,先來看看今天我們要實現的效果圖:(高仿微信主界面)

這里我畫了張界面分析圖,畫圖永遠的痛,湊合著看哈

這里的xml布局文件,我把每一部分都分開寫了:

top1.xml

 1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 2     xmlns:tools="http://schemas.android.com/tools" 3     android:layout_width="match_parent" 4     android:layout_height="50dp" 5     android:background="@drawable/bg" 6     android:paddingLeft="12dp" 7     android:paddingRight="12dp" > 8  9     <LinearLayout10         android:layout_width="wrap_content"11         android:layout_height="wrap_content"12         android:layout_centerVertical="true"13         android:gravity="center"14         android:orientation="horizontal" >15 16         <ImageView17             android:layout_width="30dp"18             android:layout_height="30dp"19             android:src="@drawable/weixin" />20 21         <TextView22             android:layout_width="wrap_content"23             android:layout_height="wrap_content"24             android:layout_marginLeft="12dp"25             android:text="微信"26             android:textColor="@android:color/white"27             android:textSize="18dp" />28     </LinearLayout>29 30     <LinearLayout31         android:layout_width="wrap_content"32         android:layout_height="wrap_content"33         android:layout_alignParentRight="true"34         android:layout_centerVertical="true"35         android:gravity="center"36         android:orientation="horizontal" >37 38         <ImageView39             android:layout_width="30dp"40             android:layout_height="30dp"41             android:src="@drawable/search" />42 43         <ImageView44             android:layout_width="30dp"45             android:layout_height="30dp"46             android:src="@drawable/add" />47 48         <ImageView49             android:layout_width="30dp"50             android:layout_height="30dp"51             android:src="@drawable/more" />52     </LinearLayout>53 54 </RelativeLayout>

top2.xml

 1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 2     android:layout_width="match_parent" 3     android:layout_height="40dp" 4     android:orientation="vertical" > 5  6     <LinearLayout 7         android:layout_width="match_parent" 8         android:layout_height="37dp"  9         android:gravity="center_vertical"10         android:background="#cccccc"11         >12 13         <LinearLayout14             android:layout_width="wrap_content"15             android:layout_height="wrap_content"16             android:layout_weight="1"17             android:gravity="center" >18 19             <TextView20                 android:id="@+id/tv1"21                 android:layout_width="wrap_content"22                 android:layout_height="wrap_content"23                 android:text="聊天" 24                 android:textColor="#339900"/>25         </LinearLayout>26 27         <LinearLayout28             android:layout_width="wrap_content"29             android:layout_height="wrap_content"30             android:layout_weight="1"31             android:gravity="center" >32 33             <TextView34                  android:id="@+id/tv2"35                 android:layout_width="wrap_content"36                 android:layout_height="wrap_content"37                 android:text="發現" 38                 android:textColor="@android:color/black"/>39         </LinearLayout>40 41         <LinearLayout42             android:layout_width="wrap_content"43             android:layout_height="wrap_content"44             android:layout_weight="1"45             android:gravity="center" >46 47             <TextView48                  android:id="@+id/tv3"49                 android:layout_width="wrap_content"50                 android:layout_height="wrap_content"51                 android:text="通訊錄" 52                 android:textColor="@android:color/black"/>53         </LinearLayout>54     </LinearLayout>55 56     <LinearLayout57         android:layout_width="match_parent"58         android:layout_height="3dp" >59 60         <ImageView61             android:id="@+id/tabline"62             android:layout_width="100dp"63             android:layout_height="match_parent"64             android:background="@drawable/tabline" />65     </LinearLayout>66 67 </LinearLayout>

mywx.xml(用include包含前2個布局文件,并設置垂直排列)

 1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 2     xmlns:tools="http://schemas.android.com/tools" 3     android:layout_width="match_parent" 4     android:layout_height="match_parent" 5     android:orientation="vertical" 6     tools:context="com.example.weixin_test.MyWxTest" > 7  8     <include layout="@layout/top1" /> 9 10     <include layout="@layout/top2" />11 12     13  <android.support.v4.view.ViewPager14      android:id="@+id/viewpager"15      android:layout_width="match_parent"16      android:layout_height="wrap_content"17      android:layout_weight="1"18      >19      20      21  </android.support.v4.view.ViewPager>22 </LinearLayout>

Fragment1.xml(由于Flagment的布局文件只是簡單采用字符標示,布局都一樣,這里只給出第一個Fragment布局文件)

 1 <?xml version="1.0" encoding="utf-8"?> 2 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 3     android:layout_width="match_parent" 4     android:layout_height="match_parent" 5     > 6      7     <TextView  8         android:layout_width="wrap_content" 9         android:layout_height="wrap_content"10         android:text="我是第一個界面"11         android:textSize="30dp"12         android:layout_centerInParent="true"13         14         />15     16 17 </RelativeLayout>

接下來是java代碼了,注釋很全(其實用法還是之前的ViewPager,只不過之前的ViewPager的數據源里存放的是view對象,而這里是Fragment)

  1 package com.example.weixin_test;  2   3 import java.util.ArrayList;  4 import java.util.List;  5   6 import android.graphics.Color;  7 import android.os.Bundle;  8 import android.support.v4.app.Fragment;  9 import android.support.v4.app.FragmentActivity; 10 import android.support.v4.app.FragmentPagerAdapter; 11 import android.support.v4.view.ViewPager; 12 import android.support.v4.view.ViewPager.OnPageChangeListener; 13 import android.util.DisplayMetrics; 14 import android.util.Log; 15 import android.view.Display; 16 import android.view.ViewGroup.LayoutParams; 17 import android.view.Window; 18 import android.widget.ImageView; 19 import android.widget.LinearLayout; 20 import android.widget.TextView; 21  22 public class MyWxTest extends FragmentActivity { 23  24     PRivate ViewPager viewPager;// 聲明一個viewpager對象 25     private TextView tv1; 26     private TextView tv2; 27     private TextView tv3; 28     private ImageView tabline; 29     private List<Fragment> list;// 聲明一個list集合存放Fragment(數據源) 30  31     private int tabLineLength;// 1/3屏幕寬 32     private int currentPage = 0;// 初始化當前頁為0(第一頁) 33  34     @Override 35     protected void onCreate(Bundle savedInstanceState) { 36         super.onCreate(savedInstanceState); 37         requestWindowFeature(Window.FEATURE_NO_TITLE); 38         setContentView(R.layout.mywx); 39         // 初始化滑動條1/3 40         initTabLine(); 41  42         // 初始化界面 43         initView(); 44     } 45  46     private void initTabLine() { 47         // 獲取顯示屏信息 48         Display display = getWindow().getWindowManager().getDefaultDisplay(); 49         // 得到顯示屏寬度 50         DisplayMetrics metrics = new DisplayMetrics(); 51         display.getMetrics(metrics); 52         // 1/3屏幕寬度 53         tabLineLength = metrics.widthPixels / 3; 54         // 獲取控件實例 55         tabline = (ImageView) findViewById(R.id.tabline); 56         // 控件參數 57         LayoutParams lp = tabline.getLayoutParams(); 58         lp.width = tabLineLength; 59         tabline.setLayoutParams(lp); 60     } 61  62     private void initView() { 63         // 實例化對象 64         viewPager = (ViewPager) findViewById(R.id.viewpager); 65         tv1 = (TextView) findViewById(R.id.tv1); 66         tv2 = (TextView) findViewById(R.id.tv2); 67         tv3 = (TextView) findViewById(R.id.tv3); 68         list = new ArrayList<Fragment>(); 69  70         // 設置數據源 71         Fragment1 fragment1 = new Fragment1(); 72         Fragment2 fragment2 = new Fragment2(); 73         Fragment3 fragment3 = new Fragment3(); 74  75         list.add(fragment1); 76         list.add(fragment2); 77         list.add(fragment3); 78  79         // 設置適配器 80         FragmentPagerAdapter adapter = new FragmentPagerAdapter( 81                 getSupportFragmentManager()) { 82  83             @Override 84             public int getCount() { 85                 return list.size(); 86             } 87  88             @Override 89             public Fragment getItem(int arg0) { 90                 return list.get(arg0); 91             } 92         }; 93  94         // 綁定適配器 95         viewPager.setAdapter(adapter); 96  97         // 設置滑動監聽 98         viewPager.setOnPageChangeListener(new OnPageChangeListener() { 99 100             @Override101             public void onPageSelected(int position) {102                 // 當頁面被選擇時,先講3個textview的字體顏色初始化成黑103                 tv1.setTextColor(Color.BLACK);104                 tv2.setTextColor(Color.BLACK);105                 tv3.setTextColor(Color.BLACK);106 107                 // 再改變當前選擇頁(position)對應的textview顏色108                 switch (position) {109                 case 0:110                     tv1.setTextColor(Color.rgb(51, 153, 0));111                     break;112                 case 1:113                     tv2.setTextColor(Color.rgb(51, 153, 0));114                     break;115                 case 2:116                     tv3.setTextColor(Color.rgb(51, 153, 0));117                     break;118                 }119 120                 currentPage = position;121 122             }123 124             @Override125             public void onPageScrolled(int arg0, float arg1, int arg2) {126                 Log.i("tuzi", arg0 + "," + arg1 + "," + arg2);127 128                 // 取得該控件的實例129                 LinearLayout.LayoutParams ll = (android.widget.LinearLayout.LayoutParams) tabline130                         .getLayoutParams();131 132                 if (currentPage == 0 && arg0 == 0) { // 0->1移動(第一頁到第二頁)133                     ll.leftMargin = (int) (currentPage * tabLineLength + arg1134                             * tabLineLength);135                 } else if (currentPage == 1 && arg0 == 1) { // 1->2移動(第二頁到第三頁)136                     ll.leftMargin = (int) (currentPage * tabLineLength + arg1137                             * tabLineLength);138                 } else if (currentPage == 1 && arg0 == 0) { // 1->0移動(第二頁到第一頁)139                     ll.leftMargin = (int) (currentPage * tabLineLength - ((1 - arg1) * tabLineLength));140                 } else if (currentPage == 2 && arg0 == 1) { // 2->1移動(第三頁到第二頁)141                     ll.leftMargin = (int) (currentPage * tabLineLength - (1 - arg1)142                             * tabLineLength);143                 }144 145                 tabline.setLayoutParams(ll);146 147             }148 149             @Override150             public void onPageScrollStateChanged(int arg0) {151                 // TODO Auto-generated method stub152 153             }154         });155 156     }157 158 }

對這個類做下說明:

1、這里的滑動屏幕下劃線動態跟隨的效果,其實實現方法有2種,原理是一樣的

(1)可以使用ViewPager的兩個子類ViewFlipper和ViewSwitche,這種方法比較簡單,直接用就行。

(2)用原生代碼實現,也就是動態的去控制下劃線的左外邊距。

這里我采用的是第2種方法,我覺得授人予魚還不如授人予漁,其實也并不復雜,細節去理下細節就懂了。

這里需要注意一個地方,我們在給ViewPager設置監聽器時,這邊會復寫一個onPageScrolled方法,里面有3個參數,我用Log打印出它們在頁面滑動時的數據變化

這是頁面一向頁面二滑動時候的數據記錄:

我們可以發現第一個參數值直接從0->1,第二個參數值從0.0依次增加到0.9xx無限靠近1,然后頁面到達第二頁它又恢復成了0,第三個參數從1開始累積到300+(這個我們不去關注)

這是頁面二向頁面三滑動時候的數據記錄:

我們可以發現第一個參數值直接從1->2,第二個參數值從0.0依次增加到0.9xx無限靠近1,然后頁面到達第二頁它又恢復成了0,第三個參數從1開始累積到300+(這個我們不去關注)

因此我們可以發現一個規律:

當ViewPager頁面值為0(第一頁)且當參數一為0時,頁面的狀態時從  第一頁到第二頁

當ViewPager頁面值為1(第二頁)且當參數一為1時,頁面的狀態時從  第一頁到第二頁

以此類推,大家可以自己打印出來看看,對這些數據比較有感覺,由于文章篇幅問題,這里就不再貼圖了。

我們可以利用第二個參數從0.0推薦遞增到1,這個數據來控制左外邊距(在第一頁時左外邊距為0,第二頁時左外邊距為1/3屏幕寬,第三頁時左外邊距為2/3屏幕寬)

由此推導出的公式為:

向左滑時:當前頁數*屏幕1/3寬+onPageScrolled方法第二個參數*屏幕1/3寬

向右滑時:當前頁數*屏幕1/3寬-(1-onPageScrolled方法第二個參數)*屏幕1/3寬

2、由于這里使用到了Fragment,這里就不再和以往一樣繼承Activity,這里需要繼承Activity的子類FragmentActivity。

由于3個Fragment的代碼幾乎一致,所以這里只給出Fragment1.java

 1 package com.example.weixin_test; 2  3 import android.os.Bundle; 4 import android.support.annotation.Nullable; 5 import android.support.v4.app.Fragment; 6 import android.view.LayoutInflater; 7 import android.view.View; 8 import android.view.ViewGroup; 9 10 public class Fragment1 extends Fragment {11     @Override12     public View onCreateView(LayoutInflater inflater,13             @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {14         return inflater.inflate(R.layout.fragment1, container, false);15     }16 17 }

來講一下關于這個類的說明:

1、Fragment一般是作為Activity界面的一部分,它把Layout對象嵌入到了Activity之中,若要對一個Fragment提供Layout對象必須去調用一個onCreateView()方法,它的返回值是一個View對象,這個方法為我們提供了一個LayoutInflater便于我們把XML布局文件轉換成View對象。

2、onCreateView()方法中:

container參數是用來存放Fragment的layout。

saveInstanceState參數是一個Bundle,跟Activity的onCreate()中Bundle差不多,用于狀態恢復。

3、inflate()方法中有三個參數:

1:layout的資源id。

2:存放fragment的layout的ViewGroup。

3:這個布爾值是代表是否在創建Fragment的layout期間,把layout附加到container上,由于系統已經把layout對象存放在了ViewGroup中,所以這里為false。

作者:Balla_兔子出處:http://m.survivalescaperooms.com/lichenwei/本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文鏈接。正在看本人博客的這位童鞋,我看你氣度不凡,談吐間隱隱有王者之氣,日后必有一番作為!旁邊有“推薦”二字,你就順手把它點了吧,相得準,我分文不收;相不準,你也好回來找我!


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 佛山市| 涿州市| 通榆县| 红原县| 杨浦区| 重庆市| 海原县| 云林县| 霍林郭勒市| 沂水县| 常州市| 尉犁县| 日喀则市| 东乡县| 万年县| 佛学| 孟州市| 启东市| 大田县| 万安县| 奈曼旗| 长子县| 高陵县| 乡宁县| 剑阁县| 北川| 塘沽区| 西吉县| 大渡口区| 平顶山市| 汝南县| 扶绥县| 镶黄旗| 牟定县| 伊宁县| 栖霞市| 海盐县| 江阴市| 铁岭县| 建始县| 太白县|