Skip to main content

Fragment

Fragment可以当做是Activity的一个模块化组件。他拥有自己的生命周期、事件。并且可以在activity运行时动态加载和移除。

创建Fragment

创建Fragment,只需要继承Fragment类即可。

    package com.xiao.residue.fg;

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

import com.xiao.residue.hw.R;

/**
 * A simple {@link Fragment} subclass.
 */
public class frag_menu extends Fragment {


    public frag_menu() {
        // Required empty public constructor
    }


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

同样的,你可以为Fragment创建界面配置的xml文件。

<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="com.xiao.residue.fg.frag_menu">

    <!-- TODO: Update blank fragment layout -->
    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="@string/hello_blank_fragment" />

</FrameLayout>  

在Activity中使用Fragment

XML方式调用

首先编辑activity的xml文件

<?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:name="com.xiao.residue.fg.frag_menu"
        android:layout_width="0dp"
        android:layout_weight="1"
        android:id="@+id/c_frag"
        android:layout_height="match_parent"/>
</LinearLayout>  

然后需要修改Activity的继承为FragmentActivity

public class MainActivity extends FragmentActivity {  
...
}

注意在xml中创建的Fragment,不能在运行中移除

代码调用

一样,首先编辑xml文件,不同的是我们这次放置一个存放Fragment的容器而非Fragment。

<?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">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
    <FrameLayout
        android:id="@+id/c_frag"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</LinearLayout>  

然后在代码中对其进行加载:

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //Load Fragment to the container
        if(findViewById(R.id.c_frag)!=null){
            //Container exist
            if(savedInstanceState != null){
                //Resume from, fragment is already in.
                return;
            }
            //Create Frag_Menu
            frag_menu c_fm = new frag_menu();
            //Add it to activity

            //如果从intent使用putextra传递了参数,在Fragment中需要使用到,则要把参数传入
            c_fm.setArguments(getIntent().getExtras());
            //如果要自己定义参数传入,可以自己创建一个bundle来进行操作。
            Bundle args = new Bundle();
            args.putInt("pos",377);
            c_fm.setArguments(args);
            //创建一个事务,添加Fragment
            FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
            ft.add(R.id.c_frag,c_fm);
            ft.commit();

        }
    }
替换Fragment
ft = getSupportFragmentManager().beginTransaction();  
ft.replace(R.id.c_frag,c_fm);  
ft.commit();  

移除Fragment

ft = getSupportFragmentManager().beginTransaction();  
ft.remove(c_fm);  
ft.commit();  

Fragment和Activity通讯

Activity -> Fragment

Activity向Fragment传递信息,直接调用其public方法就好。

Fragment -> Activity

Fragment向Activity传递数据,需要使用事件的方法进行传递。

首先,创建接口

在类的内部创建一个interface来声明接口,并在内部创建这个接口变量。同时为了安全考虑,重写onAttach事件,检查接口是否被实现。

public class frag_menu extends Fragment {  
    //声明接口
    FragMenuListener fml;

    //创建一个监听接口,用于activity和fragment之间进行数据交互
    public interface FragMenuListener{
        public void onFragmentRemove();
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        //检查接口是否实现,没有实现就报错,防止不好定位错误
        try {
            fml = (FragMenuListener)activity;
        }catch (ClassCastException e){
            throw new ClassCastException(activity.toString()+" Should Implment the Method");
        }finally {

        }
    }
}

然后,在Activity实现接口

首先在类上需要声明实现接口,然后再其内部实现在接口中声明的方法。

public class MainActivity extends AppCompatActivity implements frag_menu.FragMenuListener{  
    @Override
    public void onFragmentRemove() {
        //do something
        }
    }
}

在Fragment中调用

我们以在Fragment中创建一个button为例。

    package com.xiao.residue.fg;


import android.app.Activity;  
import android.content.Context;  
import android.os.Bundle;  
import android.support.v4.app.Fragment;  
import android.view.LayoutInflater;  
import android.view.View;  
import android.view.ViewGroup;  
import android.widget.Button;  
import android.widget.TabHost;

import com.xiao.residue.hw.R;

/**
 * A simple {@link Fragment} subclass.
 */
public class frag_menu extends Fragment {  
    //声明接口
    FragMenuListener fml;

    //创建一个监听接口,用于activity和fragment之间进行数据交互
    public interface FragMenuListener{
        public void onFragmentRemove();
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        //检查接口是否实现,没有实现就报错,防止不好定位错误
        try {
            fml = (FragMenuListener)activity;
        }catch (ClassCastException e){
            throw new ClassCastException(activity.toString()+" Should Implment the Method");
        }finally {

        }
    }

    public frag_menu() {
        // Required empty public constructor
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {


        // Inflate the layout for this fragment
        View v = inflater.inflate(R.layout.fragment_frag_menu, container, false);
        Button b = (Button)v.findViewById(R.id.c_btn_fm_remove);
        b.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                fml.onFragmentRemove();
            }
        });
        return v;

    }

}