您的位置:首页 > 其它

Fragment 和 FragmentActivity的使用

2016-06-24 11:47 344 查看
今天学习下
Android中的 Fragment 和 FragmentActivity,因为没有4.0手机,平台是2.3.3 所以我是使用 v4 support 包来进行学习。

要想用Fragment 功能必须先让activity继承FragmentActivity,其原因是里面包含了Fragment运作的FragmentManager接口的实现类 FragmentManagerImpl ,由这个类管理所有Fragment的显示、隐藏

1.使用最简单的Fragment,我们只要继承Fragment就可以

[java]
view plain
copy





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的添加和删除:

[java]
view plain
copy





public class DoorFragmentActivity extends FragmentActivity{  
  
    public static final String FRAG_SMS = "sms_list_frag";  
    public static final String FRAG_TEXT = "text_frag";  
      
    priv
4000
ate 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:

[java]
view plain
copy





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);  
b1f6

            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.主页面的布局文件:

[html]
view plain
copy





<?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.运行效果图:
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: