Fragment是Android honeycomb 3.0新增的概念,在如何使用Android Fragment中做了关于Fragment的详细介绍。本文则主要是通过实例的方式让大家更直观的了解Fragment的使用方法。
Fragment 设计理念 在设计应用时特别是Android 应用 ,有众多的分辨率要去适应,而fragments 可以让你在不同分辨率的屏幕上动态管理UI。例如:通讯应用程序(QQ),在PAD上可以设计成:用户列表在左边,消息窗口在右边;而在手机上可以设计成:用户列表填充屏幕,当点击某一用户时,再弹出新的对话窗口界面,如下图:
Fragment的生命周期 每一个fragments 都有自己的一套生命周期回调方法和处理自己的用户输入事件。 对应生命周期可参考下图:
其中大多数程序必须使用Fragments 必须实现的三个回调方法分别为: onCreate
系统创建Fragments 时调用,可做执行初始化工作或者当程序被暂停或停止时用来恢复状态,跟Activity 中的onCreate相当. onCreateView 用于首次绘制用户界面的回调方法,必须返回要创建的Fragments 视图UI。假如你不希望提供Fragments 用户界面则可以返回NULL. onPause 当用户离开这个Fragments 的时候调用,这时你要提交任何应该持久的变化,因为用户可能不会回来。更多的事件可以参考上图的生命周期关系图。
Fragment 的类别 系统内置了三种Fragments ,这三种Fragments 分别有不同的应用场景分别为: DialogFragment 对话框式的Fragments,可以将一个fragments 对话框并到activity 管理的fragments back stack 中,允许用户回到一个前曾摒弃fragments. ListFragments 类似于ListActivity 的效果,并且还提供了ListActivity 类似的onListItemCLick和setListAdapter等功能. PreferenceFragments 类似于PreferenceActivity .可以创建类似PAD的设置界面。
Fragment 的详细使用 来看一张效果图: 左边点击时,右边的字符会与左边选中的项的字符相同。与IPAD上的设置界面很相似,这一点是否借鉴了ipad 上的UI呢?
XML文件: <?xml version="1.0" encoding="utf-8"?> <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" > <fragment class="com.itcast.fragment.FragmentDemoActivity$TitlesFragment"android:id="@+id/titles" android:layout_weight="1" android:layout_width="0px" android:layout_height="match_parent"/> <FrameLayout android:id="@+id/details" android:layout_weight="1" android:layout_width="0px" android:layout_height="match_parent" android:background="?android:attr/detailsElementBackground"/> </LinearLayout>
主界面代码: package com.itcast.fragment; import android.app.Activity; import android.app.AlertDialog; import android.app.Fragment; import android.app.FragmentTransaction; import android.app.ListFragment; import android.os.Bundle; import android.util.TypedValue; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.ListView; import android.widget.ScrollView; import android.widget.TextView; public class FragmentDemoActivity extends Activity { public static String[] array={"title1,", " title 2", " title 3", " title4"," title 5,", " title 6", " title 7"," title 8" }; @Override public void onCreate(BundlesavedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } public static classTitlesFragment extends ListFragment { boolean mDualPane; int mCurCheckPosition = 0; @Override public void onCreate(BundlesavedInstanceState) { super.onCreate(savedInstanceState); System.out.println("Fragment-->onCreate"); } @Override public ViewonCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { System.out.println("Fragment-->onCreateView"); returnsuper.onCreateView(inflater, container, savedInstanceState); } @Override public void onPause() { super.onPause(); System.out.println("Fragment-->onPause"); } @Override public void onStop() { super.onStop(); System.out.println("Fragment-->onStop"); } @Override public voidonAttach(Activity activity) { super.onAttach(activity); System.out.println("Fragment-->onAttach"); } @Override public void onStart() { super.onStart(); System.out.println("Fragment-->onStart"); } @Override public void onResume() { super.onResume(); System.out.println("Fragment-->onResume"); } @Override public void onDestroy() { super.onDestroy(); System.out.println("Fragment-->onDestroy"); } @Override public voidonActivityCreated(Bundle savedInstanceState) { // TODO Auto-generatedmethod stub super.onActivityCreated(savedInstanceState); System.out.println("Fragment-->onActivityCreted"); setListAdapter(newArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, array)); View detailsFrame =getActivity().findViewById(R.id.details); mDualPane = detailsFrame!= null &&detailsFrame.getVisibility() == View.VISIBLE; if (savedInstanceState!= null) { //从保存的状态中取出数据 mCurCheckPosition =savedInstanceState.getInt("curChoice", 0); } if (mDualPane) { getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE); showDetails(mCurCheckPosition); } } @Override public voidonSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putInt("curChoice", mCurCheckPosition);//保存当前的下标 } @Override public voidonListItemClick(ListView l, View v, int position, long id) { super.onListItemClick(l,v, position, id); showDetails(position); } void showDetails(int index){ mCurCheckPosition =index; if (mDualPane) { getListView().setItemChecked(index, true); DetailsFragmentdetails = (DetailsFragment) getFragmentManager() .findFragmentById(R.id.details); if (details == null|| details.getShownIndex() != index) { details =DetailsFragment.newInstance(mCurCheckPosition); //得到一个fragment 事务(类似sqlite的操作) FragmentTransaction ft = getFragmentManager() .beginTransaction(); //将得到的fragment 替换当前的viewGroup内容,add则不替换会依次累加 ft.replace(R.id.details, details); //设置动画效果 ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE); ft.commit();//提交 } } else { newAlertDialog.Builder(getActivity()).setTitle( android.R.string.dialog_alert_title).setMessage( array[index]).setPositiveButton(android.R.string.ok, null).show(); } } } /** * 作为界面的一部分,为fragment 提供一个layout * * */ public static classDetailsFragment extends Fragment { public staticDetailsFragment newInstance(int index) { DetailsFragment details= new DetailsFragment(); Bundle args = newBundle(); args.putInt("index", index); details.setArguments(args); return details; } public int getShownIndex() { returngetArguments().getInt("index", 0); } @Override public View onCreateView(LayoutInflaterinflater, ViewGroup container, BundlesavedInstanceState) { // TODO Auto-generatedmethod stub if (container == null) return null; ScrollView scroller =new ScrollView(getActivity()); TextView text = newTextView(getActivity()); int padding = (int)TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, 4, getActivity() .getResources().getDisplayMetrics()); text.setPadding(padding,padding, padding, padding); scroller.addView(text); text.setText(array[getShownIndex()]); return scroller; } } } 注意: 如果你想在Fragment 里面创建menu,则必须在onCreate的时候设置让它可以存在optionMenu才可以创建,代码为: public static class DetailsFragment extends Fragment { @Override public void onCreate(BundlesavedInstanceState) { super.onCreate(savedInstanceState); setHasOptionsMenu(true); } } 之后的操作即可以像平常Android的menu用法一样,代码为: @Override public voidonCreateOptionsMenu(Menu menu, MenuInflater inflater) { super.onCreateOptionsMenu(menu, inflater); menu.add("Menu1a").setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM); menu.add("Menu1b").setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM); } @Override public booleanonOptionsItemSelected(MenuItem item) { Toast.makeText(getActivity(),"index is"+getShownIndex()+" && menu text is"+item.getTitle(), 1000).show(); returnsuper.onOptionsItemSelected(item); }
|