Android中Fragment和ViewPager那点事儿(仿微信APP)

本文介绍如何在Android中结合ViewPager和Fragment,模仿微信应用的界面切换效果。通过点击导航按钮或滑动屏幕,实现场景间的平滑过渡,并同步更新导航组件的状态。主要步骤包括设置主布局、创建fragment布局、定义导航组件的形态变化、建立FragmentPagerAdapter以及处理点击事件和页面监听。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在之前的博文《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嵌套来实现主布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
   android:orientation="vertical"
    tools:context="com.example.administrator.viewpagerfragment.MainActivity">

    <LinearLayout
        android:background="@color/colorblack"
        android:padding="10dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <TextView
            android:layout_width="0dp"
            android:layout_weight="1"
            android:gravity="center_vertical"
            android:layout_height="match_parent"
            android:layout_marginLeft="5dp"
            android:text="潘侯爷微信"
            android:textSize="20sp"
            android:textColor="@color/colorWhite"/>

        <ImageView
            android:src="@mipmap/jy_drltsz_btn_addperson"
            android:adjustViewBounds="true"
            android:maxHeight="23dp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
    </LinearLayout>


    <android.support.v4.view.ViewPager
        android:id="@+id/viewPager"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"/>

    <View
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:background="@color/colornormal"/>

    <LinearLayout
        android:orientation="horizontal"
        android:padding="5dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <LinearLayout
            android:id="@+id/weixin"
            android:clickable="true"
            android:orientation="vertical"
            android:layout_width="0dp"
            android:gravity="center"
            android:layout_weight="1"
            android:layout_height="wrap_content">

            <ImageView
                android:id="@+id/weixin_img"
                android:background="@drawable/weixin_picture_selector"
                android:layout_width="30dp"
                android:layout_height="25dp" />
            <TextView
                android:id="@+id/weixin_txt"
                android:layout_width="wrap_content"
                android:gravity="center"
                android:layout_height="wrap_content"
                android:text="微信"
                android:textSize="12sp"
                android:textColor="@drawable/weixin_text_selector"/>
        </LinearLayout>

        <LinearLayout
            android:id="@+id/contact"
            android:clickable="true"
            android:orientation="vertical"
            android:layout_width="0dp"
            android:gravity="center"
            android:layout_weight="1"
            android:layout_height="wrap_content">

            <ImageView
                android:id="@+id/contact_img"
                android:background="@drawable/txl_picture_selector"
                android:layout_width="30dp"
                android:layout_height="25dp" />

            <TextView
                android:id="@+id/contact_txt"
                android:layout_width="wrap_content"
                android:gravity="center"
                android:layout_height="wrap_content"
                android:text="通讯录"
                android:textSize="12sp"
                android:textColor="@drawable/weixin_text_selector"/>
        </LinearLayout>

        <LinearLayout
            android:id="@+id/find"
            android:clickable="true"
            android:orientation="vertical"
            android:layout_width="0dp"
            android:gravity="center"
            android:layout_weight="1"
            android:layout_height="wrap_content">

            <ImageView
                android:id="@+id/find_img"
                android:background="@drawable/find_picture_selector"
                android:layout_width="30dp"
                android:layout_height="25dp" />
            <TextView
                android:id="@+id/find_txt"
                android:layout_width="wrap_content"
                android:gravity="center"
                android:layout_height="wrap_content"
                android:text="发现"
                android:textSize="12sp"
                android:textColor="@drawable/weixin_text_selector"/>
        </LinearLayout>

        <LinearLayout
            android:id="@+id/self"
            android:clickable="true"
            android:orientation="vertical"
            android:layout_width="0dp"
            android:gravity="center"
            android:layout_weight="1"
            android:layout_height="wrap_content">

            <ImageView
                android:id="@+id/self_img"
                android:background="@drawable/me_picture_selector"
                android:layout_width="30dp"
                android:layout_height="25dp" />
            <TextView
                android:id="@+id/self_txt"
                android:layout_width="wrap_content"
                android:gravity="center"
                android:layout_height="wrap_content"
                android:text="我"
                android:textSize="12sp"
                android:textColor="@drawable/weixin_text_selector"/>
        </LinearLayout>
    </LinearLayout>
</LinearLayout>

第二步:layout中fragment的布局文件

这里四个导航对应四个不同的fragment(实现上面的效果,也可以只建立一个fragment,但这样不利于后期扩展),这里我们只演示其中一个weixin_fragment.xml(其他三个为contactListFragment;findFragment;selfFragment

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:id="@+id/tv"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="没有微信消息"
        android:gravity="center"
        android:textSize="50sp"/>
</LinearLayout>

第三步:drable中设定下方导航组件不同的形态

导航组件中文字形态变化只是颜色不同,图片的话需要设置点击前后不同的图片(这里演示一种)

(1)文字的变化wenxin_text_selector.xml

这里使用selected而不用checked的原因:个人使用的导航布局为linerlayout,并且为linerlayout设置chiclable而不是其中的Text/imageView,所以为了判断变化,这里使用了selected,方便代码中设置调用。

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

(2)图片的变化weixin_picture_selector.xml

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

第四步:Java中对应fragment布局的Fragment继承类

这里建议继承android.support.v4.app.Fragment包下的.Fragment,因为后面要用的FragmentPagerAdapter属于V4包,应该统一。

4个fragment对应4个java类,这里演示一个,其他三个都一样。

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
/**
 * Created by panchengjia on 2016/12/24.
 */
public class WeixinFragment extends Fragment {
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.weixin_fragment,container,false);
        return view;
    }
}

第五步:java中功能实现MainActivity.java文件

代码中详细标注了各个实现步骤的注释,这里不再赘述

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import java.util.ArrayList;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    //声明存储fragment的集合
    private ArrayList<Fragment> fragments;
    //声明四个导航对应fragment
    WeixinFragment weixinFragment;
    ContactListFragment contactListFragment;
    FindFragment findFragment;
    SelfFragment selfFragment;
    //声明ViewPager
    private ViewPager viewPager;
    FragmentManager fragmentManager;//声明fragment管理
    //声明导航栏中对应的布局
    private LinearLayout weixin, contact, find, self;
    //声明导航栏中包含的imageview和textview
    private ImageView weixin_img, contact_img, find_img, self_img;
    private TextView weixin_txt, contact_txt, find_txt, self_txt;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //初始化加载首页布局
        initView();
        //调用自定义initListener方法,为各个组件添加监听事件
        initListener();
        //设置默认选择的pager和导航栏的状态
        viewPager.setCurrentItem(0);
        weixin_img.setSelected(true);
        weixin_txt.setSelected(true);
    }

    private void initListener() {
        //为四大导航组件添加监听
        weixin.setOnClickListener(this);
        contact.setOnClickListener(this);
        find.setOnClickListener(this);
        self.setOnClickListener(this);
        //为viewpager添加页面变化的监听以及事件处理
        viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

            }

            @Override
            public void onPageSelected(int position) {
                //根据位置直接决定显示哪个fragment
                viewPager.setCurrentItem(position);
                switch (position) {
                    case 0:
                        weixin_img.setSelected(true);
                        weixin_txt.setSelected(true);

                        contact_img.setSelected(false);
                        contact_txt.setSelected(false);
                        find_img.setSelected(false);
                        find_txt.setSelected(false);
                        self_img.setSelected(false);
                        self_txt.setSelected(false);

                        break;
                    case 1:
                        weixin_img.setSelected(false);
                        weixin_txt.setSelected(false);

                        contact_img.setSelected(true);
                        contact_txt.setSelected(true);
                        find_img.setSelected(false);
                        find_txt.setSelected(false);
                        self_img.setSelected(false);
                        self_txt.setSelected(false);

                        break;
                    case 2:
                        weixin_img.setSelected(false);
                        weixin_txt.setSelected(false);

                        contact_img.setSelected(false);
                        contact_txt.setSelected(false);
                        find_img.setSelected(true);
                        find_txt.setSelected(true);
                        self_img.setSelected(false);
                        self_txt.setSelected(false);

                        break;
                    case 3:
                        weixin_img.setSelected(false);
                        weixin_txt.setSelected(false);

                        contact_img.setSelected(false);
                        contact_txt.setSelected(false);
                        find_img.setSelected(false);
                        find_txt.setSelected(false);
                        self_img.setSelected(true);
                        self_txt.setSelected(true);
                        break;
                }
            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });

    }

    private void initView() {
        //在主布局中根据id找到ViewPager
        viewPager = (ViewPager) findViewById(R.id.viewPager);
        //实例化所属四个fragment
        weixinFragment = new WeixinFragment();
        contactListFragment = new ContactListFragment();
        findFragment = new FindFragment();
        selfFragment = new SelfFragment();
        fragments = new ArrayList<>();
        //添加fragments到集合中
        fragments.add(weixinFragment);
        fragments.add(contactListFragment);
        fragments.add(findFragment);
        fragments.add(selfFragment);
        fragmentManager = getSupportFragmentManager();
        //为ViewPager设置适配器用于部署fragments
        viewPager.setAdapter(new MyFragmentPagerAdapter(fragmentManager));


        weixin = (LinearLayout) findViewById(R.id.weixin);
        contact = (LinearLayout) findViewById(R.id.contact);
        find = (LinearLayout) findViewById(R.id.find);
        self = (LinearLayout) findViewById(R.id.self);


        weixin_img = (ImageView) findViewById(R.id.weixin_img);
        contact_img = (ImageView) findViewById(R.id.contact_img);
        find_img = (ImageView) findViewById(R.id.find_img);
        self_img = (ImageView) findViewById(R.id.self_img);

        weixin_txt = (TextView) findViewById(R.id.weixin_txt);
        contact_txt = (TextView) findViewById(R.id.contact_txt);
        find_txt = (TextView) findViewById(R.id.find_txt);
        self_txt = (TextView) findViewById(R.id.self_txt);
    }

    /**
     * 设置导航栏的点击事件并同步更新对应的ViewPager
     * 点击事件其实就是更改导航布局中对应的Text/ImageView
     * 的选中状态,配合drable中的selector更改图片以及文字变化
     *
     * @param v
     */
    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.weixin:
                viewPager.setCurrentItem(0);
                weixin_img.setSelected(true);
                weixin_txt.setSelected(true);

                contact_img.setSelected(false);
                contact_txt.setSelected(false);
                find_img.setSelected(false);
                find_txt.setSelected(false);
                self_img.setSelected(false);
                self_txt.setSelected(false);

                break;
            case R.id.contact:
                viewPager.setCurrentItem(1);
                weixin_img.setSelected(false);
                weixin_txt.setSelected(false);

                contact_img.setSelected(true);
                contact_txt.setSelected(true);
                find_img.setSelected(false);
                find_txt.setSelected(false);
                self_img.setSelected(false);
                self_txt.setSelected(false);

                break;
            case R.id.find:
                viewPager.setCurrentItem(2);
                weixin_img.setSelected(false);
                weixin_txt.setSelected(false);

                contact_img.setSelected(false);
                contact_txt.setSelected(false);
                find_img.setSelected(true);
                find_txt.setSelected(true);
                self_img.setSelected(false);
                self_txt.setSelected(false);

                break;
            case R.id.self:
                viewPager.setCurrentItem(3);
                weixin_img.setSelected(false);
                weixin_txt.setSelected(false);

                contact_img.setSelected(false);
                contact_txt.setSelected(false);
                find_img.setSelected(false);
                find_txt.setSelected(false);
                self_img.setSelected(true);
                self_txt.setSelected(true);

                break;
        }
    }

    //创建FragmentPagerAdapter
    class MyFragmentPagerAdapter extends FragmentPagerAdapter {

        public MyFragmentPagerAdapter(FragmentManager fm) {
            super(fm);
        }

        @Override
        public android.support.v4.app.Fragment getItem(int position) {
            return fragments.get(position);
        }

        @Override
        public int getCount() {
            return fragments.size();
        }
    }
}


后期就微信的其他功能的实现做简单介绍,不早了,休息


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值