Fragment的第一种声明方式
直接在布局中声明即可
1在activity_main中定义fragment
name属性指定的是一个我们自己定义的Fragment
<?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.example.fragment2.Fragment1"
android:id="@+id/list"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="match_parent" />
<fragment android:name="com.example.fragment2.Fragment2"
android:id="@+id/viewer"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="match_parent" />
</LinearLayout>
2定义一个类继承Fragment
package com.example.fragment2;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
//定义Fragment 理解为是Activity的一部分
public class Fragment1 extends Fragment {
//当系统第一次画ui的时候调用 通过这个方法可以让fragment显示自己的布局内容
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
//通过打气筒将一个布局转换成view
View view=inflater.inflate(R.layout.fragment1, null);
return view;
}
}
package com.example.fragment2;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class Fragment2 extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view=inflater.inflate(R.layout.fragment2, null);
return view;
}
}
3定义每一个fragment的布局
fragment1.xml
<?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:orientation="vertical" >
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="这是fragment1中的内容"
android:textColor="#ff0000"
/>
</LinearLayout>
fragment2.xml
<?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:orientation="vertical" >
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="这是fragment2中的内容"
android:textColor="#000000"
/>
</LinearLayout>
这种方式在开发中几乎不用,了解即可。
Fragment的第二种声明方式
动态添加fragment
实现在横竖屏时加载不同的Fragment
1 定义Fragment
Fragment1.java
package com.example.dyncfragment;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class Fragment1 extends Fragment {
//显示Fragment自己要显示的内容
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view=inflater.inflate(R.layout.fragment1, null);
return view;
}
}
Fragment2.java
package com.example.dyncfragment;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class Fragmen2 extends Fragment {
//显示Fragment自己要显示的内容
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view=inflater.inflate(R.layout.fragment2, null);
return view;
}
}
2.定义Fragment1和Fragment2的布局
fragment1.xml
<?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:orientation="vertical" >
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="这是竖屏中的内容"
android:textColor="#ff0000"
/>
</LinearLayout>
fragment2.xml
<?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:orientation="vertical" >
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="这是横屏中的内容"
android:textColor="#000000"
/>
</LinearLayout>
3 在MainActivity中动态加载
package com.example.dyncfragment;
import android.app.Activity;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.WindowManager;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//[1]获取手机的分辨率
WindowManager wm=(WindowManager) getSystemService(WINDOW_SERVICE);
int width=wm.getDefaultDisplay().getWidth();
int height=wm.getDefaultDisplay().getHeight();
//[2]判断横竖屏
//[3]获取Fragment管理者 通过上下文直接获取
FragmentManager fragmentManager=getFragmentManager();
FragmentTransaction beginTransation=fragmentManager.beginTransaction();//开启事务
if(height>width){
//说明是竖屏 加载一个fragment android.R.id.content 代表当前手机的窗体
beginTransation.replace(android.R.id.content, new Fragment1());
}else{
//说明是横屏
beginTransation.replace(android.R.id.content, new Fragment2());
}
//[4]最后一步 记得提交 commit
beginTransation.commit();
}
}
动态替换fragment的步骤
一、获取Fragment的管理者
FragmentManager fragmentManager=getFragmentManager();
二、开启一个事务
FragmentTransaction beginTransation=fragmentManager.beginTransaction();//开启事务
三、提交事务
beginTransation.commit();
案例:用动态替换的方式模拟微信主界面
1activity_main中定义fragment要动态替换的布局
<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.example.wx.MainActivity" >
<!--fragment要动态替换的布局-->
<LinearLayout
android:id="@+id/ll_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
></LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:orientation="horizontal"
>
<Button
android:id="@+id/btn_wx"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="微信"
/>
<Button
android:id="@+id/btn_contact"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="通讯录"
/>
<Button
android:id="@+id/btn_discover"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="发现"
/>
<Button
android:id="@+id/btn_me"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="我"
/>
</LinearLayout>
</RelativeLayout>
2.定义四个fragment的布局
fragment_wx.xml
<?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:orientation="vertical" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="我是微信模块的内容"
/>
<Button
android:id="@+id/btn_test"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="测试"
/>
</LinearLayout>
fragment_contect.xml
<?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:orientation="vertical" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp"
android:text="我是通讯录模块的内容"
/>
</LinearLayout>
fragment_discover.xml
<?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:orientation="vertical" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp"
android:text="我是发现模块的内容"
/>
</LinearLayout>
fragment_me.xml
<?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:orientation="vertical" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="22sp"
android:textColor="#ff0000"
android:text="我是我的模块的内容"
/>
</LinearLayout>
3定义Fragment.java
WxFragment.java
public class WxFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view=inflater.inflate(R.layout.fragment_wx, null);
//测试按钮的点击事件
view.findViewById(R.id.btn_test).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
System.out.println("hahahahahah");
}
});
return view;
}
}
ContactFragment.java
public class ContactFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view=inflater.inflate(R.layout.fragment_contact, null);
return view;
}
}
DiscoverFragment.java
public class DiscoverFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view=inflater.inflate(R.layout.fragment_discover, null);
return view;
}
}
MeFragment.java
public class MeFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view=inflater.inflate(R.layout.fragment_me, null);
return view;
}
}
4在MainActivity中动态替换Fragment
package com.example.wx;
import android.app.Activity;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class MainActivity extends Activity implements OnClickListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//[1]找到按钮
Button btn_wx=(Button) findViewById(R.id.btn_wx);
Button btn_contact=(Button) findViewById(R.id.btn_contact);
Button btn_discover=(Button) findViewById(R.id.btn_discover);
Button btn_me=(Button) findViewById(R.id.btn_me);
//[2]设置点击事件
btn_wx.setOnClickListener(this);
btn_contact.setOnClickListener(this);
btn_discover.setOnClickListener(this);
btn_me.setOnClickListener(this);
}
@Override
public void onClick(View v) {
//[4]获取fragment的管理者
FragmentManager fragmentManager=getFragmentManager();
FragmentTransaction beginTransaction=fragmentManager.beginTransaction();
//具体判断一下点击的是哪个按钮
switch (v.getId()) {
case R.id.btn_wx: //说明点击的是微信
beginTransaction.replace(R.id.ll_layout, new WxFragment());
break;
case R.id.btn_contact: //说明点击的是通讯录
beginTransaction.replace(R.id.ll_layout, new ContactFragment());
break;
case R.id.btn_discover: //说明点击的是发现
beginTransaction.replace(R.id.ll_layout, new DiscoverFragment());
break;
case R.id.btn_me: //说明点击的是我
beginTransaction.replace(R.id.ll_layout, new MeFragment());
break;
}
//记得commit
beginTransaction.commit();
}
}
无论怎样,想要使用Fragment必须定义一个Fragment1.java文件和对应的xml布局文件。
在Fragment中是无法使用onclick的,只能使用setOnClickListener(…).
Fragment的生命周期
以下Fragment重写了Fragment生命周期的全部11个方法,运行查看各方法何时执行。
public class MeFragment extends Fragment {
//首先要依附在Activity上
@Override
public void onAttach(Activity activity) {
System.out.println("onAttach");
super.onAttach(activity);
}
@Override
public void onCreate(Bundle savedInstanceState) {
System.out.println("onCreate");
super.onCreate(savedInstanceState);
}
//系统第一次画UI的时候调用
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view=inflater.inflate(R.layout.fragment_me, null);
System.out.println("onCreateView");
return view;
}
//当在onCreateView方法里面准备了view 初始化了
@Override
public void onActivityCreated(Bundle savedInstanceState) {
System.out.println("onActivityCreated");
super.onActivityCreated(savedInstanceState);
}
@Override
public void onStart() {
System.out.println("onStart");
super.onStart();
}
@Override
public void onResume() {
System.out.println("onResume");
super.onResume();
}
@Override
public void onPause() {
System.out.println("onPause");
super.onPause();
}
@Override
public void onStop() {
System.out.println("onStop");
super.onStop();
}
@Override
public void onDestroyView() {
System.out.println("onDestroyView");
super.onDestroyView();
}
//fragment销毁
@Override
public void onDestroy() {
System.out.println("onDestroy");
super.onDestroy();
}
//取消依附
@Override
public void onDetach() {
System.out.println("onDetach");
super.onDetach();
}
}
分析
当第一次进入应用时
按home键
回到应用
返回键退出
其他的一些生命周期方法都不常用,Fragment中必须覆写的方法是onCreatView(),还可以覆写onDestroy()方法,进行一些回收内存的操作。
Fragment之间通信(通过Activity作为桥梁)
需求:点击左侧fragment按钮,改变右侧fragment中TextView的值。
activity_main
<LinearLayout 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:orientation="horizontal"
tools:context="com.example.communication.MainActivity" >
<LinearLayout
android:id="@+id/ll1"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical"
></LinearLayout>
<LinearLayout
android:id="@+id/ll2"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical"
></LinearLayout>
</LinearLayout>
左侧Fragment布局
fragment1.xml
<?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:orientation="vertical" >
<Button
android:id="@+id/btn_update"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="修改"
/>
</LinearLayout>
右侧Fragment布局
fragment2.xml
<?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:orientation="vertical" >
<TextView
android:id="@+id/tv_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Hello World"
/>
</LinearLayout>
MainActivity
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//[1]获取fragment管理者
FragmentManager fragmentManager=getFragmentManager();
//[2]开启一个事物
FragmentTransaction beginTransaction=fragmentManager.beginTransaction();
//[2.1]替换fragment
beginTransaction.replace(R.id.ll1, new Fragment1(),"f1");//给每个Fragment定义标记tag
beginTransaction.replace(R.id.ll2, new Fragment2(),"f2");
//[3]开启事物
beginTransaction.commit();
}
}
Fragment定义
Fragment1.java 在此Fragment1中修改Fragment2中TextView内容
public class Fragment1 extends Fragment {
//当系统第一次画ui的时候调用 通过这个方法可以让fragment显示自己的布局内容
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
//通过打气筒将一个布局转换成view
View view=inflater.inflate(R.layout.fragment1, null);
//[1]找到按钮 设置点击事件
view.findViewById(R.id.btn_update).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//[2]修改fragment2里面的内容 通过fragment的公共桥梁------》activity
Fragment2 fragment2=(Fragment2) getActivity().getFragmentManager().findFragmentByTag("f2");
fragment2.updateText("hahahahahahaha");
}
});
return view;
}
}
Fragment2.java
public class Fragment2 extends Fragment {
private TextView tv_content;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view=inflater.inflate(R.layout.fragment2, null);
//[1]找到tv
tv_content = (TextView) view.findViewById(R.id.tv_content);
return view;
}
public void updateText(String content){
tv_content.setText(content);
}
}