Fragment(二)通信

来源:互联网 发布:pureVPN软件 编辑:程序博客网 时间:2024/06/05 19:54

一、Fragment 和 Activity通信

1.Activity向Fragment传值

Fragment 是Activity中的一部分,通过setArguments(bundle)方法传递值对象Buddle对象。

注意:在Fragment的构造方法中,任何带参数的构造都是非法的,Fragment的参数只能通过getArguments()获得

import android.annotation.SuppressLint;import android.app.Activity;import android.app.FragmentManager;import android.app.FragmentTransaction;import android.os.Bundle;public class MainActivity extends Activity {private FragmentManager manager;private FragmentTransaction transaction;@SuppressLint("NewApi")@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);// 创建 Fragment管理器对象manager = getFragmentManager();transaction = manager.beginTransaction();// 创建 Fragment对象LeftFragment leftFragment = new LeftFragment();// 通过Buddle对象传递参数给FragmentBundle bundle = new Bundle();bundle.putString("left", "经理:101");leftFragment.setArguments(bundle);transaction.add(R.id.left, leftFragment, "left");transaction.commit();}}

在Fragment中通过getArguments()传递过来参数值
Bundle bundle=getArguments();String value= bundle.getString("left");

2.Fragment获得Activity中的内容

由于Fragment 是Activity中的一部分,在Fragment中可以通过getActivity();获得其所在Activity的对象

Context context = getActivity();
同理:在Fragment中获得Activity中的其他控件,获得控件对象,自然也就获得该控件的其他内容

// 获得当前Activity中的文本框对象EditText editText = (EditText) getActivity().findViewById(R.id.et_text_activity);


3.Activity获得Fragment中的内容

Activity获得Fragment中的控件,最简单的方式莫过于:把该控件在Fragment中定义为全局变量,activity获得了Fragment的对象,也就能获得它的控件。以xml定义中的fragment为例

自定义Fragment

import android.annotation.SuppressLint;import android.app.Fragment;import android.os.Bundle;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.EditText;import com.keno.android.R;@SuppressLint("NewApi")public class FragmentLayout extends Fragment {public EditText etContent;@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {View view = inflater.inflate(R.layout.fragment_1, null);etContent = (EditText) view.findViewById(R.id.et_content_fragment1);return view;}}

activity_fragment_layout.xml 文件 在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">    <fragment        android:id="@+id/fragment_test1"        android:tag="fragment1_test"        android:name="com.keno.android.fragment.FragmentLayout"        android:layout_width="match_parent"        android:layout_height="200dp">    </fragment></RelativeLayout>
activity获得了Fragment的对象,也就能获得它的控件。

@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_fragment_layout);// 得到Fragment的管理类对象FragmentManager fm = getFragmentManager();// 通过fragment的id找到布局的fragmentFragmentLayout fragment = (FragmentLayout) fm.findFragmentById(R.id.fragment_test1);// 通过fragment的tag找到布局的fragment,与findFragmentById的作用一致,但要保持tag唯一FragmentLayout fragment2 = (FragmentLayout) fm.findFragmentByTag("fragment1_test");// 得到fragment中的控件,并取得其显示的值String value = fragment.etContent.getText().toString();Log.i("value", value);}





二、Fragment 和Fragment 之间的通信

此种情况针对一个Activity中包含两个或两个以上Fragment之间的通讯,下面代码,我们以一个选择文章阅读的为例进行讲解(即左侧Fragment是一个文章选择列表,右侧Fragment是一个文章内容,选择左侧文章标题,右侧Fragment显示相应的文章)如下左图

1.定义左侧文章标题列表Fragment

由于该Fragment中显示的是一个列表,可以使用ListFragment

1)首先定义ListFragment的页面布局

<?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" >    <!-- ListFragment中ListView使用特定的id  android:id="@android:id/list"   --><ListView android:id="@id/android:list"               android:layout_width="match_parent"               android:layout_height="match_parent"               android:background="#00FF00"               android:layout_weight="1"               android:drawSelectorOnTop="false"/>     <TextView android:id="@id/android:empty"               android:layout_width="match_parent"               android:layout_height="match_parent"               android:background="#FF0000"               android:text="No data"/></LinearLayout>


2)创建Fragment_ArticleList.java 需要继承ListFragment

由于Fragment_ArticleList中 的listview 点击事件需要和所在activity和其他fragment分享,此时就需要在此fragment定义一个回调接口,并且在所在activity中实现这个回调接口,以此完成activity对Fragment事件的监听

/** * Fragment之间的通讯:Fragment_ArticleList和Fragment_Article *  * @author Keno *  */@SuppressLint("NewApi")public class Fragment_ArticleList extends ListFragment {private final String TAG = "ArticleList";OnArticleSelectedListener mListener;/** * 列表数据源 */String[] presidents = { "Dwight D. Eisenhower", "John F. Kennedy","Lyndon B. Johnson", "Richard Nixon", "Gerald Ford","Jimmy Carter", "Ronald Reagan", "George H. W. Bush","Bill Clinton", "George W. Bush", "Barack Obama" };@Overridepublic void onAttach(Activity activity) {super.onAttach(activity);try {// 当前fragment所在activity必须实现 fragment内部的回调接口,否者抛出ClassCastExceptionmListener = (OnArticleSelectedListener) activity;} catch (ClassCastException e) {throw new ClassCastException(activity.toString()+ " must implement OnArticleSelectedListener");}}@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);// ListFragment为自带listview 绑定数据源setListAdapter(new ArrayAdapter<String>(getActivity(),android.R.layout.simple_list_item_1, presidents));}@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {return inflater.inflate(R.layout.fragment_aticle_list, null);}// ListFragment中的 Listview被点击时触发该方法@Overridepublic void onListItemClick(ListView l, View v, int position, long id) {String title = presidents[position];Log.i(TAG, "选中list标题为:" + title);mListener.onArticleSelected(title);}/** * 选择标题列表时的回调接口 *  * @author Keno *  */public static interface OnArticleSelectedListener {public abstract void onArticleSelected(String title);};}

2.定义左侧文章内容阅读Fragment

1)布局xml就是两个TextView控件,用于和左侧选中的文章

<?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:layout_width="match_parent"               android:layout_height="0dp"               android:layout_weight="1"               android:text="文章内容\n左侧fragment列表选中:"/>    <TextView android:id="@+id/tv_content_article"               android:layout_width="match_parent"               android:layout_height="0dp"               android:layout_weight="4"/></LinearLayout>
2)创建Fragment_Article.java
public class Fragment_Article extends Fragment {//将显示文章的控件定义为全局变量,让所在activity可以通过Fragment对象直接调用public TextView tvContent;@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {View view = inflater.inflate(R.layout.fragment_aticle, null);tvContent = (TextView) view.findViewById(R.id.tv_content_article);return view;}}

3.Activity的定义

注意:此处activity必须实现Fragment_ArticleList.java中的回调接口 OnArticleSelectedListener,才能监听到文章列表Fragment的点击事件

public class Fragment_Fragment_Communication extends FragmentActivity implementsOnArticleSelectedListener {private FragmentManager fm;private FragmentTransaction transaction;private Fragment_ArticleList fragment;private Fragment_Article fragment_Article;private String value;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_fragment_communication2);loadFragment();// setOnclick();}@Overrideprotected void onResume() {/** * 设置为横屏 */if (getRequestedOrientation() != ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) {setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);}super.onResume();}private void loadFragment() {// 创建 Fragment管理器对象:管理和这个Activity相关的Fragmentfm = getSupportFragmentManager();// 实例化自定义Fragmentfragment = new Fragment_ArticleList();fragment_Article = new Fragment_Article();// 创建Fragment事务transaction = fm.beginTransaction();// 加载fragment 1.被填充容器id; 2.fragment对象; 3.填入fragment文件的描述transaction.add(R.id.ll_fragment_acticle_list, fragment, "article_list");transaction.add(R.id.ll_fragment_acticle_content, fragment_Article,"article_content");// 提交事务transaction.commit();}@Overridepublic void onArticleSelected(String title) {//回调方法:当fragment中listview点击事件触发时,回调处理fragment_Article.tvContent.setText("选中标题:" + title);}}




0 0