Fragment依赖父Activity生存,所以分Activity与Fragment交互,Fragment与Activity交互,Fragment与Fragment交互,但是都需要中间者Activity。
一般情况下,这种方式用的不及接口回调方式多。
场景:
Activity启动Fragment,但传入参数不同,例如,listview点击列表项,启动fragment,但是fragment显示的内容与activity选择的item有关。
这种方式实现思路是:利用Fragment的FragmentManager的Transaction事务替换Fragment,以参数传递方式实现新建Fragment的初始化数据。(setArguments传参)
MainActivity.java
/**
*Activity中利用FragmentManager实例化新Fragment并通过Transaction方式实现Fragment
*主界面布局替换掉的是一个RelativeLayout
*/
public class MainActivity extends AppCompatActivity {
private Button mButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mButton = (Button) findViewById(R.id.btn_activity);
mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//通过replace方式新建fragment
BlankFragment fragment = new BlankFragment();
Bundle bundle = new Bundle();
bundle.putString("test","hello,I am a student.");
//调用setArguments()传递bundle数据实现初始化
fragment.setArguments(bundle);
getFragmentManager().beginTransaction()
.replace(R.id.fragment,fragment)
.commit();
}
});
}
}
BlankFragment.java
public class BlankFragment extends Fragment {
public BlankFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_blank, container, false);
//获取Bundle并初始化显示数据
Bundle bundle = getArguments();
TextView t1 = (TextView) view.findViewById(R.id.tv_fragment);
t1.setText(bundle.getString("test"));
return view;
}
}
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.alphathink.fragmentdemo.MainActivity">
<RelativeLayout
android:gravity="center"
android:id="@+id/fragment"
android:layout_width="match_parent"
android:layout_height="200dp"
>
RelativeLayout>
LinearLayout>
fragment_blank.xml
<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.alphathink.fragmentdemo.BlankFragment">
<TextView
android:id="@+id/tv_fragment"
android:layout_marginTop="15dp"
android:text="hello fragment"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
LinearLayout>
运行结果是显示字符hello,I am a student就不贴了,证明数据传输成功了。
这种方式适用于,两者交互不强,比如新闻信息浏览,读书软件等,点击每个item就跳转到下一界面和本界面无过多的数据交互。
无论是Fragment与Activity还是Fragment交互,都要通过Activity交互,所以究竟还是Fragment与Activity的交互。
这种方式采用内部注册回调的方法,适合交互性强的应用场景。
这种方式的实现思路是:在fragment中注册回调方法,Activity实现这个回调方法,从而将两者联系起来,可进行下一步操作,这种方式使用较频繁。
MainActivity.java
public class MainActivity extends AppCompatActivity implements BlankFragment0.OnFragmentInteractionListener {
private TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.tv_activity);
}
@Override
public void onFragmentInteraction(String string) {
//在这里可以获取到Fragment传递来的数据,这里为方便传递了简单的string数据
textView.setText(string);
}
}
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.alphathink.fragmentdemo.MainActivity">
<fragment
android:id="@+id/fragment1"
android:name="com.alphathink.fragmentdemo.BlankFragment"
android:layout_width="match_parent"
android:layout_height="200dp"
android:tag="fragment2" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/tv_activity"/>
LinearLayout>
BlankFragment.java
public class BlankFragment extends Fragment {
//定义回调接口
private OnFragmentInteractionListener mListener;
public BlankFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_blank, container, false);
Button button = (Button) view.findViewById(R.id.btn_fragment2);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//模拟数据传递,这里没有传太复杂的数据
onButtonPressed("我按了Button");
}
});
return view;
}
// 自定义方法,内部实现回调方法即可传递数据,数据格式和方法名请自己定义
public void onButtonPressed(String string) {
if (mListener != null) {
mListener.onFragmentInteraction(string);
}
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
//如果activity未实现接抛出异常
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}
@Override
public void onDetach() {
super.onDetach();
mListener = null;
}
//Activity必须实现的接口
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(String string);
}
}
fragment_blank.xml
<RelativeLayout 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:gravity="center"
android:background="@color/colorPrimary"
tools:context="com.alphathink.fragmentdemo.BlankFragment">
<Button
android:id="@+id/btn_fragment2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="click"
android:gravity="center"/>
RelativeLayout>
实现布局很简单就是Activity中包含一个Fragment和一个TextView点击Fragment布局内部的Button可以传递给Activity参数。
实现结果也是一行字符:我按了Button,也不贴了。
结合两者就可以实现了,不多说了哈。