这一节主要复习两个知识点 Fragment与Activity之间的交互 Fragment的回调机制
一、Fragment与Activity之间的交互
Fragment与Activity之间可以通过Fragment.setArgument 方法向Fragment传递参数值,并且通过Fragment.getArgument 方法获取这些传递的参数值。
传递的数据是Bundle bundle 形式为键值对。需要注意的是本例中的onClick_ShowArgument方法是MyFragment中的按钮的单击事件方法,该方法需要放在FragmentArgumentAtivity类中,而不能放在MyFragment类中。
package com.example.fragmentargument_01; import android.annotation.SuppressLint; import android.app.Activity; import android.app.FragmentManager; import android.app.FragmentTransaction; import android.os.Bundle; import android.view.Menu; import android.view.View; import android.widget.EditText; import android.widget.Toast; public class FragmentArgumentActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_fragment_argument); } @SuppressLint("NewApi") public void onClick_sendData(View view){ MyFragment fragment = new MyFragment(); Bundle budle = new Bundle(); budle.putString("name", "hello fragment"); fragment.setArguments(budle); FragmentManager fragmentManager = getFragmentManager(); FragmentTransaction transaction =fragmentManager.beginTransaction(); transaction.add(R.id.main_container, fragment, "fragment"); transaction.commit(); Toast.makeText(this, "数据传送成功", Toast.LENGTH_SHORT); } @SuppressLint("NewApi") public void onClick_ShowArgument(View view){ EditText editText = (EditText)findViewById(R.id.editText); String name = getFragmentManager().findFragmentByTag("fragment").getArguments().getString("name"); editText.setText(name); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.fragment_argument, menu); return true; } }
package com.example.fragmentargument_01; import android.annotation.SuppressLint; import android.app.Fragment; import android.os.Bundle; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @SuppressLint("NewApi") public class MyFragment extends Fragment{ @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // TODO Auto-generated method stub View view = inflater.inflate(R.layout.myfragment, container, false); return view; } @Override public void onDestroyView() { Log.d("name", getArguments().getString("name")); super.onDestroyView(); } }
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <EditText android:id="@+id/editText" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="数据传送成功" /> <Button android:id="@+id/button_02" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="获取数据" android:onClick="onClick_ShowArgument"/> </LinearLayout>
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <Button android:id="@+id/button_01" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="传送数据到Fragment" android:onClick="onClick_sendData" /> <FrameLayout android:id="@+id/main_container" android:layout_width="fill_parent" android:layout_height="fill_parent" ></FrameLayout> </LinearLayout>
注意布局中的button 就行了。就完成了一个简单的交互过程。
二、Fragment的回调机制
本例中两个Fragment :TopFragment和BottomFragment中,假如在TopFragment中有个按钮Button . ButtomFragment有一个EditText,现在要求单击Button,将信息显示在EditText上。当时我想想,这还不简单,在TopFragment得到EditText应该是很简单的事情。当然我想的也没错,技术上是可以实现的,但是Android SDK的初衷不在这里,此前的做法相当于把两个Fragment深深的绑定在一起,并没有很好的保持其独立性,android SDK提供Fragment的目的主要是为了封装,尽可能的保持其独立性。
通常的做法就是将操作EditText的权利交给宿主窗口来处理,或直接将对EditText的操作封装在BottomFragment中,然后再窗口内调用即可。
下面是部分代码
package mobile.android.fragment.callback; import android.app.Activity; import android.app.Fragment; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; public class TopFragment extends Fragment implements OnClickListener { private OnTopButtonClickedListener listener; //提供一个内部接口 提供回调方法 public interface OnTopButtonClickedListener { public void onClick(String name); } @Override public void onAttach(Activity activity) { if(getActivity() instanceof OnTopButtonClickedListener) { listener = (OnTopButtonClickedListener)getActivity(); } super.onAttach(activity); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.top_fragment, null); view.setOnClickListener(this); return view; } public void onClick(View view) { if(listener != null) { listener.onClick("Top Fragment Demo"); } } }
TopFragment.java
package mobile.android.fragment.callback; import mobile.android.fragment.callback.TopFragment.OnTopButtonClickedListener; import android.app.Activity; import android.os.Bundle; public class FragmentCallbackActivity extends Activity implements OnTopButtonClickedListener { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_fragment_callback); } @Override public void onClick(String name) { BottomFragment fragment = (BottomFragment) getFragmentManager() .findFragmentByTag("bottom_fragment"); fragment.updateText("onClick:" + name); } }
FragmentCallbackActivity.java
package mobile.android.fragment.callback; import android.app.Fragment; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.EditText; public class BottomFragment extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater .inflate(R.layout.bottom_fragment, container, false); return view; } public void updateText(String value) { EditText editText = (EditText)getView(); editText.setText(value); } }
BottomFragment.java