Fragment(二)通信

一、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")
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		// 创建 Fragment管理器对象
		manager = getFragmentManager();
		transaction = manager.beginTransaction();
		// 创建 Fragment对象
		LeftFragment leftFragment = new LeftFragment();
		// 通过Buddle对象传递参数给Fragment
		Bundle 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;

	@Override
	public 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的对象,也就能获得它的控件。

@Override
protected void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	setContentView(R.layout.activity_fragment_layout);

	// 得到Fragment的管理类对象
	FragmentManager fm = getFragmentManager();
	// 通过fragment的id找到布局的fragment
	FragmentLayout 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显示相应的文章)如下左图Fragment(二)通信_第1张图片

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" };

	@Override
	public void onAttach(Activity activity) {
		super.onAttach(activity);
		try {
			// 当前fragment所在activity必须实现 fragment内部的回调接口,否者抛出ClassCastException
			mListener = (OnArticleSelectedListener) activity;
		} catch (ClassCastException e) {
			throw new ClassCastException(activity.toString()
					+ " must implement OnArticleSelectedListener");
		}
	}

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		// ListFragment为自带listview 绑定数据源
		setListAdapter(new ArrayAdapter<String>(getActivity(),
				android.R.layout.simple_list_item_1, presidents));
	}

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		return inflater.inflate(R.layout.fragment_aticle_list, null);
	}

	// ListFragment中的 Listview被点击时触发该方法
	@Override
	public 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;

	@Override
	public 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 implements
		OnArticleSelectedListener {
	private FragmentManager fm;
	private FragmentTransaction transaction;
	private Fragment_ArticleList fragment;
	private Fragment_Article fragment_Article;
	private String value;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_fragment_communication2);
		loadFragment();
		// setOnclick();
	}

	@Override
	protected void onResume() {
		/**
		 * 设置为横屏
		 */
		if (getRequestedOrientation() != ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) {
			setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
		}
		super.onResume();
	}

	private void loadFragment() {
		// 创建 Fragment管理器对象:管理和这个Activity相关的Fragment
		fm = getSupportFragmentManager();
		// 实例化自定义Fragment
		fragment = 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();
	}

	@Override
	public void onArticleSelected(String title) {
		//回调方法:当fragment中listview点击事件触发时,回调处理
		fragment_Article.tvContent.setText("选中标题:" + title);
	}
}




你可能感兴趣的:(Fragment)