Fragment之间的通信

``1

嵌套关系,使用setArguments()

在Fragment B中新建一个函数:newInstance()接收传过来的参数。

1
2
3
4
5
6
7
public static Fragment2 newInstance(String text) {
Fragment2 fragment = new Fragment2();
Bundle args = new Bundle();
args.putString("param", text);
fragment.setArguments(args);
return fragment;
}

在Fragment B的onCreateView中获取参数

1
2
3
4
5
6
7
8
9
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment2, container, false);
if (getArguments() != null) {
String mParam1 = getArguments().getString("param");
TextView tv = (TextView)view.findViewById(R.id.textview);
tv.setText(mParam1);
}
return view;
}

在Fragment A中,调用Fragment B时,通过newInstance函数获取实例并传递参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class Fragment1 extends Fragment {

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment1, container, false);
Button btn = (Button)view.findViewById(R.id.load_fragment2_btn);
btn.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(final View view) {
Fragment2 fragment2 = Fragment2.newInstance("从Fragment1传来的参数");

FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.add(R.id.main_layout, fragment2);
transaction.addToBackStack(null);
transaction.commit();
}
});
return view;
}
}

同Activity不同Container的Fragment交互

这种情况有三中方法解决:

方法一:直接在Activity中操作

直接在Activity中找到对应控件的实例,然后直接操控即可

方法二:直接在Fragment中操作

这里有两个问题:如何获取自己控件的引用?如何获取其他Fragment页控件的引用?

  1. 首先获取自己控件的引用
    可以在onCreateView()中获取
1
2
3
4
5
6
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment1, container, false);
listView = (ListView)rootView.findViewById(R.id.list);//获取自己视图里的控件引用,方法一
return rootView;
}

在onCreateView()中,还没有创建视图,所以在这里如果使用getView()方法将返回空
另一种方法是在onActivityCreated()中获取,其回调在onCreate()执行后再执行

  1. 获取其它Fragment页控件引用方法
    获取Activity资源,须等Activity创建完成后,必须放在onActivityCreated()回调函数中。
1
2
3
4
5
6
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);

mFragment2_tv = (TextView) getActivity().findViewById(R.id.fragment2_tv);//获取其它fragment中的控件引用的唯一方法!!!

}

总的实现示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);

mFragment2_tv = (TextView) getActivity().findViewById(R.id.fragment2_tv);//获取其它fragment中的控件引用的唯一方法!!!
listView = (ListView) getView().findViewById(R.id.list);//获取自己视图里的控件引用,方法二

ArrayAdapter arrayAdapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, mStrings);
listView.setAdapter(arrayAdapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String str = mStrings[position];
mFragment2_tv.setText(str);
}
});
}

方法三:在各自Fragment中操作

方法二在Fragment A中操作了Fragment B,违背模块分离思想,应通过Activity将其分离

在Activity中可以直接通过FragmentManager.findFragmentById()获取Fragment实例

示例:

在Fragment2设置TextView函数

1
2
3
4
5
6
7
public class Fragment2 extends Fragment {
private TextView mTv;
…………
public void setText(String text) {
mTv.setText(text);
}
}

在Fragment1 中定义处理方式:

  1. 定义接口与变量
1
2
3
4
5
private titleSelectInterface mSelectInterface;

public interface titleSelectInterface{
public void onTitleSelect(String title);
}
  1. 接口变量赋值
    接口给Activity使用,在Activity中给接口变量赋值,在Fragment与Activity关联时,需要强转
1
2
3
4
5
6
7
8
9
10
public void onAttach(Activity activity) {
super.onAttach(activity);

try {
mSelectInterface = (titleSelectInterface) activity;
} catch (Exception e) {
throw new ClassCastException(activity.toString() + "must implement
OnArticleSelectedListener");
}
}
  1. 调用接口变量
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);

listView = (ListView) getView().findViewById(R.id.list);//获取自己视图里的控件引用,方法二
ArrayAdapter arrayAdapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, mStrings);
listView.setAdapter(arrayAdapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String str = mStrings[position];
mSelectInterface.onTitleSelect(str);
}
});
}

在Activity中实现接口

1
2
3
4
5
6
7
8
9
10
11
public class MainActivity extends FragmentActivity implements Fragment1.titleSelectInterface {

……

@Override
public void onTitleSelect(String title) {
FragmentManager manager = getSupportFragmentManager();
Fragment2 fragment2 = (Fragment2)manager.findFragmentById(R.id.fragment2);
fragment2.setText(title);
}
}