Frame是Android3.0才出来的一个控件,在过去咱们显示的都彩Activity而后进行设计,而Frame出来是为了使一个窗口里面可以具备多个Activity。html
经过下图下分析,Frame能够在窗口内嵌入多个fragments,接下来的会给出源码来实现下面的功能, ,主要完成的任务是当你点击左侧的listView项,右边的fragments内容是随着你的更新而更新的。android
OnCreate:当你须要在建立frame时对一些组件进行相应的初始化,就能够在这里面写。api
onCreateView:当你须要绘制一个界面的时候就须要调用这个回调的方法来返回一个view对象,若是你不想使用任何的界面时能够返回null,还有注意的一件事情是当你横竖屏切换的时候会屡次回调这个方法。app
onPause():当用户离开这个fragment的时候会回调这个方法,而离开并不表明这个应用的结束ide
DialogFragment:这个方法是用于绘制一个对话框,这个对话框采用栈的方法,当你结束后能够返回前一个窗体。函数
ListFragment:这个相似listView,显示一个列表,列表中的项能够经过adapter(好比一个SimpleCursorAdapter)
来指定列表的项内容,当你单击的时候一样跟ListView
同样会有一个onListItemClick()
回调的函数,来进行单击列表项时的操做。
布局
PreferenceFragment
:这个fragment
的做用相似于
PreferenceActivity
,
显示一个
Preference
对象的层次结构的列表
,就是用户设置界面来理解就能够了。
this
增长界面:
一般Fragment
的界面采用interface
的方式来选择一个以有的layout XML
文件来设计界面,经过前面的知识咱们能够了解到,Fragments
有一个oncreateView()
的回调方法来决定显示的界面,那么就能够在里面用infalter
来选择,并且返回一个View
对象。
spa
传入
onCreateView()
的
container
参数是你的
fragment layout
将要插入的父
ViewGroup
(来自
activity
的
layout
)。
savedInstanceState
参数是一个
Bundle
,若是
fragment
是被恢复的,它提供关于
fragment
的以前的实例的数据。
设计
inflate()
方法有
3
个参数:
想要加载的layout的resource ID。
加载的layout的父ViewGroup。
传入container是很重要的,目的是为了让系统接受所要加载的layout的根view的layout参数,
由它将挂靠的父view指定。
布尔值指示在加载期间,展开的layout是否应当附着到ViewGroup (第二个参数)。
(在这个例子中, 指定了false, 由于系统已经把展开的layout插入到container – 传入true会在最后的layout中建立一个多余的view group。)
@Override publicView onCreateView(LayoutInflater inflater,ViewGroup container, Bundle savedInstanceState){ // Inflate the layout for this fragment return inflater.inflate(R.layout.example_fragment, container,false); } }publicstaticclassExampleFragmentextendsFragment{
添加一个Fragment
到activity
中:
咱们能够把Fragment
加入到一个Activity
的Layout
布局文件中,须要注意的是name
属性的做用就是指定一个fragment Class
到布局文件中。
有
3
种方法来为一个
fragment
提供一个标识:
为 android:id 属性提供一个惟一ID。
为 android:tag 属性提供一个惟一字符串。
若是以上2个你都没有提供,系统使用容器view的ID。
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="match_parent"> <fragmentandroid:name="com.example.news.ArticleListFragment" android:id="@+id/list" android:layout_weight="1" android:layout_width="0dp" android:layout_height="match_parent"/> <fragmentandroid:name="com.example.news.ArticleReaderFragment" android:id="@+id/viewer" android:layout_weight="2" android:layout_width="0dp" android:layout_height="match_parent"/> </LinearLayout><?xml version="1.0" encoding="utf-8"?>
而且fragment
能够添加到viewgroup
里面。
FragmentTransaction fragmentTransaction = fragmentManager.; 此时你就能够彩Add方法来添加一个view来插入到viewgrou中了 fragmentTransaction.add(R.id.fragment_container, fragment); fragmentTransaction.commit();FragmentManager fragmentManager = getFragmentManager()beginTransaction()ExampleFragment fragment =newExampleFragment();
还有,
当你添加完成后必定要调用commit
()方法,这个方法的做用相似于Sqllite
中的事务,只要你调用这个方法才会提交你所作的操做。
下图是不一样时期会回调的函数
例子:
那么咱们仍是采用官方的案例来说解吧,那么最终完成的功能以下图所示,左边是标题列表,右边是根据你的选择来显示相应的内容。
首先咱们须要设计一个layout:
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="match_parent"android:layout_height="match_parent"> <fragmentclass="com.example.android.apis.app.FragmentLayout$TitlesFragment" android:id="@+id/titles"android:layout_weight="1" android:layout_width="0px"android:layout_height="match_parent"/> <FrameLayoutandroid:id="@+id/details"android:layout_weight="1" android:layout_width="0px"android:layout_height="match_parent" android:background="?android:attr/detailsElementBackground"/> </LinearLayout>
当完成XML的设计后咱们还须要在Activity中的oncreate应用这个局面文件
protectedvoid onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.fragment_layout); } TitleFragment是继承listFragment主要用于标题的显示。 publicstaticclassTitlesFragmentextendsListFragment{ boolean mDualPane; int mCurCheckPosition =0; @Override //下面的回调方法是用来设计你的帘布 publicvoid onActivityCreated(Bundle savedInstanceState){ super.onActivityCreated(savedInstanceState); // 经过setListAdapter来进行绑定列表项,simple_list_item_activated_1是系统自定义的,采用的是text来显示列表项。 setListAdapter(newArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_activated_1,Shakespeare.TITLES)); View detailsFrame = getActivity().findViewById(R.id.details); mDualPane = detailsFrame !=null&& detailsFrame.getVisibility()==View.VISIBLE; if(savedInstanceState !=null){ // 恢复你最后选择的状态。 mCurCheckPosition = savedInstanceState.getInt("curChoice",0); } if(mDualPane){ // In dual-pane mode, the list view highlights the selected item. getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE); // Make sure our UI is in the correct state. showDetails(mCurCheckPosition); } } @Override publicvoid onSaveInstanceState(Bundle outState){ super.onSaveInstanceState(outState); outState.putInt("curChoice", mCurCheckPosition); } @Override //当你单击列表项就会回调这个方法,其中position是你单击项的下标,showDetails函数的做用是经过你传送的标题项来进行内容的选择。 publicvoid onListItemClick(ListView l,View v,int position,long id){ showDetails(position); } /** * Helper function to show the details of a selected item, either by * displaying a fragment in-place in the current UI, or starting a * whole new activity in which it is displayed. */ void showDetails(int index){ mCurCheckPosition = index; if(mDualPane){ // We can display everything in-place with fragments, so update // the list to highlight the selected item and show the data. getListView().setItemChecked(index,true); // Check what fragment is currently shown, replace if needed. DetailsFragment details =(DetailsFragment) getFragmentManager().findFragmentById(R.id.details); if(details ==null|| details.getShownIndex()!= index){ //从新设计一张新的视图来显示你所选择标题的正文内容。 details =DetailsFragment.newInstance(index); // 执行一个事务来替代之前存在的fragment FragmentTransaction ft = getFragmentManager().beginTransaction(); ft.replace(R.id.details, details); ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE); ft.commit(); } }else{ //不然用一个新的DetailsActivity的来进行显示。 // the dialog fragment with selected text. Intent intent =newIntent(); intent.setClass(getActivity(),DetailsActivity.class); intent.putExtra("index", index); startActivity(intent); } } } DetailsFragment类:经过TitlesFragment来显示相应的正文。 publicstaticclassDetailsFragmentextendsFragment{ /** * Create a new instance of DetailsFragment, initialized to *经过传送过来的Index来选择相应的内容 */ publicstaticDetailsFragment newInstance(int index){ DetailsFragment f =newDetailsFragment(); // Supply index input as an argument. Bundle args =newBundle(); args.putInt("index", index); f.setArguments(args); return f; } publicint getShownIndex(){ return getArguments().getInt("index",0); } @Override publicView onCreateView(LayoutInflater inflater,ViewGroup container, Bundle savedInstanceState){ if(container ==null){ // We have different layouts, and in one of them this // fragment's containing frame doesn't exist. The fragment // may still be created from its saved state, but there is // no reason to try to create its view hierarchy because it // won't be displayed. Note this is not needed -- we could // just run the code below, where we would create and return // the view hierarchy; it would just never be used. returnnull; } ScrollView scroller =newScrollView(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(Shakespeare.DIALOGUE[getShownIndex()]); return scroller; } }