您的位置:首页 > 其它

Fragment使用小结(三)

2016-10-16 16:59 197 查看
上一篇主要总结了Activity向Fragment传递数据的方式Fragment使用小结(二),接着Fragment向Activity传递数据以及Fragment间数据传递。

一. Fragment向Activity传递数据(两种方案)

方案一:接口回调,首先在Fragment中定义一个接口,并在接口中定义传递数据的抽象方法,然后在Activity中实现这个接口,并重写这个方法,最后在fragment中创建接口对象并指向Activity,传入数据。这种方式即可以实现Fragment和Activity之间的通信,也可以实现两个Fragment之间的通信。

MainActivity.Java

public class MainActivity extends AppCompatActivity implements ThreeFragment.MyCallBack {
private TextView mTextView;
private FragmentManager mFm;
private FragmentTransaction mTransaction;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextView = (TextView) findViewById(R.id.tv_data);
mFm = getFragmentManager();
// 2. 开启Fragment处理事务.
mTransaction = mFm.beginTransaction();
// 3. 进行Fragment操作
mTransaction.add(R.id.container, new ThreeFragment());
// 4. 进行事务的提交
mTransaction.commit();
}
@Override
public void sendData(String str) {
mTextView.setText(str);
}
}


ThreeFragment.java

public class ThreeFragment extends Fragment {
private EditText mData;
private Button mButton;
private MyCallBack mCallBack;
public interface MyCallBack {
public void sendData(String str);
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_three, container, false);
mData = (EditText) view.findViewById(R.id.et_message);
mButton = (Button) view.findViewById(R.id.bt_sendMessage);
mButton.setOnClickListener(new View.OnClickListener() {

private String mString;
@Override
public void onClick(View view) {
mString = mData.getText().toString().trim();
mCallBack.sendData(mString);

}
});
return view;
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
mCallBack = (MyCallBack) getActivity();
}
}


方案二:使用广播,首先在宿主Activity里面注册广播,然后当需要通信的时候在Fragment中发送广播,宿主Activity中接受到广播,就可以获取数据进行显示了。当然也可以用广播实现两个Fragment之间的通信。

MainActivity.Java

private TextView mTextView;
private FragmentManager mFm;
private FragmentTransaction mTransaction;
private IntentFilter mFilter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextView = (TextView) findViewById(R.id.tv_data);
mFm = getFragmentManager();
// 2. 开启Fragment处理事务.
mTransaction = mFm.beginTransaction();
// 3. 进行Fragment操作
mTransaction.add(R.id.container, new ThreeFragment());
// 4. 进行事务的提交
mTransaction.commit();
//动态注册广播
mFilter = new IntentFilter();
mFilter.addAction("android.activity.broadReceiver");
BroadcastReceiver mBr = new BroadReceiver();
registerReceiver(mBr, mFilter);
}
public class BroadReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Bundle mData = intent.getExtras();
mTextView.setText(mData.getString("text"));
}
}
}


ThreeFragment.java

mButton1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent("android.activity.broadReceiver");
intent.putExtra("text", "fragment通过广播发给Activity的数据");
getActivity().sendBroadcast(intent);
}
});


除了以上两种方案之外还可以使用EventBus等等,我会在下面的Fragment间数据传递中使用。

二 .Fragment间数据传递(五种方案)

方案一:首先直接通过getFragmentManager获取Fragment管理器,然后通过Fragment的tag标签找到该Fragment,最后调用该Fragment的方法即可

MainActivity.Java

public class MainActivity extends FragmentActivity {

private LeftFragment leftFragment;
private RightFragment rightFragment;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initFragment();
}
private void initFragment() {
leftFragment = new LeftFragment();
rightFragment = new RightFragment();
//将这个两个Fragment放到当前Activity对应的布局文件中
getSupportFragmentManager().beginTransaction().
add(R.id.fl_left, leftFragment, "left").
add(R.id.fl_right, rightFragment,"right").
commit();

}

}


LeftFragment.java

public class LeftFragment extends Fragment {

private ListView listView;

@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

View view = inflater.inflate(R.layout.fragment_left, container, false);

//从Fragment的View中获取到LsitView控件
listView = (ListView) view.findViewById(R.id.lv  );

final String[] data = {"条目一","条目二","条目三","条目
四","条目五"};

final int[] imageIds = {R.drawable.a,R.drawable.b,R.drawable.c,R.drawable.d,R.drawable.e};

listView.setAdapter(new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, data));
//给ListView设置条目的点击事件

listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
//1. 获取用户点击的位置 对应的 title 和图片
String title = data[position];
int imageId = imageIds[position];
//2. 将数据设置给RightFragment。
//(1)找到RightFragment
//获取Fragment管理器
FragmentManager fragmentManager = getFragmentManager();
//通过Fragment的tag标签找到该Fragment
RightFragment rightFragment = (RightFragment) fragmentManager.findFragmentByTag("right");
//(2)调用RightFragment的方法
rightFragment.setTitleAndImage(title, imageId);

}
});

return view;
}

}


RightFragment.java

public class RightFragment extends Fragment {

private ImageView iv;
private TextView tv_title;

@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

View view = inflater.inflate(R.layout.fragment_right, container, false);

tv_title = (TextView) view.findViewById(R.id.tv_title);
iv = (ImageView) view.findViewById(R.id.iv);
return view;
}

/*
* 添加一个方法,用于给自己设置标题和图片
*/
public void setTitleAndImage(String title, int imageId) {
tv_title.setText(title);
iv.setImageResource(imageId);
}
}


方案二:使用接口来实现两个Fragment之间通信,需要通过宿主Activity中转一下,首先在宿主Activity中实现这个接口,这样当Fragment调用onAttach方法时就可以实例化这个接口了,Fragment通过回调接口,将值返给Activity,Activity 通过setArguments 传值给另一个Fragment。如果是Fragment和宿主Activity通信则直接调用即可。

MainActivity.Java

public void sendData(String title, int imgId) {
FragmentManager manager = getFragmentManager();
//得到FragmentTransaction对象
FragmentTransaction transaction = manager.beginTransaction();
rightFragment = new RightFragment();
Bundle bundle  = new Bundle();
bundle.putString("title", title);
bundle.putInt("img",imgId);
rightFragment.setArguments(bundle);
//将rightFragment替换布局
transaction.replace(R.id.fl_right, rightFragment);
transaction.commit();//提交事务

}


LeftFragment.java

listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
//1. 获取用户点击的位置 对应的 title 和图片
String title = data[position];
int imageId = imageIds[position];
mCallBack.sendData(title,imageId);
}
});
return view;
}
public interface MyCallBack {
public void sendData(String title,int imgId);
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
mCallBack = (MyCallBack) getActivity();
}


RightFragment.java

//得到activity传过来的bundle对象
Bundle bundle = getArguments();

if(bundle!=null){
tv_title.setText(bundle.getString("title"));
iv.setImageResource(bundle.getInt("img"));
}


方案三:EventBus,直接参考 http://blog.csdn.net/tyk0910/article/details/51073292

方案四:使用广播,我采用的是LocalBroadcastManager发送广播

LocalBroadcastManager是AndroidSupport包提供了一个工具,是用来在同一个应用内的不同组件间发送Broadcast的。

注意,这是同一个应用,也就是其他应用就算和你共进程,也是无法互相发送广播的。

使用LocalBroadcastManager有如下好处:

1. 发送的广播只会在自己App内传播,不会泄露给其他App,确保隐私数据不会泄露

2. 其他App也无法向你的App发送该广播,不用担心其他App会来搞破坏

3. 比系统全局广播更加高效

LeftFragment.java

/**
* 方案四 发送广播
*/
Intent intent = new Intent("android.fragment.register");
intent.putExtra("title", title);
intent.putExtra("img", imageId);
LocalBroadcastManager.getInstance(getActivity()).sendBroadcast(intent);


RightFragment.java

LocalBroadcastManager localBroadcastManager = LocalBroadcastManager
.getInstance(getActivity());
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("android.fragment.register");
BroadcastReceiver br = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Bundle mData = intent.getExtras();

8ece
tv_title.setText(mData.getString("title"));
iv.setImageResource(mData.getInt("img"));
}

};
localBroadcastManager.registerReceiver(br, intentFilter);


方案五:通过宿主Activity(fragment(必须在同一个Activity中)),只需要改变LeftFragment.java以下代码

listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {

String title = data[position];
int imageId = imageIds[position];
// 在Fragment中调用其所在的Activity方法 , Fragment获取上下文的方法
FragmentActivity activity = getActivity();
if(activity instanceof MainActivity) {
// 获取Fragment管理器
FragmentManager fm = getFragmentManager();
// 找到第二个Fragment, 直接执行方法
RightFragment fragment = (RightFragment) fm.findFragmentByTag("right");
fragment.setTitleAndImage(title, imageId);

}

}
});

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