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(); } }
Bundle bundle=getArguments(); String value= bundle.getString("left");
由于Fragment 是Activity中的一部分,在Fragment中可以通过getActivity();获得其所在Activity的对象
Context context = getActivity();同理:在Fragment中获得Activity中的其他控件,获得控件对象,自然也就获得该控件的其他内容
// 获得当前Activity中的文本框对象 EditText editText = (EditText) getActivity().findViewById(R.id.et_text_activity);
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); }
此种情况针对一个Activity中包含两个或两个以上Fragment之间的通讯,下面代码,我们以一个选择文章阅读的为例进行讲解(即左侧Fragment是一个文章选择列表,右侧Fragment是一个文章内容,选择左侧文章标题,右侧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>
由于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); }; }
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; } }
注意:此处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); } }