简单探究Fragment

简单探究Fragment

Fragment是什么

Fragment (碎片)是一种可以嵌入在活动中的UI片段它能让程序更加合理和充分的利用大屏幕的空间,因此平板上应用的非常广泛。Fragment和活动非常相似,同样包含布局,有自己的生命周期。你甚至可以将碎片理解成一个迷你型的活动。

Fragment生命周期

Fragment必须是依存与Activity而存在的,因此Activity的生命周期会直接影响到Fragment的生命周期。官网这张图很好的说明了两者生命周期的关系:
这里写图片描述
可以看到Fragment比Activity多了几个额外的生命周期回调方法:
onAttach():当Fragment与Activity发生关联时调用。
onCreateView():创建该Fragment的视图
onActivityCreated():当Activity的onCreate方法返回时调用
onDestoryView():与onCreateView想对应,当该Fragment的视图被移除时调用
onDetach():与onAttach相对应,当Fragment与Activity关联被取消时调用

介绍完Fragment,现在我们来讲一讲它的应用

Fragment的应用

Fragment静态加载怎么用

这是使用Fragment最简单的一种方式,把Fragment当成普通的控件,直接写在Activity的布局文件中。

下面展示一个例子(我使用2个Fragment作为Activity的布局):

FirstFragment的布局文件:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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"
    android:background="#999999"
    tools:context=".test.FirstFragment">

    <!-- TODO: Update blank fragment layout -->
    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="My Firat Fragment"
        android:textSize="30dp"
        android:gravity="center"/>

</FrameLayout>

SecondFragment的布局文件:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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"
    android:background="#f9c3c3"
    tools:context=".test.SecondFragment">

    <!-- TODO: Update blank fragment layout -->
    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="My Second Fragment"
        android:textSize="30dp"
        android:gravity="center" />

</FrameLayout>

两个fragment用不同颜色,便于区分

Activity的布局文件:

<?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"
    android:orientation="horizontal"
    tools:context=".test.TestActivity">

    <fragment
        android:id="@+id/my_first_fragment"
        android:layout_weight="1"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:name="com.example.a17825.paopao.test.FirstFragment"/>
    <fragment
        android:id="@+id/my_second_fragment"
        android:layout_weight="1"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:name="com.example.a17825.paopao.test.SecondFragment"/>
</LinearLayout>

把Fragment当成普通的View一样声明在Activity的布局文件中,然后所有控件的事件处理等代码都由各自的Fragment去处理
这里要注意,fragment一定要写id,不然无法运行,android:name=”“寻找你创建的Fragment文件,下面看看效果图:
这里写图片描述

Fragment动态加载怎么用

上面已经演示了,最简单的使用Fragment的方式,下面介绍如何动态的添加、更新、以及删除Fragment

在讲Fragment动态加载先看一下Fragment常用的三个类:
android.app.Fragment 主要用于定义Fragment

android.app.FragmentManager 主要用于在Activity中操作Fragment

android.app.FragmentTransaction 保证一些列Fragment操作的原子性,熟悉事务这个词,一定能明白

为了动态使用Fragment,我们修改一下Actvity的布局文件,中间使用一个FrameLayout,下面添加两个按钮:

<?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"
    android:orientation="vertical"
    tools:context=".test.TestActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        <Button
            android:layout_weight="1"
            android:id="@+id/test_button1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="First Fragment"
            android:textSize="20dp"/>
        <Button
            android:layout_weight="1"
            android:id="@+id/test_button2"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="First Fragment"
            android:textSize="20dp"/>
    </LinearLayout>
    <FrameLayout
        android:layout_weight="1"
        android:id="@+id/test_fragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"></FrameLayout>
</LinearLayout>

下面主Activity:

package com.example.a17825.paopao.test;

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

import com.example.a17825.paopao.R;
public class TestActivity extends AppCompatActivity implements View.OnClickListener{
    private Button btn1;
    private Button btn2;

    private FirstFragment firstFragment;
    private SecondFragment secondFragment;

    private FragmentManager fragmentManager;
    private FragmentTransaction fragmentTransaction;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test);
        bindID();
        fragmentManager=getFragmentManager();
    }

    private void bindID() {
        btn1=findViewById(R.id.test_button1);
        btn2=findViewById(R.id.test_button2);
        btn1.setOnClickListener(this);
        btn2.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        fragmentTransaction=fragmentManager.beginTransaction();
        switch (v.getId()){
            case R.id.test_button1:
                if(firstFragment==null){
                    firstFragment=new FirstFragment();
                }
                fragmentTransaction.replace(R.id.test_fragment,firstFragment);
                break;
            case R.id.test_button2:
                if(secondFragment==null){
                    secondFragment=new SecondFragment();
                }
                fragmentTransaction.replace(R.id.test_fragment,secondFragment);
                break;
            default:
                break;
        }
        fragmentTransaction.commit();
    }
    }

效果图由于博主无法录制GIF,所以没有,效果简而言之就是,单击按钮fragment会进行相应切换
下面分别是单击按钮1和按钮2的效果图:
这里写图片描述
这里写图片描述

ViewPager+Fragment实现页卡滑动

适配器实现——FragmentPagerAdapter

public class FragAdapter extends FragmentPagerAdapter {  

    private List<Fragment> fragments;  

    public FragAdapter(FragmentManager fm,List<Fragment> fragments) {  
        super(fm);  
        // TODO Auto-generated constructor stub  
        this.fragments=fragments;  
    }  

    @Override  
    public Fragment getItem(int arg0) {  
        // TODO Auto-generated method stub  
        return mFragments.get(arg0);  
    }  

    @Override  
    public int getCount() {  
        // TODO Auto-generated method stub  
        return mFragments.size();  
    }  

}

二个Fragment类

第一个Fragment类:
<?xml version="1.0" encoding="utf-8"?>  
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    android:layout_width="match_parent"  
    android:layout_height="match_parent"  
    android:background="#ffffff"  
    android:orientation="vertical" >  

</LinearLayout> 

Java代码:

public class Fragment1 extends Fragment {  

    @Override  
    public View onCreateView(LayoutInflater inflater, ViewGroup container,  
            Bundle savedInstanceState) {  
        // TODO Auto-generated method stub  
        View view=inflater.inflate(R.layout.layout1, container, false);  
        return view;  
    }  

}  
第二个Fragment类:
<?xml version="1.0" encoding="utf-8"?>  
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    android:layout_width="match_parent"  
    android:layout_height="match_parent"  
    android:background="#ffff00"  
    android:orientation="vertical" >  


</LinearLayout> 

java代码:

public class Fragment2 extends Fragment {  

    @Override  
    public View onCreateView(LayoutInflater inflater, ViewGroup container,  
            Bundle savedInstanceState) {  
        // TODO Auto-generated method stub  
        View view=inflater.inflate(R.layout.layout2, container, false);  
        return view;  
    }  

}  

主activity实现

核心代码:

public class MainActivity extends FragmentActivity {  

    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.activity_main);  

        //构造适配器  
        List<Fragment> fragments=new ArrayList<Fragment>();  
        fragments.add(new Fragment1());  
        fragments.add(new Fragment2());   
        FragAdapter adapter = new FragAdapter(getSupportFragmentManager(), fragments);  

        //设定适配器  
        ViewPager vp = (ViewPager)findViewById(R.id.viewpager);  
        vp.setAdapter(adapter);  
    }  

} 

Fragment通信

fragment向activity传值:

创建一个fragment,布局文件:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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=".BlankFragment1">

    <Button
        android:id="@+id/chat_btn"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="联系人"/>
    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:textSize="50dp"
        android:text="联系人" />

</FrameLayout>

Java文件中,由于fragment没有findViewById()方法,所以onCreateView()要进行改变:

public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_blank_fragment1, container, false);
    }

改为:

public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
       View view=inflater.inflate(R.layout.fragment_blank_fragment1, container, false);
       button=view.findViewById(R.id.chat_btn);
        return view;
    }

给按钮添加单击事件:

button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
            //创建Main3Activity
                Main3Activity main3Activity= (Main3Activity) getActivity();
            }
        });

Activity布局文件添加TextView接受fragment的传值:

<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"
    android:orientation="vertical"
    tools:context=".Main3Activity">
<TextView
        android:id="@+id/title_tv"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:gravity="center"/>
    <fragment
        android:id="@+id/main_fragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:name="com.example.a17825.paopao.BlankFragment1"/>
        </LinearLayout>

在Java文件中创建一个方法,设置TextView的内容:

public void modifyTitle(String title) {
    title_tv.setText(title);
    }

然后在fragment的Java文件的按钮单击事件中调用该方法:

main3Activity.modifyTitle("我是联系人fragment");

运行结果:
这里写图片描述
单击按钮:
这里写图片描述

实现Activity传值Fragment
类似Activity之间的通信intent,这里用Bundle

Activity代码:

Bundle bundle=new Bundle();  
        bundle.putString("name","我是Activity");  
        oneFragment.setArguments(bundle);  

Fragment代码:

Bundle bundle = getArguments();  
       String name = bundle.getString("name");  
       button.setText(name);  

猜你喜欢

转载自blog.csdn.net/source_sc/article/details/80586001