Fragment 和 FragmentActivity的使用
2013-12-02 15:36
183 查看
今天学习下 Android中的 Fragment 和 FragmentActivity,因为没有4.0手机,平台是2.3.3 所以我是使用 v4 support 包来进行学习。
要想用Fragment 功能必须先让activity继承FragmentActivity,其原因是里面包含了Fragment运作的FragmentManager接口的实现类 FragmentManagerImpl ,由这个类管理所有Fragment的显示、隐藏
1.使用最简单的Fragment,我们只要继承Fragment就可以
首先Fragment 就可以把它当作一个view , 只不过这个view 与 activity一样有了生命周期函数
Fragment.onCreateView() 函数就是用于生成这个Fragment布局的view的,类似baseadapter.getView()
这样一个包含一个TextView的简单布局就完成了。
2.重写我们自己的FragmentActivity.
这里面主要要通过FragmentManager 来进行Fragment的添加和删除:
首先我们获取FragmentManager实现:直接调用 FragmentActivity.getSupportFragmentManager(),看源码可以知道这返回的是FragmentManager内部定义的实现类FragmentManagerImpl。
我们获取了FragmentManagerImpl后我们其实不咋操作这个类,只调用FragmentManager.beginTransation(),这个获取FragmentTransation接口的实现类(里面具体是BackStackRecord类的实例),我们关于Fragment的所有操作都是通过它来完成的,因为没仔细研究,我只了解直接自己在代码里面定义Fragment而没有在xml里面写(xml写觉得有点别扭)
我们主要通过 FragmentTransation的一些方法来处理Fragment的:
1) trans.add(fragment, tag); 这个实际是 containerViewId = 0 调用的3)
2) trans.add(containerViewId, fragment); 这个实际是 tag = null 调用的 3)
3) trans.add(containerViewId, fragment, tag); 如果containerViewId != 0实际上调用的是获取到
fragment的 onCreateView方法返回的view 并加入到containerViewId这个viewgroup中去即
viewgroup.addView(fragment.onCreateView());
未解决问题:containerViewId = 0 的时候代表什么??
4) trans.replace(containerViewId, fragment) 一样是null tag调用 5)
5) trans.replace(containerViewId, fragment, tag) 这个一样是添加一个fragment到对应的container中去,只不过比add多了一步对相同containerViewId中已有的fragment检索,进行removeFragment操作,再去添加这个新来的fragment
6) trans.addToBackStack(tag); 如果你的fragment对于back键有类似activity的回退响应,就要记得把它加入到里面去,trans里面模拟了栈,但是我的回退没有响应我设置的exit anim 这个无语还没解决
3.再使用下ListFragment,我这里写的是SMSListFragment继承了ListFragment:
onCreate()中完成自己要一次性初始的东西,我在里面主要是初始化一个adapter和一个对sms数据库的查询
在onActivityCreated()中将adapter设置给listview,这个不确定有没有更好的位置,
然后进入我们熟悉的生命周期方法:
onStart()中,开启查询
onStop()中,我们界面已经不在显示了,所以我们不关心数据库变化了,close cursor
4.主页面的布局文件:
要想用Fragment 功能必须先让activity继承FragmentActivity,其原因是里面包含了Fragment运作的FragmentManager接口的实现类 FragmentManagerImpl ,由这个类管理所有Fragment的显示、隐藏
1.使用最简单的Fragment,我们只要继承Fragment就可以
public class TextFragment extends Fragment{ private String mMsg; public void setMessage(String message){ this.mMsg = message; } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // TODO Auto-generated method stub final Context context = getActivity(); FrameLayout root = new FrameLayout(context); root.setBackgroundColor(Color.YELLOW); TextView tv = new TextView(context); tv.setText(mMsg); tv.setGravity(Gravity.CENTER); root.addView(tv, new FrameLayout.LayoutParams( ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT)); return root; } }
首先Fragment 就可以把它当作一个view , 只不过这个view 与 activity一样有了生命周期函数
Fragment.onCreateView() 函数就是用于生成这个Fragment布局的view的,类似baseadapter.getView()
这样一个包含一个TextView的简单布局就完成了。
2.重写我们自己的FragmentActivity.
这里面主要要通过FragmentManager 来进行Fragment的添加和删除:
public class DoorFragmentActivity extends FragmentActivity{ public static final String FRAG_SMS = "sms_list_frag"; public static final String FRAG_TEXT = "text_frag"; private Fragment mSMSFragment; private Fragment mTextFragment; private FragmentManager mFragMgr; private Button mMenuBtn; @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.door_fragment_activity_layout); mFragMgr = getSupportFragmentManager(); mMenuBtn = (Button) findViewById(R.id.door_menu_btn); mMenuBtn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub showFragments(FRAG_TEXT, true); } }); mMenuBtn.setOnLongClickListener(new OnLongClickListener() { @Override public boolean onLongClick(View v) { // TODO Auto-generated method stub return false; } }); initFragments(); showFragments(FRAG_SMS, false); } private void initFragments(){ mSMSFragment = new SMSListFragment(); TextFragment textfrag = new TextFragment(); textfrag.setMessage("这是 菜单界面"); mTextFragment = textfrag; } private void showFragments(String tag, boolean needback){ FragmentTransaction trans = mFragMgr.beginTransaction(); if(needback){ trans.setCustomAnimations(R.anim.frag_enter, R.anim.frag_exit); trans.add(R.id.door_root_content_fl, getFragmentByTag(tag), tag); trans.addToBackStack(tag); }else{ trans.replace(R.id.door_contents_fl, getFragmentByTag(tag), tag); } trans.commit(); } private Fragment getFragmentByTag(String tag){ if(FRAG_SMS.equals(tag)){ return mSMSFragment; } if(FRAG_TEXT.equals(tag)){ return mTextFragment; } return null; } }
首先我们获取FragmentManager实现:直接调用 FragmentActivity.getSupportFragmentManager(),看源码可以知道这返回的是FragmentManager内部定义的实现类FragmentManagerImpl。
我们获取了FragmentManagerImpl后我们其实不咋操作这个类,只调用FragmentManager.beginTransation(),这个获取FragmentTransation接口的实现类(里面具体是BackStackRecord类的实例),我们关于Fragment的所有操作都是通过它来完成的,因为没仔细研究,我只了解直接自己在代码里面定义Fragment而没有在xml里面写(xml写觉得有点别扭)
我们主要通过 FragmentTransation的一些方法来处理Fragment的:
1) trans.add(fragment, tag); 这个实际是 containerViewId = 0 调用的3)
2) trans.add(containerViewId, fragment); 这个实际是 tag = null 调用的 3)
3) trans.add(containerViewId, fragment, tag); 如果containerViewId != 0实际上调用的是获取到
fragment的 onCreateView方法返回的view 并加入到containerViewId这个viewgroup中去即
viewgroup.addView(fragment.onCreateView());
未解决问题:containerViewId = 0 的时候代表什么??
4) trans.replace(containerViewId, fragment) 一样是null tag调用 5)
5) trans.replace(containerViewId, fragment, tag) 这个一样是添加一个fragment到对应的container中去,只不过比add多了一步对相同containerViewId中已有的fragment检索,进行removeFragment操作,再去添加这个新来的fragment
6) trans.addToBackStack(tag); 如果你的fragment对于back键有类似activity的回退响应,就要记得把它加入到里面去,trans里面模拟了栈,但是我的回退没有响应我设置的exit anim 这个无语还没解决
3.再使用下ListFragment,我这里写的是SMSListFragment继承了ListFragment:
public class SMSListFragment extends ListFragment{ private ConversationListAdapter mAdapter; private ConversationQuery mQuery; private long startTime; @Override public void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); mAdapter = new ConversationListAdapter(getActivity()); mQuery = new ConversationQuery(getActivity().getContentResolver()); } @Override public void onActivityCreated(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onActivityCreated(savedInstanceState); setListAdapter(mAdapter); } @Override public void onStart() { // TODO Auto-generated method stub super.onStart(); startAsyncQuery(); } @Override public void onStop() { // TODO Auto-generated method stub super.onStop(); mAdapter.getCursor().close(); mAdapter.changeCursor(null); } public void startAsyncQuery() { startTime = System.currentTimeMillis(); mQuery.startQuery(1, null, Conversation.sAllThreadsUri, Conversation.ALL_THREADS_PROJECTION, null, null, Conversation.CONVERSATION_ORDER); } private final class ConversationQuery extends AsyncQueryHandler { public ConversationQuery(ContentResolver cr) { super(cr); // TODO Auto-generated constructor stub } @Override protected void onQueryComplete(int token, Object cookie, Cursor cursor) { // TODO Auto-generated method stub System.out.println("conversation cursor size : " + cursor.getCount()); mAdapter.changeCursor(cursor); Toast.makeText( getActivity(), "查询短信会话个数:" + cursor.getCount() + ",花费" + (System.currentTimeMillis() - startTime) + " ms", Toast.LENGTH_LONG).show(); } } }代码中可以知道和使用普通的ListActivity完全没区别,
onCreate()中完成自己要一次性初始的东西,我在里面主要是初始化一个adapter和一个对sms数据库的查询
在onActivityCreated()中将adapter设置给listview,这个不确定有没有更好的位置,
然后进入我们熟悉的生命周期方法:
onStart()中,开启查询
onStop()中,我们界面已经不在显示了,所以我们不关心数据库变化了,close cursor
4.主页面的布局文件:
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/door_root_content_fl" android:layout_width="match_parent" android:layout_height="match_parent" > <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <FrameLayout android:id="@+id/door_contents_fl" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" /> <LinearLayout android:layout_width="match_parent" android:layout_height="55dp" android:orientation="horizontal" > <Button android:id="@+id/door_menu_btn" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:text="菜单" /> </LinearLayout> </LinearLayout> </FrameLayout>5.运行效果图:
相关文章推荐
- 在Fragment中使用startActivityForResult和onActivityResult
- Android 实现同个Activity中存在多个Fragment多次切换之后依次返回(一)(Fragment回退栈简单使用)
- activity使用fragment transaction.commit()进行fragment切换,activity被系统回收后再点应用就无法切换
- 根据业务场景使用Fragment或Activity
- Fragment 和 FragmentActivity的使用
- android使用viewPager和Fragment实现滑动切换activity!
- Fragment 和 FragmentActivity的使用
- 在使用fragment的activity双击点击退出程序
- 在fragment中使用onActivityResult
- Android开发丶使用DialogFragment实现炫酷的登录界面并实现DialogFragment与宿主Activity的通信
- Android Fragment的使用 三 Fragment与Activity交互
- Fragment 和 FragmentActivity的使用
- 转 Fragment 和 FragmentActivity的使用
- activity中动态嵌套使用fragment的方法
- 面试集锦—Fragment中使用父Activity的属性和方法
- android中使用fragment时出现如下错误 java.lang.RuntimeException: Unable to start activity ComponentInfo{com.fra
- Fragment与Activity交互(使用Handler)
- 使用fragment在activity中传值的例子
- Activity & Fragment Transition学习概要--使用步骤
- Activity详解、Intent使用、Fragment详解-Android基础知识整理