Android中Fragment和ViewPager那點事兒(仿微信APP)

来源:http://www.cnblogs.com/panhouye/archive/2016/12/25/6218954.html
-Advertisement-
Play Games

在之前的博文《Android中使用ViewPager實現屏幕頁面切換和引導頁效果實現》和《Android中Fragment的兩種創建方式》以及《Android中Fragment與Activity之間的交互(兩種實現方式)》中我們介紹了ViewPager以及Fragment各自的使用場景以及不同的實現 ...


在之前的博文《Android中使用ViewPager實現屏幕頁面切換和引導頁效果實現》和《Android中Fragment的兩種創建方式》以及《Android中Fragment與Activity之間的交互(兩種實現方式)》中我們介紹了ViewPager以及Fragment各自的使用場景以及不同的實現方式。

那如果將他們兩結合起來,會不會擦出點火花呢,答案是肯定的。之前在介紹ViewPager時,我們實現了多個ImageView的切換,並配合更新導航原點的狀態。那我們現在就將之前的imageview替換為fragment,將導航原點替換為更加生動的佈局,比如我們經常使用的微信(取消了ActionBar):

(1)我們可以通過點擊下麵的導航按鈕選擇對應的顯示界面(fragment),如下圖:

(2)我們也可以通過滑動界面(fragment)來實現界面切換,同時下麵的導航按鈕狀態也會發生變化,如下圖:

那麼重點來了,這樣的效果要怎麼實現呢,大至分為以下的步驟

(1)佈局文件中直接部署ViewPager以及下方的導航佈局

(2)根據導航的個數來建立對應的fragment佈局並建立配套的Fragment類(為方便後期擴展,建議建立與導航個數相同的fragments)

(3)drable下使用selector實現導航組件的形態變化

(4)通過FragmentPagerAdapterV4包下)實現ViewPager與Fragment的關聯

(5)設置下方導航的點擊事件以及ViewPager的OnPageChangeListener方法實現對應的狀態改變

第一步:layout中的主佈局文件activity_main.xml文件

取消了actionBar,採用LinearLayout嵌套來實現主佈局:

  1 <?xml version="1.0" encoding="utf-8"?>
  2 <LinearLayout
  3     xmlns:android="http://schemas.android.com/apk/res/android"
  4     xmlns:tools="http://schemas.android.com/tools"
  5     android:id="@+id/activity_main"
  6     android:layout_width="match_parent"
  7     android:layout_height="match_parent"
  8    android:orientation="vertical"
  9     tools:context="com.example.administrator.viewpagerfragment.MainActivity">
 10 
 11     <LinearLayout
 12         android:background="@color/colorblack"
 13         android:padding="10dp"
 14         android:layout_width="match_parent"
 15         android:layout_height="wrap_content">
 16 
 17         <TextView
 18             android:layout_width="0dp"
 19             android:layout_weight="1"
 20             android:gravity="center_vertical"
 21             android:layout_height="match_parent"
 22             android:layout_marginLeft="5dp"
 23             android:text="潘侯爺微信"
 24             android:textSize="20sp"
 25             android:textColor="@color/colorWhite"/>
 26 
 27         <ImageView
 28             android:src="@mipmap/jy_drltsz_btn_addperson"
 29             android:adjustViewBounds="true"
 30             android:maxHeight="23dp"
 31             android:layout_width="wrap_content"
 32             android:layout_height="wrap_content" />
 33     </LinearLayout>
 34 
 35 
 36     <android.support.v4.view.ViewPager
 37         android:id="@+id/viewPager"
 38         android:layout_width="match_parent"
 39         android:layout_height="0dp"
 40         android:layout_weight="1"/>
 41 
 42     <View
 43         android:layout_width="match_parent"
 44         android:layout_height="1dp"
 45         android:background="@color/colornormal"/>
 46 
 47     <LinearLayout
 48         android:orientation="horizontal"
 49         android:padding="5dp"
 50         android:layout_width="match_parent"
 51         android:layout_height="wrap_content">
 52 
 53         <LinearLayout
 54             android:id="@+id/weixin"
 55             android:clickable="true"
 56             android:orientation="vertical"
 57             android:layout_width="0dp"
 58             android:gravity="center"
 59             android:layout_weight="1"
 60             android:layout_height="wrap_content">
 61 
 62             <ImageView
 63                 android:id="@+id/weixin_img"
 64                 android:background="@drawable/weixin_picture_selector"
 65                 android:layout_width="30dp"
 66                 android:layout_height="25dp" />
 67             <TextView
 68                 android:id="@+id/weixin_txt"
 69                 android:layout_width="wrap_content"
 70                 android:gravity="center"
 71                 android:layout_height="wrap_content"
 72                 android:text="微信"
 73                 android:textSize="12sp"
 74                 android:textColor="@drawable/weixin_text_selector"/>
 75         </LinearLayout>
 76 
 77         <LinearLayout
 78             android:id="@+id/contact"
 79             android:clickable="true"
 80             android:orientation="vertical"
 81             android:layout_width="0dp"
 82             android:gravity="center"
 83             android:layout_weight="1"
 84             android:layout_height="wrap_content">
 85 
 86             <ImageView
 87                 android:id="@+id/contact_img"
 88                 android:background="@drawable/txl_picture_selector"
 89                 android:layout_width="30dp"
 90                 android:layout_height="25dp" />
 91 
 92             <TextView
 93                 android:id="@+id/contact_txt"
 94                 android:layout_width="wrap_content"
 95                 android:gravity="center"
 96                 android:layout_height="wrap_content"
 97                 android:text="通訊錄"
 98                 android:textSize="12sp"
 99                 android:textColor="@drawable/weixin_text_selector"/>
100         </LinearLayout>
101 
102         <LinearLayout
103             android:id="@+id/find"
104             android:clickable="true"
105             android:orientation="vertical"
106             android:layout_width="0dp"
107             android:gravity="center"
108             android:layout_weight="1"
109             android:layout_height="wrap_content">
110 
111             <ImageView
112                 android:id="@+id/find_img"
113                 android:background="@drawable/find_picture_selector"
114                 android:layout_width="30dp"
115                 android:layout_height="25dp" />
116             <TextView
117                 android:id="@+id/find_txt"
118                 android:layout_width="wrap_content"
119                 android:gravity="center"
120                 android:layout_height="wrap_content"
121                 android:text="發現"
122                 android:textSize="12sp"
123                 android:textColor="@drawable/weixin_text_selector"/>
124         </LinearLayout>
125 
126         <LinearLayout
127             android:id="@+id/self"
128             android:clickable="true"
129             android:orientation="vertical"
130             android:layout_width="0dp"
131             android:gravity="center"
132             android:layout_weight="1"
133             android:layout_height="wrap_content">
134 
135             <ImageView
136                 android:id="@+id/self_img"
137                 android:background="@drawable/me_picture_selector"
138                 android:layout_width="30dp"
139                 android:layout_height="25dp" />
140             <TextView
141                 android:id="@+id/self_txt"
142                 android:layout_width="wrap_content"
143                 android:gravity="center"
144                 android:layout_height="wrap_content"
145                 android:text="我"
146                 android:textSize="12sp"
147                 android:textColor="@drawable/weixin_text_selector"/>
148         </LinearLayout>
149     </LinearLayout>
150 </LinearLayout>

第二步:layout中fragment的佈局文件(可自由擴展)

這裡四個導航對應四個不同的fragment(實現上面的效果,也可以只建立一個fragment,但這樣不利於後期擴展),這裡我們只演示其中一個weixin_fragment.xml(其他三個為 contactListFragment; findFragment;selfFragment

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     xmlns:app="http://schemas.android.com/apk/res-auto"
 4     android:orientation="vertical"
 5     android:layout_width="match_parent"
 6     android:layout_height="match_parent">
 7     <TextView
 8         android:id="@+id/tv"
 9         android:layout_width="match_parent"
10         android:layout_height="match_parent"
11         android:text="沒有微信消息"
12         android:gravity="center"
13         android:textSize="50sp"/>
14 </LinearLayout>

第三步:drable中設定下方導航組件不同的形態

導航組件中文字形態變化只是顏色不同,圖片的話需要設置點擊前後不同的圖片(這裡演示一種)

(1)文字的變化wenxin_text_selector.xml

這裡使用selected而不用checked的原因:個人使用的導航佈局為linerlayout,並且為linerlayout設置chiclable而不是其中的Text/imageView,所以為了判斷變化,這裡使用了selected,方便代碼中設置調用。

1 <?xml version="1.0" encoding="utf-8"?>
2 <selector xmlns:android="http://schemas.android.com/apk/res/android">
3     <item android:color="@color/colorpressed" android:state_selected="true"/>
4     <item android:color="@color/colornormal" android:state_selected="false" />
5 </selector>

(2)圖片的變化weixin_picture_selector.xml

1 <?xml version="1.0" encoding="utf-8"?>
2 <selector xmlns:android="http://schemas.android.com/apk/res/android">
3     <item android:drawable="@mipmap/weixin_pressed"  android:state_selected="true"/>
4     <item android:drawable="@mipmap/weixin_normal" android:state_selected="false" />
5 </selector>

第四步:Java中對應fragment佈局的Fragment繼承類

這裡建議繼承android.support.v4.app.Fragment包下的.Fragment,因為後面要用的FragmentPagerAdapter屬於V4包,應該統一。

4個fragment對應4個java類,這裡演示一個,其他三個都一樣。

 

 1 import android.os.Bundle;
 2 import android.support.annotation.Nullable;
 3 import android.support.v4.app.Fragment;
 4 import android.view.LayoutInflater;
 5 import android.view.View;
 6 import android.view.ViewGroup;
 7 import android.widget.TextView;
 8 /**
 9  * Created by panchengjia on 2016/12/24.
10  */
11 public class WeixinFragment extends Fragment {
12     @Nullable
13     @Override
14     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
15         View view = inflater.inflate(R.layout.weixin_fragment,container,false);
16         return view;
17     }
18 }

 

第五步:java中功能實現MainActivity.java文件

代碼中詳細標註了各個實現步驟的註釋,這裡不再贅述(為了提高程式運行效率,很多重覆方法未封裝,代碼看起來有點臃腫了)

  1 import android.support.v4.app.Fragment;
  2 import android.support.v4.app.FragmentManager;
  3 import android.support.v4.app.FragmentPagerAdapter;
  4 import android.support.v4.view.ViewPager;
  5 import android.support.v7.app.AppCompatActivity;
  6 import android.os.Bundle;
  7 import android.view.View;
  8 import android.widget.ImageView;
  9 import android.widget.LinearLayout;
 10 import android.widget.TextView;
 11 import java.util.ArrayList;
 12 
 13 public class MainActivity extends AppCompatActivity implements View.OnClickListener {
 14     //聲明存儲fragment的集合
 15     private ArrayList<Fragment> fragments;
 16     //聲明四個導航對應fragment
 17     WeixinFragment weixinFragment;
 18     ContactListFragment contactListFragment;
 19     FindFragment findFragment;
 20     SelfFragment selfFragment;
 21     //聲明ViewPager
 22     private ViewPager viewPager;
 23     FragmentManager fragmentManager;//聲明fragment管理
 24     //聲明導航欄中對應的佈局
 25     private LinearLayout weixin, contact, find, self;
 26     //聲明導航欄中包含的imageview和textview
 27     private ImageView weixin_img, contact_img, find_img, self_img;
 28     private TextView weixin_txt, contact_txt, find_txt, self_txt;
 29 
 30     @Override
 31     protected void onCreate(Bundle savedInstanceState) {
 32         super.onCreate(savedInstanceState);
 33         setContentView(R.layout.activity_main);
 34         //初始化載入首頁佈局
 35         initView();
 36         //調用自定義initListener方法,為各個組件添加監聽事件
 37         initListener();
 38         //設置預設選擇的pager和導航欄的狀態
 39         viewPager.setCurrentItem(0);
 40         weixin_img.setSelected(true);
 41         weixin_txt.setSelected(true);
 42     }
 43 
 44     private void initListener() {
 45         //為四大導航組件添加監聽
 46         weixin.setOnClickListener(this);
 47         contact.setOnClickListener(this);
 48         find.setOnClickListener(this);
 49         self.setOnClickListener(this);
 50         //為viewpager添加頁面變化的監聽以及事件處理
 51         viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
 52             @Override
 53             public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
 54 
 55             }
 56 
 57             @Override
 58             public void onPageSelected(int position) {
 59                 //根據位置直接決定顯示哪個fragment
 60                 viewPager.setCurrentItem(position);
 61                 switch (position) {
 62                     case 0:
 63                         weixin_img.setSelected(true);
 64                         weixin_txt.setSelected(true);
 65 
 66                         contact_img.setSelected(false);
 67                         contact_txt.setSelected(false);
 68                         find_img.setSelected(false);
 69                         find_txt.setSelected(false);
 70                         self_img.setSelected(false);
 71                         self_txt.setSelected(false);
 72 
 73                         break;
 74                     case 1:
 75                         weixin_img.setSelected(false);
 76                         weixin_txt.setSelected(false);
 77 
 78                         contact_img.setSelected(true);
 79                         contact_txt.setSelected(true);
 80                         find_img.setSelected(false);
 81                         find_txt.setSelected(false);
 82                         self_img.setSelected(false);
 83                         self_txt.setSelected(false);
 84 
 85                         break;
 86                     case 2:
 87                         weixin_img.setSelected(false);
 88                         weixin_txt.setSelected(false);
 89 
 90                         contact_img.setSelected(false);
 91                         contact_txt.setSelected(false);
 92                         find_img.setSelected(true);
 93                         find_txt.setSelected(true);
 94                         self_img.setSelected(false);
 95                         self_txt.setSelected(false);
 96 
 97                         break;
 98                     case 3:
 99                         weixin_img.setSelected(false);
100                         weixin_txt.setSelected(false);
101 
102                         contact_img.setSelected(false);
103                         contact_txt.setSelected(false);
104                         find_img.setSelected(false);
105                         find_txt.setSelected(false);
106                         self_img.setSelected(true);
107                         self_txt.setSelected(true);
108                         break;
109                 }
110             }
111 
112             @Override
113             public void onPageScrollStateChanged(int state) {
114 
115             }
116         });
117 
118     }
119 
120     private void initView() {
121         //在主佈局中根據id找到ViewPager
122         viewPager = (ViewPager) findViewById(R.id.viewPager);
123         //實例化所屬四個fragment
124         weixinFragment = new WeixinFragment();
125         contactListFragment = new ContactListFragment();
126         findFragment = new FindFragment();
127         selfFragment = new SelfFragment();
128         fragments = new ArrayList<>();
129         //添加fragments到集合中
130         fragments.add(weixinFragment);
131         fragments.add(contactListFragment);
132         fragments.add(findFragment);
133         fragments.add(selfFragment);
134         fragmentManager = getSupportFragmentManager();
135         //為ViewPager設置適配器用於部署fragments
136         viewPager.setAdapter(new MyFragmentPagerAdapter(fragmentManager));
137 
138 
139         weixin = (LinearLayout) findViewById(R.id.weixin);
140         contact = (LinearLayout) findViewById(R.id.contact);
141         find = (LinearLayout) findViewById(R.id.find);
142         self = (LinearLayout) findViewById(R.id.self);
143 
144 
145         weixin_img = (ImageView) findViewById(R.id.weixin_img);
146         contact_img = (ImageView) findViewById(R.id.contact_img);
147         find_img = (ImageView) findViewById(R.id.find_img);
148         self_img = (ImageView) findViewById(R.id.self_img);
149 
150         weixin_txt = (TextView) findViewById(R.id.weixin_txt);
151         contact_txt = (TextView) findViewById(R.id.contact_txt);
152         find_txt = (TextView) findViewById(R.id.find_txt);
153         self_txt = (TextView) findViewById(R.id.self_txt);
154     }
155 
156     /**
157      * 設置導航欄的點擊事件並同步更新對應的ViewPager
158      * 點擊事件其實就是更改導航佈局中對應的Text/ImageView
159      * 的選中狀態,配合drable中的selector更改圖片以及文字變化
160      *
161      * @param v
162      */
163     @Override
164     public void onClick(View v) {
165         switch (v.getId()) {
166             case R.id.weixin:
167                 viewPager.setCurrentItem(0);
168                 weixin_img.setSelected(true);
169                 weixin_txt.setSelected(true);
170 
171                 contact_img.setSelected(false);
172                 contact_txt.setSelected(false);
173                 find_img.setSelected(false);
174                 find_txt.setSelected(false);
175                 self_img.setSelected(false);
176                 self_txt.setSelected(false);
177 
178                 break;
179             case R.id.contact:
180                 viewPager.setCurrentItem(1);
181                 weixin_img.setSelected(false);
182                 weixin_txt.setSelected(false);
183 
184                 contact_img.setSelected(true);
185                 contact_txt.setSelected(true);
186                 find_img.setSelected(false);
187                 find_txt.setSelected(false);
188                 self_img.setSelected(false);
189                 self_txt.setSelected(false);
190 
191                 break;
192             case R.id.find:
193                 viewPager.setCurrentItem(2);
194                 weixin_img.setSelected(false);
195                 weixin_txt.setSelected(false);
196 
197                 contact_img.setSelected(false);
198                 contact_txt.setSelected(false);
199                 find_img.setSelected(true);
200                 find_txt.setSelected(true);
201                 self_img.setSelected(false);
202                 self_txt.setSelected(false);
203 
204                 break;
205             case R.id.self:
206                 viewPager.setCurrentItem(3);
207                 weixin_img.setSelected(false);
208                 weixin_txt.setSelected(false);
209 
210                 contact_img.setSelected(false);
211                 contact_txt.setSelected(false);
212                 find_img.setSelected(false);
213                 find_txt.setSelected(false);
214                 self_img.setSelected(true);
215                 self_txt.setSelected(true);
216 
217                 break;
218         }
219     }
220 
221     //創建FragmentPagerAdapter
222     class MyFragmentPagerAdapter extends FragmentPagerAdapter {
223 
224         public MyFragmentPagerAdapter(FragmentManager fm) {
225             super(fm);
226         }
227 
228         @Override
229         public android.support.v4.app.Fragment getItem(int position) {
230             return fragments.get(position);
231         }
232 
233         @Override
234         public int getCount() {
235             return fragments.size();
236         }
237     }
238 }

後期就微信的其他功能的實現做簡單介紹,不早了,休息

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一、變數提升 在ES6之前,JavaScript沒有塊級作用域(一對花括弧{}即為一個塊級作用域),只有全局作用域和函數作用域。變數提升即將變數聲明提升到它所在作用域的最開始的部分。上個簡歷的例子如: 之所以會是以上的列印結果,是由於js的變數提升,實際上上面的代碼是按照以下來執行的: 二、函數提升 ...
  • JavaScript [1]事件 ①用戶操作網頁或者瀏覽器所發生的交互行為稱為事件。比如:點擊按鈕,最小化視窗,修改文本框內容等。 ②JS為我們定義許多瀏覽器中的事件。比如:單擊(onclick)、雙擊(ondblclick)、移動(onmousemove) 等。 ③我們可以通過為事件設置一個響應函 ...
  • 用戶反饋是小程式開發必要的一個功能,但是和自己核心業務沒關係,主要是產品運營方便收集用戶的對產品的反饋。HotApp推出了用戶反饋的組件,方便大家直接集成使用 源碼下載地址: https://github.com/hotapp8/hotapp-fedback (1)零代碼接入用戶反饋功能 界面仿微信 ...
  • 昨天的(今天凌晨)的博文《Android中Fragment和ViewPager那點事兒》中,我們通過使用Fragment和ViewPager模仿實現了微信的佈局框架。今天我們來通過使用ListView實現其中聯繫人一欄的基本視圖,效果如下: 要實現上圖的效果,我們要用到兩個知識點: 1、這裡我們使用 ...
  • listview經常結合下來刷新和上拉載入更多使用,本文總結了三種常用到的方案分別作出說明。 ...
  • 概述 本篇文章會從源碼(基於Android 6.0)角度分析Android中View的繪製流程,側重於對整體流程的分析,對一些難以理解的點加以重點闡述,目的是把View繪製的整個流程把握好,而對於特定實現細節則可以日後再對相應源碼進行研讀。在進行實際的分析之前,我們先來看下麵這張圖: 我們來對上圖做 ...
  • 鎖終端 輸入: <1>cd /Applications/Xcode.app 回車 結果顯示: Xcode.app 輸入: <2>sudo chown -hR root:wheel Contents 回車 結果顯示: WARNING: Improper use of the sudo command ...
  • 經過努力終於發現了最新的 解決cocoaPods安裝的辦法: taobao Gems 源已停止維護,現由 ruby-china 提供鏡像服務 第一步:安裝rvm, 不管需不需要升級ruby,rvm可以讓你擁有多個版本的Ruby,並且可以在多個版本之間自由切換。如果已經安裝過跳到第2步(rvm -v ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...