android中fragment与activity之间通信原理以及例子
2016-03-24 18:19
651 查看
首先,如果你想在android3.0及以下版本使用fragment,你必须引用android-support-v4.jar这个包
然后你写的activity不能再继承自Activity类了,而是要继承android.support.v4.app.FragmentActivity,一些其他的父类也有相应的变化.
由于在android的实现机制中fragment和activity会被分别实例化为两个不相干的对象,他们之间的联系由activity的一个成员对象fragmentmanager来维护.fragment实例化后会到activity中的fragmentmanager去注册一下,这个动作封装在fragment对象的onAttach中,所以你可以在fragment中声明一些回调接口,当fragment调用onAttach时,将这些回调接口实例化,这样fragment就能调用各个activity的成员函数了,当然activity必须implements这些接口,否则会包classcasterror
fragment和activity的回调机制又是OOP的一次完美演绎!
下面通过一个例子来说明:
我把Activity的UI分为两个部分,左边和右边,左边用来放置点击的按钮(LeftFragment),右边用来放置对应点击后显示的信息(RightFragment).
Activity的布局layout文件:main.xml
[html]
view plaincopy
<?xml version="1.0"encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal">
<LinearLayout
android:id="@+id/left_layout"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_weight="1"
android:orientation="vertical">
</LinearLayout>
<LinearLayout
android:id="@+id/right_layout"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_weight="10"
android:orientation="vertical">
</LinearLayout>
</LinearLayout>
LeftFragment的布局layout:leftfragment.xml
[html]
view plaincopy
<?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/first_button"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/first_button"/>
<Button
android:id="@+id/second_button"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/second_button"/>
<Button
android:id="@+id/third_button"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/third_button"/>
</LinearLayout>
RightFragment的布局layout:rightfragment.xml
[html]
view plaincopy
<?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/right_show_message"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@android:color/holo_orange_dark"
android:textColor="@android:color/white"/>
</LinearLayout>
以上是两个fragment和一个Activity的布局文件,下面来看他们的java文件
Activity:
[java]
view plaincopy
public class FirstActivity extends Activity implements MyListener
{
/**
* 实现MyListener,当LeftFragment中点击第一页的时候,让RightFragment显示第一页信息,同理当点击第二页的时候,RightFragment显示第二页信息
*
* @param index
* 显示的页数
*/
public void showMessage(int index)
{
if(1 == index)
showMessageView.setText(R.string.first_page);
if(2 == index)
showMessageView.setText(R.string.second_page);
if(3 == index)
showMessageView.setText(R.string.third_page);
}
/** 得到RightFragment中显示信息的控件 */
private TextView showMessageView;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
System.out.println("Activity--->onCreate");
FragmentManager manager = getFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
// 动态增加Fragment
RightFragment rightFragment = newRightFragment();
LeftFragment leftFragment = newLeftFragment();
transaction.add(R.id.left_layout, leftFragment, "leftfragment");
transaction.add(R.id.right_layout, rightFragment, "rightfragment");
transaction.commit();
}
@Override
protected void onResume()
{
super.onResume();
System.out.println("Activity--->onResume");
showMessageView = (TextView) findViewById(R.id.right_show_message);
}
}
LeftFragment:
[java]
view plaincopy
public class LeftFragment extends Fragment
{
/** Acitivity要实现这个接口,这样Fragment和Activity就可以共享事件触发的资源了 */
public interface MyListener
{
public void showMessage(int index);
}
private MyListener myListener;
private Button firstButton;
private Button secondButton;
private Button thirdButton;
/** Fragment第一次附属于Activity时调用,在onCreate之前调用 */
@Override
public void onAttach(Activity activity)
{
super.onAttach(activity);
System.out.println("LeftFragment--->onAttach");
myListener = (MyListener) activity;
}
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
System.out.println("LeftFragment--->onCreate");
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
System.out.println("LeftFragment--->onCreateView");
returninflater.inflate(R.layout.leftfragment, container, false);
}
@Override
public void onResume()
{
super.onResume();
System.out.println("LeftFragment--->onResume");
firstButton = (Button) getActivity().findViewById(R.id.first_button);
secondButton = (Button) getActivity().findViewById(R.id.second_button);
thirdButton = (Button) getActivity().findViewById(R.id.third_button);
MyButtonClickListener clickListener = newMyButtonClickListener();
firstButton.setOnClickListener(clickListener);
secondButton.setOnClickListener(clickListener);
thirdButton.setOnClickListener(clickListener);
}
/** 按钮的监听器 */
class MyButtonClickListener implements OnClickListener
{
public void onClick(View v)
{
Button button = (Button) v;
if(button == firstButton)
myListener.showMessage(1);
if(button == secondButton)
myListener.showMessage(2);
if(button == thirdButton)
myListener.showMessage(3);
}
}
}
RightFragment:
[java]
view plaincopy
public class RightFragment extends Fragment
{
@Override
public void onCreate(Bundle savedInstanceState)
{
System.out.println("RightFragment--->onCreate");
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
System.out.println("RightFragment--->onCreateView");
returninflater.inflate(R.layout.rightfragment, container, false);
}
}
注意,Fragment的生命周期和Activity生命周期之间的关系。在Activity里动态生成Fragment,首先是Activity调用onCreate()方法,但是这时候还没有加载到Fragment里的组件,当Fragment调用其onCreateView()方法后,Activity才能得到Fragment中的组件
这里最关键的就是Fragment要有一个接口和这个接口的引用,而这个接口需要Activity去实现它。当Fragment调用onAttach(Activity acitivity)方法的时候,将这个activity传递给这个接口引用,这样,就可以和Activity进行交互了.
然后你写的activity不能再继承自Activity类了,而是要继承android.support.v4.app.FragmentActivity,一些其他的父类也有相应的变化.
由于在android的实现机制中fragment和activity会被分别实例化为两个不相干的对象,他们之间的联系由activity的一个成员对象fragmentmanager来维护.fragment实例化后会到activity中的fragmentmanager去注册一下,这个动作封装在fragment对象的onAttach中,所以你可以在fragment中声明一些回调接口,当fragment调用onAttach时,将这些回调接口实例化,这样fragment就能调用各个activity的成员函数了,当然activity必须implements这些接口,否则会包classcasterror
fragment和activity的回调机制又是OOP的一次完美演绎!
下面通过一个例子来说明:
我把Activity的UI分为两个部分,左边和右边,左边用来放置点击的按钮(LeftFragment),右边用来放置对应点击后显示的信息(RightFragment).
Activity的布局layout文件:main.xml
[html]
view plaincopy
<?xml version="1.0"encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal">
<LinearLayout
android:id="@+id/left_layout"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_weight="1"
android:orientation="vertical">
</LinearLayout>
<LinearLayout
android:id="@+id/right_layout"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_weight="10"
android:orientation="vertical">
</LinearLayout>
</LinearLayout>
LeftFragment的布局layout:leftfragment.xml
[html]
view plaincopy
<?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/first_button"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/first_button"/>
<Button
android:id="@+id/second_button"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/second_button"/>
<Button
android:id="@+id/third_button"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/third_button"/>
</LinearLayout>
RightFragment的布局layout:rightfragment.xml
[html]
view plaincopy
<?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/right_show_message"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@android:color/holo_orange_dark"
android:textColor="@android:color/white"/>
</LinearLayout>
以上是两个fragment和一个Activity的布局文件,下面来看他们的java文件
Activity:
[java]
view plaincopy
public class FirstActivity extends Activity implements MyListener
{
/**
* 实现MyListener,当LeftFragment中点击第一页的时候,让RightFragment显示第一页信息,同理当点击第二页的时候,RightFragment显示第二页信息
*
* @param index
* 显示的页数
*/
public void showMessage(int index)
{
if(1 == index)
showMessageView.setText(R.string.first_page);
if(2 == index)
showMessageView.setText(R.string.second_page);
if(3 == index)
showMessageView.setText(R.string.third_page);
}
/** 得到RightFragment中显示信息的控件 */
private TextView showMessageView;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
System.out.println("Activity--->onCreate");
FragmentManager manager = getFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
// 动态增加Fragment
RightFragment rightFragment = newRightFragment();
LeftFragment leftFragment = newLeftFragment();
transaction.add(R.id.left_layout, leftFragment, "leftfragment");
transaction.add(R.id.right_layout, rightFragment, "rightfragment");
transaction.commit();
}
@Override
protected void onResume()
{
super.onResume();
System.out.println("Activity--->onResume");
showMessageView = (TextView) findViewById(R.id.right_show_message);
}
}
LeftFragment:
[java]
view plaincopy
public class LeftFragment extends Fragment
{
/** Acitivity要实现这个接口,这样Fragment和Activity就可以共享事件触发的资源了 */
public interface MyListener
{
public void showMessage(int index);
}
private MyListener myListener;
private Button firstButton;
private Button secondButton;
private Button thirdButton;
/** Fragment第一次附属于Activity时调用,在onCreate之前调用 */
@Override
public void onAttach(Activity activity)
{
super.onAttach(activity);
System.out.println("LeftFragment--->onAttach");
myListener = (MyListener) activity;
}
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
System.out.println("LeftFragment--->onCreate");
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
System.out.println("LeftFragment--->onCreateView");
returninflater.inflate(R.layout.leftfragment, container, false);
}
@Override
public void onResume()
{
super.onResume();
System.out.println("LeftFragment--->onResume");
firstButton = (Button) getActivity().findViewById(R.id.first_button);
secondButton = (Button) getActivity().findViewById(R.id.second_button);
thirdButton = (Button) getActivity().findViewById(R.id.third_button);
MyButtonClickListener clickListener = newMyButtonClickListener();
firstButton.setOnClickListener(clickListener);
secondButton.setOnClickListener(clickListener);
thirdButton.setOnClickListener(clickListener);
}
/** 按钮的监听器 */
class MyButtonClickListener implements OnClickListener
{
public void onClick(View v)
{
Button button = (Button) v;
if(button == firstButton)
myListener.showMessage(1);
if(button == secondButton)
myListener.showMessage(2);
if(button == thirdButton)
myListener.showMessage(3);
}
}
}
RightFragment:
[java]
view plaincopy
public class RightFragment extends Fragment
{
@Override
public void onCreate(Bundle savedInstanceState)
{
System.out.println("RightFragment--->onCreate");
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
System.out.println("RightFragment--->onCreateView");
returninflater.inflate(R.layout.rightfragment, container, false);
}
}
注意,Fragment的生命周期和Activity生命周期之间的关系。在Activity里动态生成Fragment,首先是Activity调用onCreate()方法,但是这时候还没有加载到Fragment里的组件,当Fragment调用其onCreateView()方法后,Activity才能得到Fragment中的组件
这里最关键的就是Fragment要有一个接口和这个接口的引用,而这个接口需要Activity去实现它。当Fragment调用onAttach(Activity acitivity)方法的时候,将这个activity传递给这个接口引用,这样,就可以和Activity进行交互了.
相关文章推荐
- 按下更新按钮,每隔1S自动更新进度条,更新到100%自动消失
- [Android] AndroidManifest.xml出现问题
- 进入应用动画闪屏, android5.0初始动画,不执行解决等方案总结
- Android - MyFragment.java
- Android版本和API Level对应关系
- Android HAL的STUB的具体处理
- Android java web 环境变量配置
- Android - MyViewPagerActivity.java
- Android五大基本组件
- 改变Android状态栏字体颜色和实现沉浸式状态栏
- Android 仿iOS时间选择器自定义WheelView
- android学习——AndroidManifest.xml清单文件的重要性
- android Activity的onPause()与onResume()
- Android 源码 listview 重用机制 浅析
- Android应用程序组件Activity的"singleTask"
- Android实现计时与倒计时(限时抢购)的几种方法
- Android初试--Android中的ContentProvider(2)
- Android中实现定时器的3种解决方法
- [Android Pro] static 和 Volatile 的区别
- Android 简单封装的例子