Fragment的两种切换方式


不积跬步,无以至千里;不积小流,无以成江海。要沉下心来,诗和远方的路费真的很贵!

Fragment的两种切换方式

  • 两种方式为addreplace
  • add方式和replace方式区别:
    • add方式每次切换不同的Fragment的时候,不会重新创建,都是恢复上次的。如今大多数的app基本都是采用这种方式。
    • replace方式每次切换不同的Fragment,都会重新创建一个Fragment

replace

使用三个布局作为底部按钮,用一个布局占据放置Fragment的位置。

  • 布局-------activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/fragment"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:layout_constraintBottom_toTopOf="@+id/constraintLayout2"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

    </androidx.constraintlayout.widget.ConstraintLayout>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/constraintLayout"
        android:layout_width="0dp"
        android:layout_height="60dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toStartOf="@+id/constraintLayout2"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="消息"
            android:textColor="@color/main_color"
            android:textSize="25sp"
            android:typeface="serif"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

    </androidx.constraintlayout.widget.ConstraintLayout>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/constraintLayout2"
        android:layout_width="0dp"
        android:layout_height="60dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toStartOf="@+id/constraintLayout3"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toEndOf="@+id/constraintLayout">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="联系人"
            android:textColor="@color/main_color"
            android:textSize="25sp"
            android:typeface="serif"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
    </androidx.constraintlayout.widget.ConstraintLayout>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/constraintLayout3"
        android:layout_width="0dp"
        android:layout_height="60dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toEndOf="@+id/constraintLayout2">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="动态"
            android:textColor="@color/main_color"
            android:textSize="25sp"
            android:typeface="serif"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
    </androidx.constraintlayout.widget.ConstraintLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

创建三个Fragment,并且在每个Fragment布局中加入文本控件,设置文本点击事件,来判断Fragment是否重建。

  • 三个Fragment相似,此处以MessageFragment为例。

    • 布局-------fragment_message.xml
    <?xml version="1.0" encoding="utf-8"?>
    <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MessageFragment">
    
        <TextView
            android:id="@+id/msgTextView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:text="消息"
            android:gravity="center"
            android:typeface="monospace"
            android:textColor="#000000"
            android:textSize="50sp"/>
    
    </androidx.constraintlayout.widget.ConstraintLayout>
    
    • 逻辑-------MessageFragment
    package com.hnucm.androidfragment;
    
    import android.os.Bundle;
    import androidx.annotation.Nullable;
    import androidx.fragment.app.Fragment;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.TextView;
    
    public class MessageFragment extends Fragment {
        //定义控件
        private TextView textView;
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            //得到fragment中的布局文件
            View view = LayoutInflater.from(getActivity()).inflate(R.layout.fragment_message,container,false);
            //找到布局中的控件
            textView = (TextView) view.findViewById(R.id.msgTextView);
            //设置点击文本变化来判断是否重建fragment
            textView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    textView.setText("我变了-" + textView.getText().toString());
                }
            });
            //返回view
            return view;
        }
    
        @Override
        public void onActivityCreated(@Nullable Bundle savedInstanceState) {
            super.onActivityCreated(savedInstanceState);
        }
    }
    

在MainActivity中主要实现采用replace方式的切换以及底下文字颜色点击变化。

  • 逻辑-------MainActivity
package com.hnucm.androidfragment;

import androidx.appcompat.app.AppCompatActivity;
import androidx.constraintlayout.widget.ConstraintLayout;
import android.os.Bundle;
import android.view.View;

public class MainActivity extends AppCompatActivity implements View.OnClickListener{
    //定义三个Fragment
    private MessageFragment messageFragment;
    private PersonFragment personFragment;
    private DynamicFragment dynamicFragment;
    //定义三个布局按钮
    private ConstraintLayout constraintLayout;
    private ConstraintLayout constraintLayout2;
    private ConstraintLayout constraintLayout3;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //初始化Fragment
        messageFragment = new MessageFragment();
        personFragment = new PersonFragment();
        dynamicFragment = new DynamicFragment();
        //初始化ConstraintLayout
        constraintLayout = findViewById(R.id.constraintLayout);
        constraintLayout2 = findViewById(R.id.constraintLayout2);
        constraintLayout3 = findViewById(R.id.constraintLayout3);
        //定义三个布局
        //消息布局按钮
        constraintLayout.setOnClickListener(this);
        //联系人布局按钮
        constraintLayout2.setOnClickListener(this);
        //动态布局按钮
        constraintLayout3.setOnClickListener(this);
        //点击消息,字体颜色变化
        constraintLayout.setSelected(true);
        constraintLayout2.setSelected(false);
        constraintLayout3.setSelected(false);
        //事务一定要提交
        getSupportFragmentManager().beginTransaction().replace(R.id.fragment,messageFragment).commit();
    }

    @Override
    //点击事件
    public void onClick(View view) {
        switch(view.getId()){
            //切换fragment
            case R.id.constraintLayout:
                //字体颜色变化
                constraintLayout.setSelected(true);
                constraintLayout2.setSelected(false);
                constraintLayout3.setSelected(false);
                //替换Fragment
                getSupportFragmentManager().beginTransaction().replace(R.id.fragment,messageFragment).commit();
                break;
            case R.id.constraintLayout2:
                //颜色变化
                constraintLayout.setSelected(false);
                constraintLayout2.setSelected(true);
                constraintLayout3.setSelected(false);
                //切换
                getSupportFragmentManager().beginTransaction().replace(R.id.fragment,personFragment).commit();
                break;
            case R.id.constraintLayout3:
                //颜色
                constraintLayout.setSelected(false);
                constraintLayout2.setSelected(false);
                constraintLayout3.setSelected(true);
                //切换
                getSupportFragmentManager().beginTransaction().replace(R.id.fragment,dynamicFragment).commit();
                break;
        }
    }
}
  • 颜色改变文件-------main_color.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#000000" android:state_selected="false"/>
    <item android:color="#397291" android:state_selected="true"/>
</selector>

只需把文字颜色设置为这个文件即可。

add

所有的都不用改,只需要改MainActivity中的逻辑即可。

将replace方法改为add方法即可。

replace方法直接替换覆盖,add方法主要是采用隐藏和显示。

  • 逻辑-------MainActivity
package com.hnucm.androidfragment;

import androidx.appcompat.app.AppCompatActivity;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.fragment.app.FragmentTransaction;

import android.os.Bundle;
import android.view.View;

public class MainActivity extends AppCompatActivity implements View.OnClickListener{
    //定义三个Fragment
    private MessageFragment messageFragment;
    private PersonFragment personFragment;
    private DynamicFragment dynamicFragment;
    //定义三个布局按钮
    private ConstraintLayout constraintLayout;
    private ConstraintLayout constraintLayout2;
    private ConstraintLayout constraintLayout3;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //初始化ConstraintLayout
        constraintLayout = findViewById(R.id.constraintLayout);
        constraintLayout2 = findViewById(R.id.constraintLayout2);
        constraintLayout3 = findViewById(R.id.constraintLayout3);
        //定义三个布局
        //消息布局按钮
        constraintLayout.setOnClickListener(this);
        //联系人布局按钮
        constraintLayout2.setOnClickListener(this);
        //动态布局按钮
        constraintLayout3.setOnClickListener(this);
        //点击消息,字体颜色变化
        constraintLayout.setSelected(true);
        constraintLayout2.setSelected(false);
        constraintLayout3.setSelected(false);
        //第一次初始化默认显示第一个fragment
        initMessageFragment();
    }

    //显示消息Fragment
    private void initMessageFragment(){
        //开启事务,由事务来控制Fragment
        FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
        //初始化fragment并加入到事务中,如果为空就new一个
        //if条件判断语句导致add方法无需每次新建一个Fragment
        if(messageFragment == null){
            //新建一个
            messageFragment = new MessageFragment();
            //添加进事务中,并且放置到预留的区域
            fragmentTransaction.add(R.id.fragment,messageFragment);
        }
        //隐藏事务中所有的Fragment
        hideFragment(fragmentTransaction);
        //显示需要显示的Fragment
        fragmentTransaction.show(messageFragment);
        //提交事务,事务一定要提交,不然无效
        fragmentTransaction.commit();
    }

    //显示联系人Fragment
    private void initPersonFragment(){
        //开启事务,由事务来控制Fragment
        FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
        //初始化fragment并加入到事务中,如果为空就new一个
        //if条件判断语句导致add方法无需每次新建一个Fragment
        if(personFragment == null){
            //新建一个
            personFragment = new PersonFragment();
            //添加进事务中,并且放置到预留的区域
            fragmentTransaction.add(R.id.fragment,personFragment);
        }
        //隐藏事务中所有的Fragment
        hideFragment(fragmentTransaction);
        //显示需要显示的Fragment
        fragmentTransaction.show(personFragment);
        //提交事务,事务一定要提交,不然无效
        fragmentTransaction.commit();
    }

    //显示动态Fragment
    private void initDynamicFragment(){
        //开启事务,由事务来控制Fragment
        FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
        //初始化fragment并加入到事务中,如果为空就new一个
        //if条件判断语句导致add方法无需每次新建一个Fragment
        if(dynamicFragment == null){
            //新建一个
            dynamicFragment = new DynamicFragment();
            //添加进事务中,并且放置到预留的区域
            fragmentTransaction.add(R.id.fragment,dynamicFragment);
        }
        //隐藏事务中所有的Fragment
        hideFragment(fragmentTransaction);
        //显示需要显示的Fragment
        fragmentTransaction.show(dynamicFragment);
        //提交事务,事务一定要提交,不然无效
        fragmentTransaction.commit();
    }

    //隐藏Fragment
    private void hideFragment(FragmentTransaction fragmentTransaction){
        //隐藏MessageFragment
        if(messageFragment != null){
            fragmentTransaction.hide(messageFragment);
        }
        //隐藏PersonFragment
        if(personFragment != null){
            fragmentTransaction.hide(personFragment);
        }
        //隐藏DynamicFragment
        if(dynamicFragment != null){
            fragmentTransaction.hide(dynamicFragment);
        }
    }

    @Override
    //点击事件
    public void onClick(View view) {
        switch(view.getId()){
            //切换fragment
            case R.id.constraintLayout:
                //字体颜色变化
                constraintLayout.setSelected(true);
                constraintLayout2.setSelected(false);
                constraintLayout3.setSelected(false);
                //替换Fragment
                initMessageFragment();
                break;
            case R.id.constraintLayout2:
                //颜色变化
                constraintLayout.setSelected(false);
                constraintLayout2.setSelected(true);
                constraintLayout3.setSelected(false);
                //切换
                initPersonFragment();
                break;
            case R.id.constraintLayout3:
                //颜色
                constraintLayout.setSelected(false);
                constraintLayout2.setSelected(false);
                constraintLayout3.setSelected(true);
                //切换
                initDynamicFragment();
                break;
        }
    }
}

代码可以继续优化。

参考上述代码,我们发现initMessageFragment方法和initPersonFragment方法以及initDynamicFragment方法很相似,我们可以利用传递参数的方式写成一个函数。

就比如写一个简单工厂方法,其他的方法都是通过这个工厂去生产产生,你只需要传递参数,就可以根据不同参数返回不同的类型。

  • 逻辑-------MainActivity
package com.hnucm.androidfragment;

import androidx.appcompat.app.AppCompatActivity;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentTransaction;

import android.os.Bundle;
import android.view.View;

public class MainActivity extends AppCompatActivity implements View.OnClickListener{
    //定义三个Fragment
    private MessageFragment messageFragment;
    private PersonFragment personFragment;
    private DynamicFragment dynamicFragment;
    //定义三个布局按钮
    private ConstraintLayout constraintLayout;
    private ConstraintLayout constraintLayout2;
    private ConstraintLayout constraintLayout3;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //初始化ConstraintLayout
        constraintLayout = findViewById(R.id.constraintLayout);
        constraintLayout2 = findViewById(R.id.constraintLayout2);
        constraintLayout3 = findViewById(R.id.constraintLayout3);
        //定义三个布局
        //消息布局按钮
        constraintLayout.setOnClickListener(this);
        //联系人布局按钮
        constraintLayout2.setOnClickListener(this);
        //动态布局按钮
        constraintLayout3.setOnClickListener(this);
        //点击消息,字体颜色变化
        constraintLayout.setSelected(true);
        constraintLayout2.setSelected(false);
        constraintLayout3.setSelected(false);
        //第一次初始化默认显示第一个fragment
        initFragment(messageFragment);
    }

    //生产显示不同Fragment的简单工厂方法
    private void initFragment(Fragment fragment){
        //开启事务来控制Fragment
        FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
        //初始化fragment并加入到事务中,如果为空就new一个
        //if条件判断语句导致add方法无需每次新建一个Fragment
        if(fragment == null){
            //里氏代换原则,子类都可以代替父类
            //Fragment是一切Fragment的父类
            //新建一个Fragment
            fragment = new Fragment();
            //加入到事务中,并放置在预先留好的位置
            fragmentTransaction.add(R.id.fragment,fragment);
        }
        //隐藏所有的Fragment
        hideFragment(fragmentTransaction);
        //显示需要显示的Fragment
        fragmentTransaction.show(fragment);
        //提交事务,事务一定要提交,不然无效
        fragmentTransaction.commit();
    }

    //隐藏Fragment
    private void hideFragment(FragmentTransaction fragmentTransaction){
        //隐藏MessageFragment
        if(messageFragment != null){
            fragmentTransaction.hide(messageFragment);
        }
        //隐藏PersonFragment
        if(personFragment != null){
            fragmentTransaction.hide(personFragment);
        }
        //隐藏DynamicFragment
        if(dynamicFragment != null){
            fragmentTransaction.hide(dynamicFragment);
        }
    }

    @Override
    //点击事件
    public void onClick(View view) {
        switch(view.getId()){
            //切换fragment
            case R.id.constraintLayout:
                //字体颜色变化
                constraintLayout.setSelected(true);
                constraintLayout2.setSelected(false);
                constraintLayout3.setSelected(false);
                //替换Fragment
                initFragment(messageFragment);
                break;
            case R.id.constraintLayout2:
                //颜色变化
                constraintLayout.setSelected(false);
                constraintLayout2.setSelected(true);
                constraintLayout3.setSelected(false);
                //切换
                initFragment(personFragment);
                break;
            case R.id.constraintLayout3:
                //颜色
                constraintLayout.setSelected(false);
                constraintLayout2.setSelected(false);
                constraintLayout3.setSelected(true);
                //切换
                initFragment(dynamicFragment);
                break;
        }
    }
}

想法具有可实行性,但是具体的新建还是有问题,出来的是一个初始Fragment,后续继续修改。

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值