其实Activity和fragment之间传递数据有很多方法,我这里说一个用的比较多的一个方法——接口回调,后面有运行效果
接口回调有几个步骤:
1,要传递数据的类A里面定义一个接口X,接口里面创建一个抽象方法,方法里面的参数就是你要传递的数据类型
2,创建一个公共的方法Y,方法里的参数就是你创建的接口X
3,在要接收的类B里面拿到A类的实例对象a,调用A里面创建的公共的方法Y,
@@1.如果B是实现的A里面定义的那个接口,并实现了X里面的抽象方法,那么A的对象a调用A里面的公共方法Y时参数里面传递this就行了
@@2.如果B里面不是实现A里面的那个接口,那么A的对象a调用A里面的公共方法Y时里面传递new A.Y,他会自动添加X里面未实现的方法
说的有点晕,还是看代码好一点
首先当然是创建一个项目,activity的布局文件里面放一个frameLayout,用来让Fragment替换,底部放置两个Button用来点击切换fagment,具体代码如下:
<?xml version="1.0" encoding="utf-8"?>
<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="vertical"
tools:context="com.duanlian.interfacecallbackdemo1.MainActivity">
<FrameLayout
android:id="@+id/main_frameLayout"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" >
</FrameLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="50dp" >
<Button
android:id="@+id/button1"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:onClick="button"
android:text="FragmentA" />
<Button
android:id="@+id/button2"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:onClick="button"
android:text="FragmentB" />
</LinearLayout>
</LinearLayout>
然后在MainActivity定义一个接口,接口里面定义一个方法,方法里面的参数就是要传递数据的类型
public interface DataChange {
void setDataChange(String qqq);
}
创建一个公共的方法,参数是接口,当然你的先声明这个接口的对象:
static DataChange dataChange;
public void setData(DataChange dataChange) {
this.dataChange = dataChange;
}
我这个例子是在MainActivity里面请求数据,然后传递到Fragment里面去,所以我用了一个第三方Jar包xUtils请求数据
具体请求数据的方法:
private void getData(String path) {
HttpUtils utils = new HttpUtils();
utils.send(HttpRequest.HttpMethod.GET, path, new RequestCallBack<String>() {
@Override
public void onSuccess(ResponseInfo<String> responseInfo) {
//拿到请求到的数据
String result = responseInfo.result;
//调用接口的方法把数据传递进去
if (dataChange!=null) {
dataChange.setDataChange(result);
}
}
@Override
public void onFailure(HttpException e, String s) {
Toast.makeText(MainActivity.this, "请求数据失败"+s, Toast.LENGTH_SHORT).show();
}
});
}
创建两个Fragment,点击底部的Button让不同的fragment去替换布局里面的frameLayout
具体替换的方法是
/**
* 用来让Fragment替换framelayout的方法
*
* @param fragment
*/
private void changeFragment(Fragment fragment) {
getSupportFragmentManager().beginTransaction().replace(R.id.main_frameLayout, fragment).commit();
}
点击不同的Button替换fragment和调用getData()传递不同的网址请求不同的数据的方法:
public void button(View view) {
switch (view.getId()) {
case R.id.button1:
changeFragment(fragmentA);
getData("http://mobile.ximalaya.com/mobile/v1/album?albumId=2839012");
break;
case R.id.button2:
changeFragment(fragmentB);
getData("http://mobile.ximalaya.com/mobile/v1/album?albumId=2839015");
break;
default:
break;
}
在FragmentA和FragmentB里面分别都放一个TextView用来显示传递过去的数据
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#00ff00"
android:orientation="vertical">
<TextView
android:id="@+id/fragmemt_b_textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
FragmentA里面调用MainActivity里面的方法:
//拿到MainActivity的对象,调用它里面的方法
MainActivity activity = new MainActivity();
activity.setData(new MainActivity.DataChange() {
@Override
public void setDataChange(String aaa) {
textView.setText(aaa);
}
});
FragmentB里面我用的是实现接口的方法:
public class FragmentB extends Fragment implements MainActivity.DataChange
然后实现接口里面没实现的方法:
/**
* 实现接口之后必须实现接口里的抽象方法
* @param qqq
*/
@Override
public void setDataChange(String qqq) {
textView.setText(qqq);
}
然后调用MainActivity里面的方法:
//实现接口的方式调用mainActivity的方法
((MainActivity)getActivity()).setData(this);
大概就是这几个步骤,就完成了数据的传递,下面我把所有的布局文件和Activity和Framgnet里面的代码贴出来:
MainActivity代码如下:
package com.duanlian.interfacecallbackdemo1;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.util.Log;
import android.view.View;
import android.widget.Toast;
import com.duanlian.interfacecallbackdemo1.fragment.FragmentA;
import com.duanlian.interfacecallbackdemo1.fragment.FragmentB;
import com.lidroid.xutils.HttpUtils;
import com.lidroid.xutils.exception.HttpException;
import com.lidroid.xutils.http.ResponseInfo;
import com.lidroid.xutils.http.callback.RequestCallBack;
import com.lidroid.xutils.http.client.HttpRequest;
public class MainActivity extends FragmentActivity {
String TAG = "duanlian-------";
FragmentA fragmentA;
FragmentB fragmentB;
static DataChange dataChange;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
fragmentA = new FragmentA();
fragmentB = new FragmentB();
}
public void setData(DataChange dataChange) {
this.dataChange = dataChange;
}
/**
* 创建一个接口
*/
public interface DataChange {
void setDataChange(String qqq);
}
public void button(View view) {
switch (view.getId()) {
case R.id.button1:
changeFragment(fragmentA);
getData("http://mobile.ximalaya.com/mobile/v1/album?albumId=2839012");
break;
case R.id.button2:
changeFragment(fragmentB);
getData("http://mobile.ximalaya.com/mobile/v1/album?albumId=2839015");
break;
default:
break;
}
}
private void getData(String path) {
HttpUtils utils = new HttpUtils();
utils.send(HttpRequest.HttpMethod.GET, path, new RequestCallBack<String>() {
@Override
public void onSuccess(ResponseInfo<String> responseInfo) {
//拿到请求到的数据
String result = responseInfo.result;
//调用接口的方法把数据传递进去
if (dataChange!=null) {
dataChange.setDataChange(result);
}
}
@Override
public void onFailure(HttpException e, String s) {
Toast.makeText(MainActivity.this, "请求数据失败"+s, Toast.LENGTH_SHORT).show();
}
});
}
/**
* 用来让Fragment替换framelayout的方法
*
* @param fragment
*/
private void changeFragment(Fragment fragment) {
getSupportFragmentManager().beginTransaction().replace(R.id.main_frameLayout, fragment).commit();
}
}
MainActivity的布局文件:
<?xml version="1.0" encoding="utf-8"?>
<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="vertical"
tools:context="com.duanlian.interfacecallbackdemo1.MainActivity">
<FrameLayout
android:id="@+id/main_frameLayout"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" >
</FrameLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="50dp" >
<Button
android:id="@+id/button1"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:onClick="button"
android:text="FragmentA" />
<Button
android:id="@+id/button2"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:onClick="button"
android:text="FragmentB" />
</LinearLayout>
</LinearLayout>
FragmentA的代码和布局文件:
package com.duanlian.interfacecallbackdemo1.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.duanlian.interfacecallbackdemo1.MainActivity;
import com.duanlian.interfacecallbackdemo1.R;
public class FragmentA extends Fragment {
private TextView textView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_a, null);
textView = (TextView) view.findViewById(R.id.fragmemt_a_textview);
//拿到MainActivity的对象,调用它里面的方法
MainActivity activity = new MainActivity();
activity.setData(new MainActivity.DataChange() {
@Override
public void setDataChange(String aaa) {
textView.setText(aaa);
}
});
return view;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
}
布局文件:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ff00ff"
android:orientation="vertical">
<TextView
android:id="@+id/fragmemt_a_textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
FramemtB里面的代码:
package com.duanlian.interfacecallbackdemo1.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.duanlian.interfacecallbackdemo1.MainActivity;
import com.duanlian.interfacecallbackdemo1.R;
public class FragmentB extends Fragment implements MainActivity.DataChange{
private TextView textView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_b, null);
textView = (TextView) view.findViewById(R.id.fragmemt_b_textview);
//实现接口的方式调用mainActivity的方法
((MainActivity)getActivity()).setData(this);
return view;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
/**
* 实现接口之后必须实现接口里的抽象方法
* @param qqq
*/
@Override
public void setDataChange(String qqq) {
textView.setText(qqq);
}
}
布局文件:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#00ff00"
android:orientation="vertical">
<TextView
android:id="@+id/fragmemt_b_textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
运行结果如下: