4.fragment碎片化

fragment是什么

fragment类似于activity,也是个容器。

比如在设计一个手机APP中,一个active中是个新闻列表,点击这个新闻,就打开新闻的详情active. 如果在平板也安装这个app,新闻列表的宽度会被自适应拉宽.如果安装到平板,左侧一部分是新闻列表,右侧是新闻详情就好了. fragment就是解决这个问题的.

动态加载fragment

每个fragment都有自己的UI.

比如现在左侧是功能按钮,右侧一个空的布局. 点击左侧的按钮,右侧就加载不同的UI.具体步骤如下:

1.创建左侧fragment,布局中添加一个按钮

2.创建右侧fragment,是被动态加载的布局

3.创建active,先将左侧fragment加到布局中,然后在添加一个右侧的布局,点击按钮后会被右侧fragment替换

具体代码如下:

1.创建左侧fragment:

fragment类似于active,fragment是业务代码,对应一个Ui.
LeftFragment 类

public class LeftFragment extends Fragment {
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return getLayoutInflater().inflate(R.layout.fragment_left_layout,container,false);
    }
}

通过getLayoutInflater加载子布局.

ui布局:

<?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">

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

2.创建右侧fragment

RightFragment类:

public class RightFragment extends Fragment {
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return getLayoutInflater().inflate(R.layout.fragment_right_layout,container,false);
    }
}

UI:

<?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"
    android:background="#ffccee">
    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="显示"
        android:layout_weight="1"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

3.创建active主界面
先看布局,布局横向分割,左侧 右侧控件各占一半.
布局:

<?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:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.appcompat.widget.LinearLayoutCompat
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <fragment
            android:id="@+id/left_fragment"
            android:name="com.example.myapplication.LeftFragment"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            tools:layout="@layout/fragment_left_layout" />

        <FrameLayout
            android:id="@+id/framelayot"
            android:layout_width="0dp"
            android:background="#ffccee"
            android:layout_height="match_parent"
            android:layout_weight="1"
            />
    </androidx.appcompat.widget.LinearLayoutCompat>

</LinearLayout>

FragmentActivity类:

public class FragmentActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_fragment);
        Button button= (Button) getSupportFragmentManager().findFragmentById(R.id.left_fragment).getView().findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                replaceFragment(new RightFragment());
            }
        });
    }

    //加载不同的fragment
    private void replaceFragment(Fragment fragment){
        FragmentManager fm = getSupportFragmentManager();
        FragmentTransaction transaction = fm.beginTransaction();
        transaction.replace(R.id.framelayot,fragment);
        transaction.addToBackStack(null);//返回按钮不退出,返回到上个
        transaction.commit();
    }
}

这个是主界面,通过getSupportFragmentManager().findFragmentById(R.id.left_fragment).getView()获取左侧的fragment上面的按钮.

replaceFragment()是替换方法,替换的步骤如下:

1.创建fragment管理实例

FragmentManager fm = getSupportFragmentManager();

2.启动一个管理事务

FragmentTransaction transaction = fm.beginTransaction();

3.调用替换方法,然后提交:
其中addToBackStack是为了防止按back直接退出.

transaction.replace(R.id.framelayot,fragment);
transaction.addToBackStack(null);//返回按钮不退出,返回到上个
transaction.commit();

手机/平板切换:

在src目录下,layout是适配小屏幕的布局.可以在src下建立一个layout-large适合大屏的屏幕. 这样android会根据屏幕大小自动选择layout或者layout-large的布局.

所以layout下的布局只保留左侧的单页.将layout-large的布局搞成双列,布局名称保存一致.

1.layout下activity_fragment布局:

<?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:layout_width="match_parent"
    android:layout_height="match_parent">
    <androidx.appcompat.widget.LinearLayoutCompat
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <fragment
            android:id="@+id/left_fragment"
            android:name="com.example.myapplication.LeftFragment"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            tools:layout="@layout/fragment_left_layout" />
    </androidx.appcompat.widget.LinearLayoutCompat>

</LinearLayout>

2.layout-large下的activity_fragment布局:

<?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:layout_width="match_parent"
android:layout_height="match_parent">

<androidx.appcompat.widget.LinearLayoutCompat
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <fragment
        android:id="@+id/left_fragment"
        android:name="com.example.myapplication.LeftFragment"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        tools:layout="@layout/fragment_left_layout" />

    <fragment
        android:id="@+id/right_fragment"
        android:layout_width="0dp"
        android:background="#ffccee"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:name="com.example.myapplication.RightFragment"
        tools:layout="@layout/fragment_right_layout" />
</androidx.appcompat.widget.LinearLayoutCompat>

</LinearLayout>

3.在leftfargment编写动态加载代码:

两个布局中都有leftfragment,所以在leftfragment判断android是加载的哪个布局,然后做出响应逻辑.

所以FragmentActivity中,只用加载布局,无需逻辑代码.

public class FragmentActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_fragment);
    }

}

leftfargment代码:

public class LeftFragment extends Fragment {
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return getLayoutInflater().inflate(R.layout.fragment_left_layout,container,false);
    }

    //判断当前active布局中有没有右侧fragment,有的话代表是展现的双页布局
    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        Activity activity=getActivity();
        if(activity!=null){
            if(activity.findViewById(R.id.right_fragment)!=null){
                //双页模式,点击按钮刷新右侧fragment
                RightFragment fm =(RightFragment)getFragmentManager().findFragmentById(R.id.right_fragment);
                Button left_button=activity.findViewById(R.id.left_button);
                left_button.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        fm.refresh("我是来LeftFragment的测试文字");
                    }
                });

            }else{
                //单页模式,打开新的active
                Button left_button=activity.findViewById(R.id.left_button);
                left_button.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        Intent it = new Intent(Intent.ACTION_VIEW);
                        it.setData(Uri.parse("http://www.baidu.com"));
                        startActivity(it);
                    }
                });
            }
        }
    }
}

onCreateView是加载布局,是和active中的onCreate方法相同作用.onActivityCreated是在Activit创建过程中的代码,在里面判断FragmentActivity的布局是否包含right_fragment控件.在方法中使用getActivity()获取当前打开的active,然后还是老办法,通过findViewById(R.id.right_fragment)获取右侧组件,如果获取到,说明是平板,如果没有获取到说明是手机.

是平板的话,先创建rightFragment实例,然后通过leftfragment的按钮调用riaghtfragment的自定义方法refresh()来更新rightfragment的文字.

果是手机的话,点击按钮,打开另外一个action.

手机/平板最佳实践:新闻应用

略.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IT老卢

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值