Android入门(6)| 碎片

碎片是一种可以镶嵌在活动中的UI片段,它可以让程序简单合理的利用屏幕的大空间。所以碎片经常用于HD应用的开发。这次我们就来看看碎片的简单用法吧。


12070003-630e5eaf865203cd.png
本节目录

静态添加碎片

首先还是新建一个空项目,然后添加两个布局,分别叫做right_layout和left_layout,在这里面修改代码:

<?xml version="1.0" encoding="utf-8"?>
<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:text="button"/>

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

    <TextView
        android:id="@+id/text_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello fragment"/>

</LinearLayout>

然后我们需要新建LeftFragment和RightFragment类,并且让它们继承自Fragment类,注意在这里我们选择的Fragment类是support-v4库中的Fragment,接着修改代码:

package com.example.yzbkaka.fragmenttest;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

//LeftFragment
public class LeftFragment extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle saveInstanceState){
        View view = inflater.inflate(R.layout.left_layout,container,false);
        return view;
    }
}
package com.example.yzbkaka.fragmenttest;

import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

//RightFragment
public class RightFragment extends Fragment {
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle saveInstanceState){
        View view = inflater.inflate(R.layout.right_layout,container,false);
        return view;
    }
}

在新建类时我们直接是调用inflater的inflate()方法来将布局调入。

最后我们就可以将碎片加入到主布局当中了:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <fragment
        android:id="@+id/left_fragment"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:name="com.example.yzbkaka.fragmenttest.LeftFragment"/>

    <fragment
        android:id="@+id/right_fragment"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:name="com.example.yzbkaka.fragmenttest.RightFragment"/>

</LinearLayout>

注意我们使用android:name这个属性是为了将之前写好的碎片的类导入,但是这里必须要将类的包名也加上才行。

最后就是启动程序了,因为碎片主要是给平板这样的大屏幕设备使用的,所以这里我们再创建一个新的平板虚拟设备,设备下载完成之后我们就可以启动了。

动态添加碎片

碎片不仅仅可以静态的添加,还可以很高端的动态添加进活动当中,我们就一起来看一看吧。

接着使用上面的项目,我们要新建一个布局,叫做another_right_layout,同样我们也需要为这个布局新建一个类,叫做AnotherRightFragment:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" 
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    
    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent" 
        android:layout_gravity="center_horizontal"
        android:text="This is another rightfragment"/>

</LinearLayout>
package com.example.yzbkaka.fragmenttest;


import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;


public class AnotherRightFragment extends Fragment {
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle saveInstanceState){
        View view = inflater.inflate(R.layout.another_right_layout,container,false);
        return view;
    }
}

接着我们就来修改主布局当中的代码:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <fragment
        android:id="@+id/left_fragment"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:name="com.example.yzbkaka.fragmenttest.LeftFragment"/>

    <FrameLayout
        android:id="@+id/right_layout"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1">
    </FrameLayout>

</LinearLayout>

由于我们这里是要动态的添加碎片,所以我们就先不在布局中将碎片加上,而是先添加一个帧布局,这个布局就是默认将控件放在左上角。接着我们修改主代码:

package com.example.yzbkaka.fragmenttest;

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

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.button:
                replaceFragment(new AnotherRightFragment());
                break;
            default:
                break;
        }
    }

    private void replaceFragment(Fragment fragment) {
        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction transaction = fragmentManager.beginTransaction();
        transaction.replace(R.id.right_layout, fragment);
        transaction.addToBackStack(null);
        transaction.commit();
    }
}

可以看到我们使用的是replaceFragment()的方法来动态的添加碎片的,这里添加碎片主要是分为3步:
第一步:先用getSupportFragmentManager()方法获取一个FragmentManager对象,再通过它的beginTransaction()获取一个FragmentTransaction的实例,开启一个事务。
第二步:向容器内部添加或者替换碎片,这里使用的是replace()方法来实现,它需要传入两个参数,第一个参数是要要传入容器的id,这里我们传入的是之前定义好的FrameLayout的id;第二个参数是等待添加的碎片的实例。
第三步:使用commit()的方法来提交事务,完成添加。

这里我们多使用了一个addToBackStack()的方法,它的作用就是当我们在手机上按下back键的时候,就会回到上一个碎片当中,如果不使用,则会直接退出程序。这个方法一般是传入null来当参数就可以了。

碎片与活动之间通信

1.在活动中获取碎片

在活动中可以通过调用FragmentManager的findFragmentById()方法来得到相应碎片的实例,继而可以调用碎片里的方法。

RightFragment rightFragment = (RightFragment) getSupportFragmentManager().findFragmentById()(R.id.right_fragment);

2.在碎片中获取活动

每一个碎片都可以通过调用getActivity()方法来得到和当前活动相关联的活动实例:

MainActivity activity = (MainActivity) getActivity();

3.碎片与碎片之间的通信

碎片之间交流的主要思路就是在一个碎片中先获取到与它相关联的活动,然后再通过这个活动来或的其他的碎片即可。

碎片的生命周期

由于碎片是依附于活动生存的,所以碎片的生命周期是和活动的生命周期相似的,也是分为了4种状态:运行状态、暂停状态、停止状态和销毁状态,但是在一些细小的地方碎片和活动会有一些不同。

12070003-da53184cb4c14067.png
碎片的生命周期

从图中我们可以看到碎片从被创建到被销毁需要进行11个回调方法,相比于活动来说是多了5个,即: onAttach()、onCreateView()、onActivityCreated()、onDestroyView()和onDetach(),下面来具体介绍这5个回调方法:

  • onAttach()
    当碎片与活动相关联的时候调用。
  • onCreateView()
    当为碎片创建视图的时候调用。
  • onActivityCreated()
    当与碎片相关联的活动创建的时候调用。
  • onDestroyView()
    当与碎片相关联的视图销毁的时候调用。
  • onDetach()
    当碎片与其相关联的活动解除关联的时候调用。

所以我们简单的将图片概括出来就是:

1.当打开界面时:onAttach()->onCreate()->onCreateView()->onActivityCreated()
->onStart()->onResume()
2.当按下主屏幕键时:onPause()->onStop()
3.当重新回到界面时:onStart()->onResume()
4.当按下back键时:onPause()->onStop()->onDestroyView()->onDestroy()->onDetach()

猜你喜欢

转载自blog.csdn.net/weixin_33923762/article/details/87554257
今日推荐