继承frament和activity添加fragment的区别

68893人阅读
android学习(4)
今天学习下 Android中的 Fragment 和 FragmentActivity,因为没有4.0手机,平台是2.3.3 所以我是使用 v4 support 包来进行学习。
要想用Fragment 功能必须先让activity继承FragmentActivity,其原因是里面包含了Fragment运作的FragmentManager接口的实现类 FragmentManagerImpl ,由这个类管理所有Fragment的显示、隐藏
1.使用最简单的Fragment,我们只要继承Fragment就可以
public class TextFragment extends Fragment{
private String mM
public void setMessage(String message){
this.mMsg =
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));
首先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 mSMSF
private Fragment mTextF
private FragmentManager mFragM
private Button mMenuB
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() {
public void onClick(View v) {
// TODO Auto-generated method stub
showFragments(FRAG_TEXT, true);
mMenuBtn.setOnLongClickListener(new OnLongClickListener() {
public boolean onLongClick(View v) {
// TODO Auto-generated method stub
initFragments();
showFragments(FRAG_SMS, false);
private void initFragments(){
mSMSFragment = new SMSListFragment();
TextFragment textfrag = new TextFragment();
textfrag.setMessage(&这是 菜单界面&);
mTextFragment =
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);
trans.replace(R.id.door_contents_fl, getFragmentByTag(tag), tag);
private Fragment getFragmentByTag(String tag){
if(FRAG_SMS.equals(tag)){
return mSMSF
if(FRAG_TEXT.equals(tag)){
return mTextF
首先我们获取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 mA
private ConversationQuery mQ
private long startT
public void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
mAdapter = new ConversationListAdapter(getActivity());
mQuery = new ConversationQuery(getActivity().getContentResolver());
public void onActivityCreated(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onActivityCreated(savedInstanceState);
setListAdapter(mAdapter);
public void onStart() {
// TODO Auto-generated method stub
super.onStart();
startAsyncQuery();
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
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=&/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& &
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.运行效果图:
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:88632次
排名:千里之外
评论:21条Frament&与&Activity&生命周期
官方文档中有详细的文字说明,不过最好还是实践下,熟悉过程。/guide/components/fragments.html
一、Activity的生命周期图:
<img src="/blog7style/images/common/sg_trans.gif" real_src ="http://img.my.csdn.net/uploads//_2659.png" ALT="" STYLE="border-style: max-width: 100%;"
TITLE="Frament&与&Activity&生命周期" />
二、Fragment生命周期图
<img src="/blog7style/images/common/sg_trans.gif" real_src ="http://img.my.csdn.net/uploads//_2990.png" ALT="" STYLE="border-style: max-width: 100%;"
TITLE="Frament&与&Activity&生命周期" />
三、对比图
<img src="/blog7style/images/common/sg_trans.gif" real_src ="http://img.my.csdn.net/uploads//_4818.png" ALT="" STYLE="border-style: max-width: 100%;"
TITLE="Frament&与&Activity&生命周期" />
四、测试代码:
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。1、 中的 android:name属性指定了在layout中实例化的Fragment类.
当系统创建这个activity layout时,它实例化每一个在layout中指定的fragment,并调用每一个上的onCreateView()方法,来获取每一个 fragment的layout.系统将从fragment返回的 View直接插入到元素所在的地方.
2、通过在xml中定义fragment的方式,我们不能在运行时移除fragment。如果我们想要通过切换fragments来跟用户有更好的互动,那么就需要在activity启动的时候定义fragment了。
2.2、在运行时添加一个Fragment到Activity
上面一节的在activity的布局文件(layout xml)中添加Fragment的方法我们已经知道了。现在我们将学习另外一种方式,这种方式允许我们在运行时动态的显示和隐藏fragment。为了达到在activity中动态管理Fragment,我们需要用到FragmentManager,并且通过它创建FragmentTransaction。
activity允许移除或者替换fragment需要有如下条件:
1、activity的onCreate()方法中添加初始化的fragment
2、fragment放置位置的布局中必须有一个视图容器
比如:res/layout/news_articles.xml文件提供了视图容器。
&frameLayout xmlns:android="/apk/res/android"
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" /&
Activity中使用getSupportFragmentManager()获取FragmentManager,之后调用beginTransaction去创建一个FragmentTransaction对象, 再调用add()方法即可添加一个fragment。 在activity中可以使用同一个FragmentTransaction对象去执行多个fragment事务,当做这样操作时,必须调用commint()方法。 下面的代码演示怎样添加一个fragment到res/layout/news_articles.xml的layout:import android.os.B
import android.support.v4.app.FragmentA
public class MainActivity extends FragmentActivity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.news_articles);
if (findViewById(R.id.fragment_container) != null) {
if (savedInstanceState != null) {
HeadlinesFragment firstFragment = new HeadlinesFragment();
firstFragment.setArguments(getIntent().getExtras());
// Add the fragment to the 'fragment_container' FrameLayout
getSupportFragmentManager().beginTransaction()
.add(R.id.fragment_container, firstFragment).commit();
add()的第一个参数是fragment要放入的ViewGroup, 由resource ID指定,第二个参数是需要添加的fragment.一旦用FragmentTransaction做了改变,为了使改变生效,必须调用commit().PS
现在再来说明另外一个实例,实例图如下,我要在四个标签页面切换(主页,手机,配件,购物车)
代码如下,具体就是通过影藏和显示fragment来实现切换
import android.os.B
import android.support.v4.app.F
import android.support.v4.app.FragmentA
import android.view.V
import android.view.W
public class FramentMainActivity extends FragmentActivity {
private Fragment[]
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_frament_main);
fragments = new Fragment[4];
fragments[0] = getSupportFragmentManager().findFragmentById(R.id.farment_main);
fragments[1] = getSupportFragmentManager().findFragmentById(R.id.farment_phone);
fragments[2] = getSupportFragmentManager().findFragmentById(R.id.farment_accessory);
fragments[3] = getSupportFragmentManager().findFragmentById(R.id.farment_cart);
getSupportFragmentManager().beginTransaction().
hide(fragments[1]).hide(fragments[2]).hide(fragments[3]).show(fragments[0]).commit();
public void mainClick(View view){
getSupportFragmentManager().beginTransaction().hide(fragments[1]).hide(fragments[2]).hide(fragments[3]).show(fragments[0]).commit();
public void phoneClick(View view){
getSupportFragmentManager().beginTransaction().hide(fragments[0]).hide(fragments[2]).hide(fragments[3]).show(fragments[1]).commit();
public void accessoryClick(View view){
getSupportFragmentManager().beginTransaction().hide(fragments[0]).hide(fragments[1]).hide(fragments[3]).show(fragments[2]).commit();
public void cartClick(View view){
getSupportFragmentManager().beginTransaction().hide(fragments[0]).hide(fragments[1]).hide(fragments[2]).show(fragments[3]).commit();
3、Frament 管理
要管理 fragment,需使用 FragmentManager,要获取它,需在 activity 中调用方法 getFragmentManager()。 可以用 FragmentManager 来做以上事情:
使用方法 findFragmentById()或 findFragmentByTag(),获取 activity 中已存在的 fragment
使用方法 popBackStack()从 activity 的后退栈中弹出 fragment(这可以模拟后退键引发的动作)
用方法 addOnBackStackChangedListerner()注册一个侦听器以监视后退栈的变化
还可以使用 FragmentManager 打开一个 FragmentTransaction 来执行 fragment 的事务,比如添加或删除 fragment。
在 activity 中使用 fragment 的一个伟大的好处是能跟据用户的输入对 fragment 进行添加、删除、替换以及执行 其它动作的能力。提交的一组 fragment 的变化叫做一个事务。事务通过 FragmentTransaction 来执行。还可以把每个 事务保存在 activity 的后退栈中,这样就可以让用户在 fragment 变化之间导航(跟在 activity 之间导航一样)。
可以通过 FragmentManager 来取得 FragmentTransaction 的实例,如下:
FragmentManagerfragmentManager = getFragmentManager();
FragmentTransactionfragmentTransaction =fragmentManager.beginTransaction();
一个事务是在同一时刻执行的一组动作(很像数据库中的事务)。可以用 add(),remove(),replace()等方法构成事务,最后使用 commit()方法提交事务。在调用 commint()之前,可以用addToBackStack()把事务添加到一个后退栈中, 这个后退栈属于所在的 activity。有了它,就可以在用户按下返回键时,返回到 fragment 执行事务之前的状态。如 下例:演示了如何用一个 fragment 代替另一个 fragment,同时在后退栈中保存被代替的
fragment 的状态。
4、为Activity创建事件回调方法
在一些情况下, 你可能需要一个fragment与activity分享事件. 一个好的方法是在fragment中定义一个回调的interface, 并要求宿主activity实现它.当activity通过interface接收到一个回调, 必要时它可以和在layout中的其他fragment分享信息.
例如, 如果一个新的应用在activity中有2个fragment}

我要回帖

更多关于 activity获取fragment 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信