Android:多个Fragment切换问题/切换动画设置

Posted zstar-_

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android:多个Fragment切换问题/切换动画设置相关的知识,希望对你有一定的参考价值。

问题描述

在项目开发中,遇到这样一个问题场景:在某个页面(Fragament)中,点击按钮,进行页面部分的切换,即在一个Fragament中嵌套使用了两个Fragament进行切换。

设置按钮监听

首先在布局文件中,给两个进行切换的按钮标记id:button_user、button_shop;
并添加需要动态填充的布局(id为id_role)

<Button
   android:id="@+id/button_user"
   android:layout_width="100dp"
   android:layout_height="30dp"
   android:background="@drawable/button_circle2"
   android:text="我是用户"
   android:textColor="@color/bar"
   android:textSize="12sp"
   android:paddingTop="-10dp"
   android:paddingLeft="10dp"
   android:paddingRight="10dp"
   android:layout_marginLeft="70dp"/>


<Button
   android:id="@+id/button_shop"
   android:layout_width="100dp"
   android:layout_height="30dp"
   android:background="@drawable/button_circle"
   android:text="我是商家"
   android:textColor="@color/white"
   android:textSize="12sp"
   android:paddingTop="-10dp"
   android:paddingLeft="10dp"
   android:paddingRight="10dp"
   android:layout_marginLeft="20dp"/>


<LinearLayout
   android:id="@+id/id_role"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:orientation="vertical">
</LinearLayout>

在主控的Fragment文件中调用接口 View.OnClickListener

public class page fragment extends Fragment implements View.OnClickListener
	...

在onActivityCreated中绑定按钮并设置按钮监听:

@Override
public void onActivityCreated(Bundle savedInstanceState) 
    super.onActivityCreated(savedInstanceState);
    Button button_user = (Button) getActivity().findViewById(R.id.button_user);
    Button button_shop = (Button) getActivity().findViewById(R.id.button_shop);
    button_user.setOnClickListener(this);
    button_shop.setOnClickListener(this);

覆写接口的onClick方法

@Override
public void onClick(View v) 
    switch (v.getId())
        case R.id.button_user:
            Log.d("Number","1");
            break;
        case R.id.button_shop:
            Log.d("Number","2");
            break;
        default:
            break;
    

至此,按钮监听设置完成。

Fragment切换

要实现Fragment的切换,使用FragmentManager类来管理fragment,对fragment的操作(添加、删除、替换等)称为一个事务,通过FragmentTransaction类来提交执行。(类似数据库中的事务概念)
几个关键方法
add() :添加
hide() :隐藏
show() :显示
replace() :替换
关于Fragment 生命周期/事物管理的更详细的信息可参考这篇博文Fragment的基本应用

简要来说,实现fragment切换主要步骤为:
1.实例化对象fragmentTransaction
2.隐藏当前已显示的fragment
3.对需要动态添加的fragment进行判断,如果没有,使用add添加;如果已有,直接显示。
4.提交事务
相关代码如下:

 private void hideFragment(FragmentTransaction fragmentTransaction) 
        if(imshop != null)
            fragmentTransaction.hide(imshop);
        
        if(imuser != null)
            fragmentTransaction.hide(imuser);
        
    

    @Override
    public void onClick(View v) 
        FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
        hideFragment(fragmentTransaction);
        switch (v.getId())
            case R.id.button_user:
                if(imuser == null)
                    imuser imuser = new imuser();
                    fragmentTransaction.replace(R.id.id_role,imuser);
                else 
                    fragmentTransaction.show(imuser);
                
                break;
            case R.id.button_shop:
                if(imshop == null)
                    imshop imshop = new imshop();
                    fragmentTransaction.replace(R.id.id_role,imshop);
                else 
                    fragmentTransaction.show(imshop);
                
                break;
            default:
                break;
        
        fragmentTransaction.commit();
    

其中,imuser/imshop 为我需要添加的两个Fragment的类对象。
这里我遇到了一个小问题,使用add进行添加后,并不能完成切换,但替换成replace之后便可实现切换,具体原因待考究。

Fragment动画

点击按钮进行界面切换是瞬间完成的,对于用户来说,体验并不良好。因此可以简单添加两个左移、右移的动画来进行过渡,使体验更为丝滑。

首先建立动画文件,在res下创建文件夹anim。

先考虑一个左移动画,主要可拆分成两个步骤:1.当前页面向左划出。2.之后页面向右划入。
因此建立两个文件:
左移划出:slide_out_to_left.xml

<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="400"
    android:fromXDelta="0.0"
    android:interpolator="@android:anim/accelerate_interpolator"
    android:toXDelta="-100%" />

右移划入:slide_in_from_right

<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="400"
    android:fromXDelta="100.0%"
    android:interpolator="@android:anim/accelerate_interpolator"
    android:toXDelta="0.0"
    />

这里参数简单说明一下:
duration:表示动画持续时间(毫秒)
fromXDelta:滑动起始点
toXDelta:滑动终点

更多属性可参考这篇文章Android动画

上面两个步骤实现了左滑,同样,右滑只需要修改坐标值即可。

左移划入slide_in_from_left.xml

<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="400"
    android:fromXDelta="-100%"
    android:interpolator="@android:anim/accelerate_interpolator"
    android:toXDelta="0.0"
    />

右移划出slide_out_to_right.xml

<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="400"
    android:fromXDelta="0.0"
    android:interpolator="@android:anim/accelerate_interpolator"
    android:toXDelta="100%" />

设置完之后,重新修改控制文件,只需添加 fragmentTransaction.setCustomAnimations属性。

	@Override
    public void onClick(View v) 
        FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
        hideFragment(fragmentTransaction);
        switch (v.getId())
            case R.id.button_user:
                if(imuser == null)
                    imuser imuser = new imuser();
                    fragmentTransaction.setCustomAnimations(R.anim.slide_in_from_right, R.anim.slide_out_to_left);
                    fragmentTransaction.replace(R.id.id_role,imuser);
                else 
                    fragmentTransaction.show(imuser);
                
                break;
            case R.id.button_shop:
                if(imshop == null)
                    imshop imshop = new imshop();
                    fragmentTransaction.setCustomAnimations(R.anim.slide_in_from_left, R.anim.slide_out_to_right);
                    fragmentTransaction.replace(R.id.id_role,imshop);
                else 
                    fragmentTransaction.show(imshop);
                
                break;
            default:
                break;
        
        fragmentTransaction.commit();
    

效果演示:

常规Activity多个Fragment切换

设计导航栏时经常采用在Activity中进行多个Fragment切换,实际上和在Fragment进行设计大同小异。这里放置一个案例可供参考。

main.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/bg">

    <LinearLayout
        android:id="@+id/id_content"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
    </LinearLayout>
    <include layout="@layout/bottom" />
</FrameLayout>

bottom.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="66dp"
    android:gravity="center"
    android:orientation="horizontal"
    android:background="@color/white"
    android:layout_gravity="bottom">

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

        <ImageButton
            android:id="@+id/id_tab_img1"
            android:clickable="false"
            android:layout_width="28dp"
            android:layout_height="28dp"
            android:src="@drawable/home"
            android:scaleType="fitXY"
            android:background="#00000000"/>

    </LinearLayout>

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

        <ImageButton
            android:id="@+id/id_tab_img2"
            android:clickable="false"
            android:layout_width="28dp"
            android:layout_height="28dp"
            android:scaleType="fitXY"
            android:src="@drawable/product"
            android:background="#00000000"/>

    </LinearLayout>

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

        <ImageButton
            android:id="@+id/id_tab_add"
            android:clickable="false"
            android:layout_width="60dp"
            android:layout_height="60dp"
            android:src="@drawable/add"
            android:scaleType="fitXY"
            android:background="#00000000"/>
    </LinearLayout>

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

        <ImageButton
            android:id="@+id/id_tab_img3"
            android:clickable="false"
            android:layout_width="28dp"
            android:layout_height="28dp"
            android:src="@drawable/community"
            android:scaleType="fitXY"
            android:background="#00000000"/>

    </LinearLayout>

    <LinearLayout

        android:id="@+id/id_tab4"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:gravity="center"
        android:orientation="vertical">

        <ImageButton
            android:id="@+id/id_tab_img4"
            android:clickable="false"
            android:layout_width="28dp"
            android:layout_height="28dp"
            android:src="@drawable/me"
            android:scaleType="fitXY"
            android:background="#00000000"/>

    </LinearLayout>

</LinearLayout>

MainActivity.java

package cn.edu.cdut.goat;

import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import androidx.viewpager.widget.PagerAdapter;
import androidx.viewpager.widget.ViewPager;

import android.annotation.SuppressLint;
Android安卓viewpager和Fragment的结合,多个Fragment视图之间切换等运用

android中Fragment的切换方法。

Android Fragment实现button间的切换

Android 一个Activity 里面放置多个 Fragment 实现点击切换的Tab 页面效果

Android Viewpager加Fragment做界面切换时数据消失的解决方式

Android编程心得-使用ActionBar+Fragment+ViewPager实现动态切换Menu效果