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

Android入门(32)——第九章 Fragment与Activity通信

2015-07-07 19:14 609 查看
第一部分:

1. Fragment的生命周期:



2. 案例:

第一步:创建布局fragment2,用来作为Fragment3和Fragment4的布局。只包含一个TextView控件,其中ID为text。

<?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/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="text" />

</LinearLayout>
第二步:创建MyFragment3.java文件,用来实例化Fragment3,同时还包括生命周期的各种函数:实例化采用fragment2布局文件。

package com.example.fragment;

import android.app.Activity;
import android.app.Fragment;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

public class MyFragment3 extends Fragment{

/*
* 每次创建都会绘制Fragment的View组件时回调该方法。
* */
@Override
// 加载自己的布局
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// 把layout布局文件转换成View对象

// 第一个参数resource:Fragment需要加载的布局文件
// 第二个参数root:加载layout的父ViewGroup
// attactToRoot:false,不返回父ViewGroup
View view = inflater.inflate(R.layout.fragment2, container, false);
TextView tv = (TextView)view.findViewById(R.id.text);// 这里加了view是因为返回对象必须是一个view。
tv.setText("第一个Fragment");
Log.i("Main", "Fragment1---onCreateView()");
return view;
}

/*
* 当Fragment被添加到Activity的时候会回调这个方法,这个方法只会去调用一次。
* */
@Override
public void onAttach(Activity activity) {
// TODO Auto-generated method stub
super.onAttach(activity);
Log.i("Main", "Fragment1---onAttach()");
}

/*
* 创建Fragment时会调用。只会调用一次
* */
@Override
public void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
Log.i("Main", "Fragment1---onCreate()");
}

/*
* 创建以后的一个状态,当Fragment所在的Activity启动完成后调用。
* */
@Override
public void onActivityCreated(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onActivityCreated(savedInstanceState);
Log.i("Main", "Fragment1---onActivityCreated()");
}

/*
* 启动Fragment。
* */
@Override
public void onStart() {
// TODO Auto-generated method stub
super.onStart();
Log.i("Main", "Fragment1---onStart()");
}

/*
* 恢复Fragment时会被回调,调用onStart()方法后面一定会调用这个方法。
* */
@Override
public void onResume() {
// TODO Auto-generated method stub
super.onResume();
Log.i("Main", "Fragment1---onResume()");
}

/*
* 暂停Fragment。
* */
@Override
public void onPause() {
// TODO Auto-generated method stub
super.onPause();
Log.i("Main", "Fragment1---onPause()");
}

/*
* 停止Fragment。
* */
@Override
public void onStop() {
// TODO Auto-generated method stub
super.onStop();
Log.i("Main", "Fragment1---onStop()");
}

/*
* 销毁Fragment所包含的View组件时调用,与CreateView对应。
* */
@Override
public void onDestroyView() {
// TODO Auto-generated method stub
super.onDestroyView();
Log.i("Main", "Fragment1---onDestroyView()");
}

/*
* 销毁Fragment时会被回调。
* */
@Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
Log.i("Main", "Fragment1---onDestroy()");
}

/*
* Fragment从Activity中删除时会回调该方法,并且这个方法只会调用一次。
* */
@Override
public void onDetach() {
// TODO Auto-generated method stub
super.onDetach();
Log.i("Main", "Fragment1---onDetach()");
}
}
第三步:创建MyFragment4.java文件,用来实例化Fragment4,同时还包括生命周期的各种函数:这一步与上一步相似。实例化采用fragment2布局文件。
package com.example.fragment;

import android.app.Activity;
import android.app.Fragment;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

public class MyFragment4 extends Fragment{

@Override
// 加载自己的布局
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// 把layout布局文件转换成View对象

// 第一个参数resource:Fragment需要加载的布局文件
// 第二个参数root:加载layout的父ViewGroup
// attactToRoot:false,不返回父ViewGroup
View view = inflater.inflate(R.layout.fragment2, container, false);
TextView tv = (TextView)view.findViewById(R.id.text);
tv.setText("第二个Fragment");
Log.i("Main", "Fragment2---onCreateView()");
return view;
}

@Override
public void onAttach(Activity activity) {
// TODO Auto-generated method stub
super.onAttach(activity);
Log.i("Main", "Fragment2---onAttach()");
}

@Override
public void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
Log.i("Main", "Fragment2---onCreate()");
}

@Override
public void onActivityCreated(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onActivityCreated(savedInstanceState);
Log.i("Main", "Fragment2---onActivityCreated()");
}

@Override
public void onStart() {
// TODO Auto-generated method stub
super.onStart();
Log.i("Main", "Fragment2---onStart()");
}

@Override
public void onResume() {
// TODO Auto-generated method stub
super.onResume();
Log.i("Main", "Fragment2---onResume()");
}

@Override
public void onPause() {
// TODO Auto-generated method stub
super.onPause();
Log.i("Main", "Fragment2---onPause()");
}

@Override
public void onStop() {
// TODO Auto-generated method stub
super.onStop();
Log.i("Main", "Fragment2---onStop()");
}

@Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
Log.i("Main", "Fragment2---onDestroy()");
}

@Override
public void onDetach() {
// TODO Auto-generated method stub
super.onDetach();
Log.i("Main", "Fragment2---onDetach()");
}
}


第五步:创建main3布局文件,是为下面的MainActivity3提供布局页面的:只有一个Button按钮。

<?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"
android:id="@+id/layout">

<Button
android:text="切换Fragment"
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</Button>

</LinearLayout>


第四步:创建MainActivity3.java文件,用来设置两个Fragment之间的跳转。

package com.example.fragment;

import android.app.Activity;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class MainActivity3 extends Activity{

private Button button;
private boolean flag = true;

@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.main3);
init();
button = (Button) findViewById(R.id.button);
button.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction beginTransaction = fragmentManager.beginTransaction();
// 点击按钮时,Fragment4和Fragment3之间相互转换。是动态加在的
if(flag){
MyFragment4 frag4 = new MyFragment4();
// 这个layout是在main3中的LinearLayout。
beginTransaction.replace(R.id.layout, frag4);
flag = false;
}
else{
MyFragment3 frag3 = new MyFragment3();
beginTransaction.replace(R.id.layout, frag3);
flag = true;
}
beginTransaction.commit();
}
});
}

private void init() {
// TODO Auto-generated method stub
FragmentManager fragmentManager = getFragmentManager();// 动态生成Fragment3,默认生成这个。
FragmentTransaction beginTransaction = fragmentManager.beginTransaction();
MyFragment3 frag3 = new MyFragment3();
beginTransaction.add(R.id.layout,frag3);
beginTransaction.commit();
}
}

第五步:去MainActivity中设置switch跳转:

package com.example.fragment;

import android.os.Bundle;
import android.app.Activity;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.content.Intent;
import android.view.Menu;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.RadioGroup;

public class MainActivity extends Activity implements android.widget.RadioGroup.OnCheckedChangeListener{

private RadioGroup group;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

group = (RadioGroup) findViewById(R.id.radiogroup);
group.setOnCheckedChangeListener(this);
}

@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
//
switch(checkedId){
case R.id.first:
Intent intent = new Intent(this,MainActivity2.class);
startActivity(intent);
break;
case R.id.second:
MyFragment2 fragment2 = new MyFragment2();
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction beginTransaction = fragmentManager.beginTransaction();
// 第一个参数是说你要把fragment2加载到布局的ID,例子中frame在main布局文件中定义。
// 第二个参数是说
beginTransaction.add(R.id.frame, fragment2);
beginTransaction.addToBackStack(null);	// 返回键就可以返回了。
beginTransaction.commit();
break;
case R.id.third:
Intent intent1 = new Intent(this,MainActivity3.class);
startActivity(intent1);
break;
case R.id.fourth:
break;
default:
break;
}
}
}
效果图:点击按钮进行切换:





查看Log日志:



完全是个线性变化,不会打断,一直都是从头到尾的。开始会从onAttach()到onResume(),退出走后面的。

我们下面走一个流程:

启动Fragment



屏幕锁屏



屏幕解屏



切换到其他Fragment



回到桌面



回到应用



退出Fragment



第二部分:

3. Fragment与Activity通信:





案例一:Activity向Fragment传送信息:

第一步:在MainActivity文件中设置switch,进行点击跳转:

package com.example.fragment;

import android.os.Bundle;
import android.app.Activity;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.content.Intent;
import android.view.Menu;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.RadioGroup;

public class MainActivity extends Activity implements android.widget.RadioGroup.OnCheckedChangeListener{

private RadioGroup group;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

group = (RadioGroup) findViewById(R.id.radiogroup);
group.setOnCheckedChangeListener(this);
}

@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
//
switch(checkedId){
case R.id.first:
Intent intent = new Intent(this,MainActivity2.class);
startActivity(intent);
break;
case R.id.second:
MyFragment2 fragment2 = new MyFragment2();
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction beginTransaction = fragmentManager.beginTransaction();
// 第一个参数是说你要把fragment2加载到布局的ID,例子中frame在main布局文件中定义。
// 第二个参数是说
beginTransaction.add(R.id.frame, fragment2);
beginTransaction.addToBackStack(null);	// 返回键就可以返回了。
beginTransaction.commit();
break;
case R.id.third:
Intent intent1 = new Intent(this,MainActivity3.class);
startActivity(intent1);
break;
case R.id.fourth:
Intent intent2 = new Intent(this,MainActivity4.class);
startActivity(intent2);
break;
default:
break;
}
}
}
第二步:创建一个MyFragment5.java的文件,用来实例化Fragment,

package com.example.fragment;

import android.app.Activity;
import android.app.Fragment;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;

public class MyFragment5 extends Fragment{

@Override
// 加载自己的布局
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// 把layout布局文件转换成View对象

// 第一个参数resource:Fragment需要加载的布局文件
// 第二个参数root:加载layout的父ViewGroup
// attactToRoot:false,不返回父ViewGroup
View view = inflater.inflate(R.layout.fragment2, container, false);
TextView tv = (TextView)view.findViewById(R.id.text);
String text = getArguments().get("name")+" ";// 获取它所在的Activity,然后接收从Activity中传来的信息,然后用Toast显示处理。
tv.setText(text);
Toast.makeText(getActivity(), "已成功接收到"+text, Toast.LENGTH_SHORT).show();

return view;
}

}


第三步:创建一个与下面活动对应的布局文件main4,其中包含一个EditText和Button。

<?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"
android:id="@+id/layout"
>

<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/editText"
/>

<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="发送"
android:id="@+id/send"
/>
</LinearLayout>


第四步:创建一个新的活动MainActivity4,记得去清单中登记,

package com.example.fragment;

import android.app.Activity;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity4 extends Activity{

private EditText editext;
private Button send;

@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.main4);
editext = (EditText) findViewById(R.id.editText);
send = (Button) findViewById(R.id.send);

send.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
String text = editext.getText().toString();
MyFragment5 fragment5 = new MyFragment5();
Bundle bundle = new Bundle();
bundle.putString("name", text);// 用这个方法从Activity给Fragment发送信息,信息名称为name
fragment5.setArguments(bundle);// Fragment从这里向Activity接收信息
FragmentManager fragmentManager = getFragmentManager();// 动态创建Fragment。
FragmentTransaction beginTransaction = fragmentManager.beginTransaction();
beginTransaction.add(R.id.layout,fragment5,"fragment5");
beginTransaction.commit();
Toast.makeText(MainActivity4.this, "向Fragment发送数据"+text, Toast.LENGTH_SHORT).show();
}
});
}
}
效果图:





案例二:案例二包括了双方的收发:

第一步:改写MyFragment5文件:定义一个接口,让MainActivity4去实现,通过接口来传递信息。

就是Fragment通过onattach方法获取了当前的Activity,然后Activity调用自己实现的方法thank将数据传回去。

package com.example.fragment;

import android.app.Activity;
import android.app.Fragment;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;

public class MyFragment5 extends Fragment {

public MyListener listener;
private String code = "Thank you!";

// 定义一个接口,在MainActivity4中实现。
public interface MyListener {
public void thank(String code);
}

// 当Fragment添加到Activity中时调用的一个方法。也就是通过这个方法,Fragment获取了当前的Activity。
@Override
public void onAttach(Activity activity) {
// TODO Auto-generated method stub
listener = (MyListener) activity; // 所以这里Activity也就是那个Activity。
super.onAttach(activity);
}

@Override
// 加载自己的布局
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// 把layout布局文件转换成View对象

// 第一个参数resource:Fragment需要加载的布局文件
// 第二个参数root:加载layout的父ViewGroup
// attactToRoot:false,不返回父ViewGroup
View view = inflater.inflate(R.layout.fragment2, container, false);
TextView tv = (TextView) view.findViewById(R.id.text);
String text = getArguments().get("name") + " ";
tv.setText(text);
Toast.makeText(getActivity(), "已成功接收到" + text, Toast.LENGTH_SHORT)
.show();
Toast.makeText(getActivity(), "向Activity发送" + code, Toast.LENGTH_SHORT)
.show();
listener.thank(code); // 这样就把字符串传给了Activity。相当于Activity通过自己实现的方法thank将数据传了回去,thank函数是Activity中的。
return view;
}

}
第二步:改写MainActivity4文件,该类实现MyListener,通过thank从Fragment那边接收信息:

package com.example.fragment;

import com.example.fragment.MyFragment5.MyListener;

import android.app.Activity;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

// 实现在MyFragment5中定义的接口MyListener
public class MainActivity4 extends Activity implements MyListener {

private EditText editext;
private Button send;

@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.main4);
editext = (EditText) findViewById(R.id.editText);
send = (Button) findViewById(R.id.send);

send.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
String text = editext.getText().toString();
MyFragment5 fragment5 = new MyFragment5();
Bundle bundle = new Bundle();
bundle.putString("name", text);
fragment5.setArguments(bundle);
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction beginTransaction = fragmentManager
.beginTransaction();
beginTransaction.add(R.id.layout, fragment5, "fragment5");
beginTransaction.commit();
Toast.makeText(MainActivity4.this, "向Fragment发送数据" + text,
Toast.LENGTH_SHORT).show();
}
});
}

@Override
public void thank(String code) {
// TODO Auto-generated method stub
Toast.makeText(MainActivity4.this, "Think" + code, Toast.LENGTH_SHORT)
.show();
}
}
至于效果图,我已经懒得放了,就是点击发送以后,下面连续出现了四个Toast条。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: