您的位置:首页 > 移动开发 > Android开发

android中Fragment与Activity之间通信原理以及例子

2014-02-08 18:14 507 查看


对于fragment通信的应用在http://www.vogella.com/tutorials/AndroidFragments/article.html中有如下描述:


Application communication with fragments

To increase reuse of fragments, they should not directly communicate with each other.
Every communication of the fragments should be done via the host activity.

For this purpose a fragment should define an interface as an inner type and require that
the activity, which uses it, must implement this interface. This way you avoid that the fragment has any knowledge about the activity which uses it. In its
onAttach()
method
it can check if the activity correctly implements this interface.

首先,如果你想在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的一次完美演绎!

下面的例子是来自http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2012/1016/441.html。

Activity的UI分为两个部分,左边和右边,左边用来放置点击的按钮(LeftFragment),右边用来放置对应点击后显示的信息(RightFragment).

Activity的布局layout文件:main.xml:

<?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

<?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

<?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>


以上是布局文件,

java文件如下:

主Activity部分,该activity实现了leftfragment中定义的接口MyListener,

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 = new RightFragment();
LeftFragment leftFragment = new LeftFragment();
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,该fragment定义了一个接口MyListener,LeftFragment在它的onAttach()方法执行期间捕获该接口的实现,然后就可以调用接口方法,以便跟Activity通信。
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");
return inflater.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 = new MyButtonClickListener();
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:

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");
return inflater.inflate(R.layout.rightfragment, container, false);
}
}


注意,Fragment的生命周期和Activity生命周期之间的关系。在Activity里动态生成Fragment,首先是Activity调用onCreate()方法,但是这时候还没有加载到Fragment里的组件,当Fragment调用其onCreateView()方法后,Activity才能得到Fragment中的组件

效果:
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: