android fragments

本文详细介绍了Android中的Fragment组件,包括其生命周期、如何与Activity交互、不同类型的Fragment及其应用场景等。此外,还提供了具体的代码示例帮助理解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

fragment总是嵌入一个activity 而且fragment的生命周期总是被它的host activity的生命周期直接影响。

比如:当activity暂停的时候,它所有的fragments都暂停;当activity摧毁的时候,所有的fragments都被摧毁。当activity在运行的时候(它在resumed 生命周期状态),你可以独立操作每一个fragment,比如增加、移除。当你执行一个fragment transaction时,你可以将它加入到activity管理的back stack。activity的back stack记录了发生的fragment transaction。back stack允许用户通过Back 键后撤一次fragment transaction

如果你想迁移一个已有的APP使用fragment,只要把activity的回调移植到你的fragment就可以了。


onCreate()

初始化fragment必要的部件

onCreateView()

fragment第一次绘制UI,你必须返回frame的layout的root view

onPause()

用户离开fragment,你必须提交那些在当前用户会话背后必须一致的change


Fragment的一些子类

(1)DialogFragment

展示一个浮动的对话框

(2)ListFragment

展示被adapter管理 的items list(比如:SimpleCursorAdapter)

(3)PreferanceFragment

对创建一个setting activity很有效


onCreateView(LayoutInflater inflater, ViewGroup container, Bundle saveInstance)

inflate()

参数:(1)layout的resource ID

(2)inflated layout的parent的ViewGroup

(3)是否inflated layout被附着到ViewGroup


如何添加fragment到activity的layout

(1)在layout 文件里面声明

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <fragment android:name="com.example.news.ArticleListFragment"
            android:id="@+id/list"
            android:layout_weight="1"
            android:layout_width="0dp"
            android:layout_height="match_parent" />
    <fragment android:name="com.example.news.ArticleReaderFragment"
            android:id="@+id/viewer"
            android:layout_weight="2"
            android:layout_width="0dp"
            android:layout_height="match_parent" />
</LinearLayout>
android:name 表示Fragment类

(2)在程序里面添加fragment到一个已知的ViewGroup

使用FragmentTransaction的API实现 fragment transactions(比如 add, remove, replace)

<span style="font-size:24px;">FragmentManager fragmentManager = getFragmentManager()
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();</span>
然后使用add()加入一个fragment
<span style="font-size:24px;">ExampleFragment fragment = new ExampleFragment();
fragmentTransaction.add(R.id.fragment_container, fragment);
fragmentTransaction.commit();</span>


如果fragment 没有UI

通过add(Fragment, String)(提供一个唯一的string 标签,而不是用view ID)

这种fragment不用实现onCreateView()

对于没有UI的fragment,只有string tag才能找到它;有UI的fragment,也可以有string tag

findFragmentByTag()


通过getFragmentManager()得到activity的FragmentManager

FragmentManager的功能:

(1)得到activity已有的fragment : finfFragmentById() / findFragmentByTag()

(2)将fragment从back stack 出栈: popBackStack()

(3)为back stack注册一个listener: addOnBackStackChangedListener()


Fragment Transactions:

add() , remove(), replace()

commit() 提交transaction 给activity

在commit()之前,如果调用addToBackStack()可以将这次transaction加入到back stack,这样允许后退键返回到之前的fragment state

<span style="font-size:24px;">// Create new fragment and transaction
Fragment newFragment = new ExampleFragment();
FragmentTransaction transaction = getFragmentManager().beginTransaction();

// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);

// Commit the transaction
transaction.commit();</span>

如果多个transaction之后才调用addToBackStack(),那么按下Back button会倒退这多个的transaction。

如果你在activity保存自己的状态(用户离开这个activity)之后使用commit()提交一个transaction,会出现异常,

这是因为activity恢复之后,commit之后的state会丢失。你可以使用commitAllowingStateLoss()


和 Activity通信

Fragment可以得到activity实例通过 getActivity(), 这样就可以找到这个activity的layout的其他view

View listView = getActivity().findViewById(R.id.list);
同样的,activity得到fragment

ExampleFragment fragment = (ExampleFragment) getFragmentManager().findFragmentById(R.id.example_fragment);


为activity创建event callbacks

如何实现fragment和activity分享events,方法是fragment定义一个接口,然后它的host activity实现这个接口

当activity通过fragment内部的interface接收到事件时,它可以和layout的其他fragment分享这个event
举个例子:

fragment A用ListView显示不同的新闻栏目,fragment B用于选中某个栏目后具体的新闻信息

此时,在fragment A 中实现 OnArticleSelectedListener 接口

public static class FragmentA extends ListFragment {
    ...
    // Container Activity must implement this interface
    public interface OnArticleSelectedListener {
        public void onArticleSelected(Uri articleUri);
    }
    ...
}


然后host activity实现这个接口,重写onArticleSelected()函数,实现通知fragment B来自fragment A的event


为了保证host activity实现这个接口,可以在fragment A的onAttach()函数验证

这里如果强制类型转换成功,说明activity实现了该接口

public static class FragmentA extends ListFragment {
    OnArticleSelectedListener mListener;
    ...
    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        try {
            mListener = (OnArticleSelectedListener) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString() + " must implement OnArticleSelectedListener");
        }
    }
    ...
} 
如果没有实现该接口,会出现类型转换异常 ClassCastException

比如Fragment A继承自ListFragment ,那么每次用户点击一个items, 系统调用onListItemClick(), 在里面用onArticleSelected()来和activity分享这个event

public static class FragmentA extends ListFragment {
    OnArticleSelectedListener mListener;
    ...
    @Override
    public void onListItemClick(ListView l, View v, int position, long id) {
        // Append the clicked item's row ID with the content provider Uri
        Uri noteUri = ContentUris.withAppendedId(ArticleColumns.CONTENT_URI, id);
        // Send the event and Uri to the host activity
        mListener.onArticleSelected(noteUri);
    }
    ...
}
传递给onListItemClick()的参数 id是点击的items的row ID 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值