上篇学习了Fragment的静态和动态添加的简单使用,以及生命周期,为了更好的理解和使用fragment,本节结合实际应用,和大家分享fragment与activity之间以及与fragment之间的交互。
1、fragment与activity交互。
activity向fragment传递参数:
在提交事务实例化fragment时将参数传给fragment,在newInstance()方法里调用色图setArguments()将参数保存起来。
在oncreate()方法中getAraguments()将参数取出来使用。
fragment向activity传递参数:
这个采用了接口回调机制,在fragment里定义交互接口,让activity实现接口,fragment生命周期的
onAttach(Activity activity)里将activity强转为接口对象,得到接口实例,调用接口交互方法将参数传回给activity。
例子:
从效果图可以看出,左边是个fragment里面放了listView,点击Item可以将参数传递给Activity,Activiyt接收到参数后根据条件判断替换右边对应的framgent.并将参数传递给替换的fragment。
左边的fragemnt:xml文件:
<FrameLayout 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" tools:context="fragment_demo.fragment.FragmentTwo" android:background="@android:color/holo_blue_bright"> <ListView android:id="@+id/fragment_listview" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </FrameLayout>
package fragment_demo.fragment; import android.app.Activity; import android.app.Fragment; import android.content.Context; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.BaseAdapter; import android.widget.ListView; import android.widget.TextView; import android.widget.Toast; import com.example.call.R; /** * A simple {@link Fragment} subclass. */ public class FragmentTwo extends Fragment implements AdapterView.OnItemClickListener { private ListView mListView; private String[] data = new String[]{"新闻", "电影", "旅游"}; private OnCallBackInter mOnCallBackInter; /*注册与Activity交互的接口*/ public interface OnCallBackInter{ public void OngetMsg(String msg); } @Override /*交互接口*/ public void onAttach(Activity activity) { super.onAttach(activity); mOnCallBackInter = (OnCallBackInter)activity; //得到了实现接口的实例了 } /*返回Fragment实例*/ public static FragmentTwo newInstance(){ FragmentTwo fragmentTwo = new FragmentTwo(); return fragmentTwo; } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View v = inflater.inflate(R.layout.fragment_fragment_two_layout, container, false); mListView = (ListView) v.findViewById(R.id.fragment_listview); FragmentListAdapter adapter = new FragmentListAdapter(getActivity()); adapter.setDataStr(data); mListView.setAdapter(adapter); mListView.setOnItemClickListener(this); return v; } @Override public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) { String str = (String) adapterView.getAdapter().getItem(i); Toast.makeText(getActivity(), str, Toast.LENGTH_SHORT).show(); mOnCallBackInter.OngetMsg(str); //将参数回传给Activity } public class FragmentListAdapter extends BaseAdapter { private String[] dataStr = new String[]{}; private LayoutInflater inflater; public FragmentListAdapter(Context context) { this.inflater = LayoutInflater.from(context); } public void setDataStr(String[] data) { this.dataStr = data; notifyDataSetChanged(); } @Override public int getCount() { return dataStr.length; } @Override public Object getItem(int i) { return dataStr[i]; } @Override public long getItemId(int i) { return i; } @Override public View getView(int i, View view, ViewGroup viewGroup) { if (view == null) { view = inflater.inflate(android.R.layout.simple_list_item_1, null); } TextView txt = (TextView) view; txt.setText((CharSequence) getItem(i)); return view; } } }fragment里传参数给activity,是通过接口回调的方式实现的。
右边的3个fragment几乎相同,这里指贴出一个。
xml布局:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@android:color/holo_red_light"> <!-- TODO: Update blank fragment layout --> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="电影Fragment" android:textSize="20sp" android:layout_centerInParent="true"/> <TextView android:id="@+id/movies_fragment_txt" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="20sp" android:layout_alignParentBottom="true"/> </RelativeLayout>
package fragment_demo.fragment; import android.app.Fragment; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; import com.example.call.R; /** * A simple {@link Fragment} subclass. */ public class MoviesFragment extends Fragment { private static final String ARG_PARAM1 = "param1"; private String mParam1; public MoviesFragment() { // Required empty public constructor } public static MoviesFragment newInstance(String str){ MoviesFragment fragment = new MoviesFragment(); Bundle bundle = new Bundle(); bundle.putString(ARG_PARAM1,str); fragment.setArguments(bundle); return fragment; } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if(getArguments() != null){ mParam1 = getArguments().getString(ARG_PARAM1); } } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment View v = inflater.inflate(R.layout.fragment_movies_layout, container, false); TextView txt = (TextView) v.findViewById(R.id.movies_fragment_txt); txt.setText(mParam1); return v; } }
最后再来看看MainActivity里面做了写什么判断?
MainActivity XML布局:
<?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="horizontal"> <FrameLayout android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:id="@+id/fragment_title_frameLayout"/> <FrameLayout android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="2" android:id="@+id/fragment_content_framentlayout"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/fragment_showTxt" android:layout_gravity="center" android:background="@android:color/holo_purple"/> </FrameLayout> </LinearLayout>
package fragment_demo.fragment; import android.app.Activity; import android.app.FragmentManager; import android.os.Bundle; import android.widget.TextView; import com.example.call.R; public class FragmentMainActivity extends Activity implements FragmentTwo.OnCallBackInter { private TextView mShowTxt; private FragmentManager manager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_fragment_main_layout); mShowTxt = (TextView) findViewById(R.id.fragment_showTxt); manager = getFragmentManager(); manager.beginTransaction().add(R.id.fragment_title_frameLayout, FragmentTwo.newInstance()).commit(); /*这里本应该注册接口的,但是Fragment里的OnAttach()方法已经实现了这一步*/ } @Override /*实现交互接口方法*/ public void OngetMsg(String msg) { if(msg.equals("新闻")) { manager.beginTransaction().replace(R.id.fragment_content_framentlayout, NewsFragment.newInstance(msg)).commit(); }else if (msg.equals("电影")){ manager.beginTransaction().replace(R.id.fragment_content_framentlayout,MoviesFragment.newInstance(msg)).commit(); }else if (msg.equals("旅游")){ manager.beginTransaction().replace(R.id.fragment_content_framentlayout,TravealFragment.newIntance(msg)).commit(); } } }