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

Android:多个Fragment切换问题切换动画设置,第1张

问题描述

在项目开发中,遇到这样一个问题场景:在某个页面(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


<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


<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


<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


<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


<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;
import android.app.Activity;
import android.app.LocalActivityManager;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.ImageButton;
import android.widget.LinearLayout;

import java.util.ArrayList;
import java.util.List;

import cn.edu.cdut.goat.R;

public class MainActivity extends FragmentActivity implements View.OnClickListener {
    //声明四个Tab的布局文件
    private LinearLayout mTab1;
    private LinearLayout mTab2;
    private LinearLayout mTab3;
    private LinearLayout mTab4;

    //声明四个Tab的ImageButton
    private ImageButton mImg1;
    private ImageButton mImg2;
    private ImageButton mImg3;
    private ImageButton mImg4;

    //声明四个Tab分别对应的Fragment
    private Fragment mFrag1;
    private Fragment mFrag2;
    private Fragment mFrag3;
    private Fragment mFrag4;

    @Override
    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);  // 隐藏标题栏
        setContentView(R.layout.activity_main);
        initViews();//初始化控件
        initEvents();//初始化事件
        selectTab(0);//默认选中第一个Tab
    }

    private void initEvents(){
        //初始化四个Tab的点击事件
        mTab1.setOnClickListener(this);
        mTab2.setOnClickListener(this);
        mTab3.setOnClickListener(this);
        mTab4.setOnClickListener(this);
    }

    private void initViews(){
        //初始化四个Tab的布局文件
        mTab1=(LinearLayout)findViewById(R.id.id_tab1);
        mTab2=(LinearLayout)findViewById(R.id.id_tab2);
        mTab3=(LinearLayout)findViewById(R.id.id_tab3);
        mTab4=(LinearLayout)findViewById(R.id.id_tab4);

        //初始化四个ImageButton
        mImg1=(ImageButton)findViewById(R.id.id_tab_img1);
        mImg2=(ImageButton)findViewById(R.id.id_tab_img2);
        mImg3=(ImageButton)findViewById(R.id.id_tab_img3);
        mImg4=(ImageButton)findViewById(R.id.id_tab_img4);

    }

    //处理Tab的点击事件
    @SuppressLint("NonConstantResourceId")
    @Override
    public void onClick(View v){
        resetImgs(); //先将四个ImageButton置为灰色
        switch(v.getId()){
            case R.id.id_tab1:
                selectTab(0);
                break;
            case R.id.id_tab2:
                selectTab(1);
                break;
            case R.id.id_tab3:
                selectTab(2);
                break;
            case R.id.id_tab4:
                selectTab(3);
                break;
        }

    }

    //进行选中Tab的处理
    private void selectTab(int i){
        //获取FragmentManager对象
        FragmentManager manager=getSupportFragmentManager();
        //获取FragmentTransaction对象
        FragmentTransaction transaction=manager.beginTransaction();
        //先隐藏所有的Fragment
        hideFragments(transaction);
        switch(i){
            //当选中点击的是第一页的Tab时
            case 0:
                //设置第一页的ImageButton为绿色
                mImg1.setImageResource(R.drawable.home_select);
                //如果第一页对应的Fragment没有实例化,则进行实例化,并显示出来
                if(mFrag1==null){
                    mFrag1=new pageFragment1();
                    transaction.add(R.id.id_content,mFrag1);
                }else{
                    //如果第一页对应的Fragment已经实例化,则直接显示出来
                    transaction.show(mFrag1);
                }
                break;
            case 1:
                mImg2.setImageResource(R.drawable.product_select);
                if(mFrag2==null){
                    mFrag2=new pageFragment2();
                    transaction.add(R.id.id_content,mFrag2);
                }else{
                    transaction.show(mFrag2);
                }
                break;
            case 2:
                mImg3.setImageResource(R.drawable.community_select);
                if(mFrag3==null){
                    mFrag3=new pageFragment3();
                    transaction.add(R.id.id_content,mFrag3);
                }else{
                    transaction.show(mFrag3);
                }
                break;
            case 3:
                mImg4.setImageResource(R.drawable.me_select);
                if(mFrag4==null){
                    mFrag4=new pageFragment4();
                    transaction.add(R.id.id_content,mFrag4);
                }else{
                    transaction.show(mFrag4);
                }
                break;
        }
        //不要忘记提交事务
        transaction.commit();
    }

    //将四个的Fragment隐藏
    private void hideFragments(FragmentTransaction transaction){
        if(mFrag1!=null){
            transaction.hide(mFrag1);
        }
        if(mFrag2!=null){
            transaction.hide(mFrag2);
        }
        if(mFrag3!=null){
            transaction.hide(mFrag3);
        }
        if(mFrag4!=null){
            transaction.hide(mFrag4);
        }
    }

    //将四个ImageButton置为灰色
    private void resetImgs(){
        mImg1.setImageResource(R.drawable.home);
        mImg2.setImageResource(R.drawable.product);
        mImg3.setImageResource(R.drawable.community);
        mImg4.setImageResource(R.drawable.me);
    }
}

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/992774.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-21
下一篇 2022-05-21

发表评论

登录后才能评论

评论列表(0条)

保存