Android之碎片

一、碎片的概念(Fragment)

1、碎片:是一种可以嵌入在活动当中的UI片段,他能让程序更加合理和充分地利用大屏幕的空间。
2、碎片可以被认为是迷你型的活动,在一个活动中可以引用多个碎片,这样就可以充分利用活动界面空间

二、碎片的使用

2.1 碎片的创建和实现

1、新建一个左侧碎片布局left_fragment.xml和右侧碎片布局right_fragment,并添加一些控件
		<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
		    android:orientation="vertical"
		    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:layout_gravity="center_horizontal"
		        android:text="Button"
		        />
		</LinearLayout>
		<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
		    android:orientation="vertical"
		    android:background="#00ff00"
		    android:layout_width="match_parent"
		    android:layout_height="match_parent">
		    <TextView
		        android:layout_width="wrap_content"
		        android:layout_height="wrap_content"
		        android:layout_gravity="center_horizontal"
		        android:textSize="20sp"
		        android:text="This is right fragment"
		        />
		</LinearLayout>

2、分别创建一个LeftFragment类和RightFragment类,均继承Fragment类,重写onCreateView()方法,这样就创造了两个碎片

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

3、在主活动布局activity_main.xml中实现代码

    <fragment
        android:id="@+id/left_fragment"
        android:name="com.example.testfragment.LeftFragment"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight = "1"/>
    <fragment
        android:id="@+id/right_fragment"
        android:name="com.example.testfragment.RightFragment"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight = "1"/>
	android:name 用于显示指明要添加的碎片的类在包下所处的位置

2.2 动态地添加碎片

1、在上述操作的基础上,再新建一个another_right_fragment.xml布局文件,添加控件

		<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
		    android:orientation="vertical"
		    android:background="#ffff00"
		    android:layout_width="match_parent"
		    android:layout_height="match_parent">
		    <TextView
		        android:layout_width="wrap_content"
		        android:layout_height="wrap_content"
		        android:layout_gravity="center_horizontal"
		        android:textSize="20sp"
		        android:text="This is another right fragment"
		        />
		</LinearLayout>

2、新建一个AnotherRightFragment类作为另一个右侧碎片,继承Fragment,实现代码

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

3、在activity_main.xml中,实现代码

	    <fragment
	        android:id="@+id/left_fragment"
	        android:name="com,example.fragmenttest.LeftFragment"
	        android:layout_width="0dp"
	        android:layout_height="match_parent"
	        android:layout_weight = "1"/>
	    <FrameLayout
	        android:id="@+id/right_layout"
	        android:layout_width="0dp"
	        android:layout_height="match_parent"
	        android:layout_weight = "1">
	     </FrameLayout>
我们将平板中的右侧碎片换成一个FrameLayout布局

4、在主活动中,动态添加碎片

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button button = (Button)findViewById(R.id.button);
        button.setOnClickListener(this);
        replaceFragment(new RightFragment());//换前碎片,直接在屏幕上显示
    }
    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.botton:
                replaceFragment(new AnotherRightFragment());//换前碎片,点击按钮后显示
                break;
                default:
                    break;
        }
    }
    private void replaceFragment(Fragment fragment){
    	//2、构造placeFragment()方法,获取FragmentManager,在活动中调用getSupportFragmentManager()方法得到
        FragmentManager fragmentManager = getSupportFragmentManager();
        //3、开启一个事务,调用beginTransaction();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        //4、向容器内添加或替换碎片,用replace()实现
        fragmentTransaction.replace(R.id.right_layout,fragment);
        //5、调用commit()方法提交事务
        fragmentTransaction.commit();
    }
}
	1、创建一个replaceFragment()方法,在onCreate()方法中调用该方法并传入一个Fragment对象,动态添加对象的实例
	2、构造placeFragment()方法,获取FragmentManager,在活动中调用getSupportFragmentManager()方法得到
	3、开启一个事务,调用beginTransaction();
	4、向容器内添加或替换碎片,用replace()实现
	5、调用commit()方法提交事务

2.3 在碎片中模拟返回栈

在一般情况下,碎片中摁下Back键,程序会直接退出;如若想实现摁下back键回到碎片前一个碎片,即实现返回栈功能,则需要在replaceFragment()方法提交事务前添加下面这一行代码:

        fragmentTransaction.addToBackStack(null);
        //该方法可以接受一个名字用于描述返回栈的状态,此时摁下back键,程序会回到前一个碎片界面

三、碎片的声明周期

3.1 碎片的状态和回调

1、状态

  1. 运行状态 :当一个碎片可见时,且所关联的活动正处于运行状态时,该碎片也处于运行状态
  2. 暂停状态:当一个活动进入暂停状态,与他相关联的可见碎片就会进入暂停状态
  3. 停止状态:当一个活动进入停止状态,与它相关联的碎片就会进入停止状态
  4. 销毁状态:活动被销毁时,碎片也会跟着被销毁

2、回调方法

  1. onAttach():当碎片和活动建立关联时调用
  2. onCreateView():为碎片创建视图时调用
  3. onActivityCreated():确保与碎片相关联的活动一定已经创建完毕时调用
  4. onDestroyView():当与碎片关联的视图被移除时调用
  5. onDetach():当碎片与活动解除关联时调用

3、碎片完整的生命周期示意图:
在这里插入图片描述

四、动态加载布局的技巧

4.1 使用限定符

限定符:用于判断程序应该使用单页模式还是双页模式
举例实现:
1、修改activity_main.xml中的代码,只保留左侧碎片且让他充满整个父布局

		  <LinearLayout 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">
		   <fragment
		        android:id="@+id/left_fragment"
		        android:name="com.example.testfragment.LeftFragment"
		        android:layout_width="match_parent"
		        android:layout_height="match_parent"
		    />
		</LinearLayout>

2、在res目录下新建layout_large文件夹,在这个文件夹下新建一个布局,且名字也叫做activity_main.xml,代码如下:

		<?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"
		    xmlns:tools="http://schemas.android.com/tools"
		    android:layout_width="match_parent"
		    android:layout_height="match_parent"
		    tools:context=".MainActivity">
		    <fragment
		        android:id="@+id/left_fragment"
		        android:name="com.example.testfragment.LeftFragment"
		        android:layout_width="0dp"
		        android:layout_height="match_parent"
		        android:layout_weight="1"
		        />
		    <fragment
		        android:id="@+id/right_fragment"
		        android:name="com.example.testfragment.RightFragment"
		        android:layout_width="0dp"
		        android:layout_height="match_parent"
		        android:layout_weight="1"/>
		</LinearLayout>

3、通过比较,发现第一个同名布局文件只包含了一个碎片,即单页模式;第二个同名布局文件包含了两个碎片,即双页模式。其中layout-large文件夹下的large是个限定符,那些屏幕被认为时large的设备就会自动加载layout-large文件夹下的布局,反之也是一样。因此若是在手机模拟器上运行,则会引用第一个布局文件,若是在平板模拟器上运行,则会引用第二个布局文件
4、Android系统中一些常见的限定符参考博客 常见限定符

4.2 最小宽度限定符的使用

最小宽度限定符允许我们对屏幕的宽度指定一个最小值(以dp为基本单位),然后以这个最小值为临界点,屏幕宽度大于这个值的设备就加载一个布局,反之就加载小于这个宽度的布局,具体设置方法,在layout文件后面加上后缀-sw600dp(以600dp为界限)即可。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值