Fragment
Android是在Android 3.0 (API level 11)开始引入Fragment的。
可以把Fragment想成Activity中的模块,这个模块有自己的布局,有自己的生命周期,单独处理自己的输入,在Activity运行的时候可以加载或者移除Fragment模块。
可以把Fragment设计成可以在多个Activity中复用的模块。
Android是在Android 3.0 (API level 11)开始引入Fragment的。
可以把Fragment想成Activity中的模块,这个模块有自己的布局,有自己的生命周期,单独处理自己的输入,在Activity运行的时候可以加载或者移除Fragment模块。
可以把Fragment设计成可以在多个Activity中复用的模块。
当第一次绘制Fragment的UI时系统调用onCreateView()方法,必须返回一个View,如果Fragment不提供UI也可以返回null。
注意,如果继承自ListFragment,onCreateView()默认的实现会返回一个ListView,所以不用自己实现。
注意,如果继承自ListFragment,onCreateView()默认的实现会返回一个ListView,所以不用自己实现。
Fragment有两种加载方式:一种是在Activity的layout中使用标签<fragment>声明;另一种方法是在代码中把它加入到一个指定的ViewGroup中。
另外,Fragment它可以并不是Activity布局中的任何一部分,它可以是一个不可见的部分。这部分内容先略过。
加载方式1:通过Activity的布局文件将Fragment加入Activity
在Activity的布局文件中,将Fragment作为一个子标签加入即可。
另外,Fragment它可以并不是Activity布局中的任何一部分,它可以是一个不可见的部分。这部分内容先略过。
加载方式1:通过Activity的布局文件将Fragment加入Activity
在Activity的布局文件中,将Fragment作为一个子标签加入即可。
Fragment 和Activity之间的在通信
1.在Fragment 中声明一个接口
2.在Activity中实现Fragment声明的接口
3.在Fragment中声明一个接口对象
4.在Fragment的生命周期Onattch方法中判断当前Activity是否实现了此
Fragment中声明的接口。如果已经实现,就把当前Activity转化为接口对象。
5.调用Activity中实现的方法。=》(接口对象.方法名)
(谨记上述的步骤,有助于理解)
下面我们就通过代码具体的了解Fragment
首先建立一个包,专门存放Fragment的文件:
依据下图的步骤来新建需要的Fragment。
下面就是Fragment简单的引用
Fragment1Activity
package com.jerehedu.jerduech07;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.app.AppCompatActivity;
import com.jerehedu.jerduech07.fragment.FirstFragment;
import com.jerehedu.jerduech07.fragment.LeftFragment;
import com.jerehedu.jerduech07.fragment.SecondFragment;
public class Fragment1Activity extends AppCompatActivity implements LeftFragment.OnFragmentInteractionListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fragment1);
getSupportActionBar().hide();
}
@Override
public void changeFragment(int which) {
if(which==1){
Fragment fragment1=new FirstFragment();
getSupportFragmentManager().beginTransaction().replace(R.id.fl,fragment1)
.commit();
}else if (which==2){
Fragment fragment2=new SecondFragment();
getSupportFragmentManager().beginTransaction().replace(R.id.fl,fragment2).commit();
}
}
}
对应的布局文件:Fragment1_Layout
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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.jerehedu.jerduech07.Fragment1Activity">
<fragment
android:layout_width="match_parent"
android:layout_height="100dp"
android:name="com.jerehedu.jerduech07.fragment.TopFragment"
android:id="@+id/top_fragment"/>
<!--对fragment静态的引用-->
<fragment
android:layout_width="100dp"
android:layout_height="match_parent"
android:id="@+id/left_fragment"
android:name="com.jerehedu.jerduech07.fragment.LeftFragment"
android:layout_below="@+id/top_fragment" />
<!--<fragment-->
<!--android:layout_width="300dp"-->
<!--android:layout_height="match_parent"-->
<!--android:id="@+id/main_fragment"-->
<!--android:name="com.jerehedu.jerduech07.fragment.MainFragment"-->
<!--android:layout_below="@+id/top_fragment"-->
<!--android:layout_toEndOf="@+id/left_fragment" />-->
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/fl"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"
android:layout_below="@+id/top_fragment"
android:layout_toEndOf="@+id/left_fragment">
</FrameLayout>
</RelativeLayout>
接下来的三个Fragment文件是Fragment1activity内所引用到的所有文件:
(1)
FristFragment:
package com.jerehedu.jerduech07.fragment;
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.TextView;
import com.jerehedu.jerduech07.R;
/**
* A simple {@link Fragment} subclass.
*/
public class FirstFragment extends Fragment {
public FirstFragment() {
// 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_first, container, false);
//将静态布局转化为V
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Bundle bundle= getArguments();
if (bundle!=null){
int ch= bundle.getInt("channel");
TextView tv= (TextView)getView().findViewById(R.id.tv);
tv.setText(ch+"");
}
}
}
FristFragment文件对应的布局文件:
<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.jerehedu.jerduech07.fragment.FirstFragment">
<!-- TODO: Update blank fragment layout -->
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:textSize="30sp"
android:layout_gravity="center"
android:text="我是fragment1"
android:background="#b9f2c0"
android:id="@+id/tv"/>
</FrameLayout>
(2)SecondFragment
package com.jerehedu.jerduech07.fragment;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.jerehedu.jerduech07.R;
/**
* A simple {@link Fragment} subclass.
*/
public class SecondFragment extends Fragment {
public SecondFragment() {
// 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_second, container, false);
}
}
其对应的布局文件如下:
<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.jerehedu.jerduech07.fragment.SecondFragment">
<!-- TODO: Update blank fragment layout -->
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="我是第二个fragment"
android:layout_gravity="center"
android:textSize="20sp"
android:gravity="center"
android:id="@+id/f2"/>
</FrameLayout>
(3)
LeftFragment:
Fragment1Actuvity实现了该碎片的接口以及对应的方法
package com.jerehedu.jerduech07.fragment;
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.Toast;
import com.jerehedu.jerduech07.R;
import com.jerehedu.jerduech07.fragmentcallback.OneFragment;
/**
* A simple {@link Fragment} subclass.
*/
public class LeftFragment extends Fragment {
private OnFragmentInteractionListener mListener;
private Fragment fragment1=new FirstFragment();
private Fragment fragment2 = new SecondFragment();
public LeftFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view=inflater.inflate(R.layout.fragment_left, container, false);
Button bt1= (Button) view.findViewById(R.id.bt1);
Button bt2= (Button) view.findViewById(R.id.bt2);
Button bt3= (Button) view.findViewById(R.id.bt3);
Button bt4= (Button) view.findViewById(R.id.bt4);
Button bt5= (Button) view.findViewById(R.id.bt5);
Button bt6= (Button) view.findViewById(R.id.bt6);
bt1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(getContext(), "点击了按钮1", Toast.LENGTH_SHORT).show();
//new 一个Fragment,不需要写this
FragmentManager fm=getFragmentManager();
FragmentTransaction fr=fm.beginTransaction();
fr.replace(R.id.fl,fragment1);
fr.commit();//提交
}
});
bt2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(getContext(), "点击了第二个那妞", Toast.LENGTH_SHORT).show();
FragmentManager fm2 = getFragmentManager();
FragmentTransaction fr2 = fm2.beginTransaction();
fr2.replace(R.id.fl, fragment2);
fr2.commit();
}
});
bt3.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mListener.changeFragment(1);
}
});
bt4.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mListener.changeFragment(2);
}
});
bt5.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (fragment1!=null&&!fragment1.isHidden()){
getFragmentManager().beginTransaction().hide(fragment1).commit();
}
}
});
bt6.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (fragment1 != null && fragment1.isHidden())
getFragmentManager().beginTransaction().show(fragment1).commit();
}
});
return view;
}
@Override
public void onAttach(Context context) {
if (context instanceof OneFragment.OnFragmentInteractionListener){
mListener= (OnFragmentInteractionListener) context;
}else{
throw new RuntimeException(context.toString()
+"must implement OnFragmentInteractionListener");
}
}
public interface OnFragmentInteractionListener{
void changeFragment(int which);
}
}
其对应的布局文件
<RelativeLayout 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="#d4f905"
tools:context="com.jerehedu.jerduech07.fragment.LeftFragment">
<!-- TODO: Update blank fragment layout -->
<!--<TextView-->
<!--android:layout_width="match_parent"-->
<!--android:layout_height="match_parent"-->
<!--android:text="LeftFragment"-->
<!--android:background="#ffff04"-->
<!--android:textColor="#ffffff"-->
<!--android:gravity="center"-->
<!--android:textSize="30sp"/>-->
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="第一个Fragment"
android:textSize="10sp"
android:id="@+id/bt1"
/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="第二个Fragment"
android:textSize="10sp"
android:id="@+id/bt2"
android:layout_gravity="center_horizontal|top"
android:layout_below="@+id/bt1"
android:layout_alignParentStart="true" />
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="第一个Back"
android:textSize="10sp"
android:id="@+id/bt3"
android:layout_below="@+id/bt2"
android:layout_alignParentStart="true" />
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="第二个Back"
android:textSize="10sp"
android:id="@+id/bt4"
android:layout_below="@+id/bt3"
android:layout_alignParentStart="true" />
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/bt5"
android:text="隐藏Fragment1"
android:layout_below="@+id/bt4"
android:layout_alignParentStart="true" />
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/bt6"
android:text="显示Fragment1"
android:layout_below="@+id/bt5"
android:layout_alignParentStart="true" />
</RelativeLayout>
运行结果如下:
Fragment2Activity文件:
package com.jerehedu.jerduech07;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.app.AppCompatActivity;
import com.jerehedu.jerduech07.fragment.FirstFragment;
import com.jerehedu.jerduech07.fragment.SecondFragment;
import com.jerehedu.jerduech07.fragmentcallback.OneFragment;
public class Fragment2Activity extends AppCompatActivity implements OneFragment.OnFragmentInteractionListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fragment2);
}
@Override
public void changeFragment(int which) {
if (which==1){
Fragment fragment1=new FirstFragment();
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.fl2, fragment1)
.commit();
}else if (which==2){
Fragment fragment2=new SecondFragment();
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.fl2, fragment2)
.commit();
}
}
}
其对应的布局文件为:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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=".Fragment2Activity">
<fragment
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/one_Fragment"
android:name="com.jerehedu.jerduech07.fragmentcallback.OneFragment"/>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/fl2"
android:layout_below="@+id/one_Fragment">
</FrameLayout>
</RelativeLayout>
所用到的其他Fragment文件见Fragment1Activity
运行结果如下:
Fragment的生命周期:
onAttach () Fragment被附加到Activity的时,调用此函数,在这个方法中可以获得宿主Activity。
onCreate () Fragment被创建的时,调用此函数。
onCreateView () Fragment的布局加载时,调用此函数。
onActivityCreated () 当宿主Activity启动完毕后,调用此函数。
onStart () 启动Fragment时,调用此函数。
onResume () Fragment恢复时,调用此函数。
onPause () Fragment暂停时,调用此函数。
onStop() Fragment停止时,调用此函数。
onDestroyView() 销毁Fragment中的View控件时,调用此函数。
onDestroy() 销毁Fragment时,调用此函数。
onDetach() Fragment从Activity脱离时,调用此函数
下面俩个实例演示了Fragment和Activity各自生命周期的关系,以及运行的规律:
Fragment:生命周期
package com.jerehedu.jerduech07.fragment;
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.jerehedu.jerduech07.R;
/**
* A simple {@link Fragment} subclass.
*/
public class LifeFragment extends Fragment {
private TextView tv;
public LifeFragment() {
// Required empty public constructor
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
Log.d("====LifeFragment===","onAttach");
//Fragment附加到Activity
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d("====LifeFragment===", "onCraet");
//Fragment被创建
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view=inflater.inflate(R.layout.fragment_life,container,false);
return view;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Log.d("====LifeFragment===", "onActivityCreated");
}
@Override
public void onStart() {
super.onStart();
Log.d("====LifeFragment===", "onStart");
}
@Override
public void onResume() {
super.onResume();
Log.d("====LifeFragment===", "onResume");
}
@Override
public void onPause() {
super.onPause();
Log.d("====LifeFragment===", "onPause");
}
@Override
public void onStop() {
super.onStop();
Log.d("====LifeFragment===", "onStop");
}
@Override
public void onDestroyView() {
super.onDestroyView();
Log.d("====LifeFragment===", "onDestroyView");
}
@Override
public void onDestroy() {
super.onDestroy();
Log.d("====LifeFragment===", "onDestroy");
}
@Override
public void onDetach() {
super.onDetach();
Log.d("====LifeFragment===", "onDetach");
//和Attach相反,从Activity脱离
}
}
package com.jerehedu.jerduech07;
import android.support.v4.app.Fragment;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import com.jerehedu.jerduech07.fragment.FirstFragment;
import com.jerehedu.jerduech07.fragment.LifeFragment;
public class FragmentLifeActivity extends AppCompatActivity {
final Fragment fragment=new LifeFragment();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fragment_life);
getSupportActionBar().hide();
getSupportFragmentManager().beginTransaction()
.replace(R.id.life_frame, fragment).commit();
final Button bt1= (Button) findViewById(R.id.bt_remove);
Button bt2= (Button) findViewById(R.id.bt_replace);
Button bt3= (Button) findViewById(R.id.bt_hide);
Button bt4= (Button) findViewById(R.id.bt_show);
bt1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (fragment!=null) {
getSupportFragmentManager().beginTransaction()
.remove(fragment).commit();
}
}
});
bt2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (fragment!=null) {
Fragment fragment1=new FirstFragment();
//捆绑数据 Bundle
Bundle bundle=new Bundle();
bundle.putInt("channel",66);
fragment1.setArguments(bundle);
//赋值
getSupportFragmentManager().beginTransaction()
.replace(R.id.life_frame, fragment1).commit();
}
}
});
bt3.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (fragment!=null&&!fragment.isHidden()){
getSupportFragmentManager().beginTransaction().hide(fragment).commit();
}
}
});
bt4.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (fragment!=null&&fragment.isHidden()){
getSupportFragmentManager().beginTransaction().show(fragment).commit();
}
}
});
getSupportFragmentManager().beginTransaction()
.replace(R.id.life_frame, fragment).commit();
Log.d("====Activity===","onCreat");
}
@Override
protected void onStart() {
super.onStart();
Log.d("====Activity===", "onStart");
}
@Override
protected void onRestart() {
super.onRestart();
Log.d("====Activity===", "onCreat");
}
@Override
protected void onResume() {
super.onResume();
Log.d("====Activity===", "onResume");
}
@Override
protected void onPause() {
super.onPause();
Log.d("====Activity===", "onPause");
}
@Override
protected void onStop() {
super.onStop();
Log.d("====Activity===", "onStop");
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.d("====Activity===", "onDestroy");
}
}
1.点击运行后各个生命周期运行的情况:
2.点击回退键时各个生命周期运行状况
3.点击HOME键各个生命周期运行状况:
且该程序还可实现下面的界面:
点击按钮remove --fragment
点击 replace --fragment:
hide--fragment
show --fragment: