安卓中fragment的使用全解
来源:互联网 发布:potplayermini优化版 编辑:程序博客网 时间:2024/06/05 15:24
全栈工程师开发手册 (作者:栾鹏)
安卓教程全解
安卓中Fragment可以没有UI,不需要manifest中注册,只能嵌套在一个activity存在。
在Fragment基础上,系统派生处理另外几种fragment
1、DialogFragment:一个fragment可以在fragment的父activity上显示一个浮动的对话框,而且可以自定义对话框的UI
2、ListFragment:可以通过绑定数据源呈现一个Listview作为它主要的UI展示方式
3、WebViewFragment:封装了WebView,当Fragment被暂停或恢复时,子WebView同样会被暂停和恢复
fragment布局在activity的方式
在activity中设置fragment有2种方式。
1、在xml中设置一个FrameLayout的容器,使用java为其添加一个fragment。
2、在xml中直接引用自定义的fragment。
我们设置activity的UI如下:一个空的fragment容器:FrameLayout,一个自定义Fragment,一个自定义ListFragment。
activity_frament.xml
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <!-- 作为自定义fragment的父容器,在java中去填充这个容器 --> <FrameLayout android:id="@+id/activity_fragment_container" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" android:background="@color/red" /> <!-- 直接引用java中自定义的Fagment,必须为该fragment设置id或tag --> <fragment android:name="com.lp.app.Fragment1" android:id="@+id/activity_fragment_item" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="3" android:background="@color/green" /> <!-- 直接引用java中自定义的ListFragment,必须为该fragment设置id或tag --> <fragment android:name="com.lp.app.Fragment_list" android:id="@+id/activity_fragment_list" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="3" android:background="@color/blue" /> </LinearLayout>
在activity中使用java操作Fragment、ListFragment
对于在UI 的xml文件中设置的fragment容器FrameLayout,和直接引用的自定义Fragment、ListFragment,我们分别进行操作示例。
1、在activity的java中操作Fragment
包括向容器中添加fragment(add),查找fragment(findFragmentById、findFragmentByTag),fragment的隐藏(hide),显示(show)、删除(remove),替换容器中的fragment(replace),fragment入栈(addToBackStack),事务提交动画(setTransition),事务提交(commit),事务立即执行(executePendingTransactions)。
public void fragmentmanagerfun(){ FragmentManager fragmentmanager=getFragmentManager(); //每个activity都包含一个Fragment Manager来管理它所包含的Fragment FragmentTransaction fragmentTransaction =fragmentmanager.beginTransaction(); // //添加fragment fragmentTransaction.add(R.id.activity_fragment_container, Fragment1.newInstance("这是第1个fragment"),"tag1"); //将fragment的实例添加到容器view中(若fragment没有UI,则不需要容器),同时可以为fragment添加tag名称 fragmentTransaction.add(R.id.activity_fragment_container, new Fragment1(),"tag2"); //一个FrameLayout可以添加多层fragment fragmentTransaction.add(new Fragment1(),"tag3"); //可以添加没有ui的fragment fragmentTransaction.commit(); //保存修改,一个fragmentTransaction只能使用一次commit,方法并不会立即执行事务 fragmentmanager.executePendingTransactions(); //立即执行上面的事务。 FragmentTransaction fragmentTransaction1 =fragmentmanager.beginTransaction(); //使用保存后,需要重新创建一个才能再次使用保存 //查询fragment,获取引用 Fragment fragment1=fragmentmanager.findFragmentById(R.id.activity_fragment_item); //只能查找布局文件中的fragment Fragment fragment2=fragmentmanager.findFragmentByTag("tag2"); //通过tag查找java文件中添加的fragment,没保存前无法找到 //判断是否被添加到了容器中 if(fragment2.isAdded()) { //隐藏当前的Fragment,仅仅是设为不可见,并不会销毁 fragmentTransaction1.hide(fragment2); //显示之前隐藏的Fragment fragmentTransaction1.show(fragment2); //删除fragment fragmentTransaction1.remove(fragment2); //去除fragment,跟add是相反操作(无法移除在xml中添加的) } //替换fragment fragmentTransaction1.replace(R.id.activity_fragment_container, Fragment1.newInstance("这是第2个fragment"),"tag3"); //替换fragment,先remove容器下层的一个fragment,再加入一个fragment,同时可以为fragment添加tag名称 String tag=null; fragmentTransaction1.addToBackStack(tag); //在提交前将当前fragment视图保存到由宿主 Activity管辖的后退栈中(通过点击back按钮更换的视图) //调用 addOnBackStackChangedListener() 方法注册监听器,用于监听后退栈的变化。 fragmentTransaction1.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN); //使事务变化动起来,使用系统过渡动画 fragmentTransaction1.setCustomAnimations(R.animator.anim1, R.animator.anim1); //使用自定义动画,前者应用到添加的fragment中,后者应用到删除的fragment中 fragmentTransaction1.commit(); //保存修改,只能使用一次commit }
2、在父activity的java中操作ListFragment(设置更改ListFragment的绑定数据)
private ArrayAdapter<String> aa=null; private ArrayList<String> items = new ArrayList<String>(); //在activity中设置listfragment的数据 public void listfragmentfun() { FragmentManager fragmentmanager=getFragmentManager(); Fragment_list fragment_list=(Fragment_list)fragmentmanager.findFragmentById(R.id.activity_fragment_list); items.clear(); for (int i = 0; i < 5; i++) { items.add("新选项" + i); } aa=new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,items); fragment_list.setListAdapter(aa);}
Fragment的生命周期
可以看到Fragment比Activity多了几个额外的生命周期回调方法:
onAttach(Activity)
当Fragment与Activity发生关联时调用。
onCreateView(LayoutInflater, ViewGroup,Bundle)
创建该Fragment的视图
onActivityCreated(Bundle)
当Activity的onCreate方法返回时调用
onDestoryView()
与onCreateView想对应,当该Fragment的视图被移除时调用
onDetach()
与onAttach相对应,当Fragment与Activity关联被取消时调用
注意:除了onCreateView,其他的所有方法如果你重写了,必须调用父类对于该方法的实现,
通过自定义fragment文件Fragment1 .java来实现fragment的全部生命周期函数
import com.lp.app.R; import android.app.Activity;import android.app.Fragment;import android.content.Context;import android.os.Bundle;import android.util.Log;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.TextView;public class Fragment1 extends Fragment{ Context context; //指向父activity //activity在构造时向fragment传递参数。不使用构造函数,使用为activity重新创建,下属fragment的字段会丢失,bundle会保留 private static final String ARG = "arg"; public static Fragment1 newInstance(String arg) { Fragment1 fragment = new Fragment1(); Bundle bundle = new Bundle(); bundle.putString(ARG, arg); fragment.setArguments(bundle); //在fragment内通过getArguments读取参数 return fragment; } //在fragment内部调用获取参数 public String getArg() { String arg = "这是一个fragment"; //默认参数值 if(getArguments()!=null) arg = getArguments().getString(ARG); return arg; } //调用该方法时Fragment会被连接到它的父activity上 @Override public void onAttach(Activity activity) { super.onAttach(activity); Log.v("frament生命周期", "fragment连接到activity"); } //调用该方法来进行Fragment的初始创建 @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); context = getActivity(); //获得对父activity的引用 //初始化fragment Log.v("frament生命周期", "fragment初始化"); } //一但Fragment已被创建,要创建它自己的用户界面时调用该方法。填充UI,获取控件引用,设置函数,创建service和timer。没有界面时不需要此函数 //可以直接控制fragment中的控件,并可以调用接口函数,实现调用父activity中函数 @Override public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) { //创建或者填充Fragment的UI,并返回它,如果这个Fragment没有UI,那么返回null View view = inflater.inflate(R.layout.mylinearlayout, container, false); final TextView myTextView = (TextView)view.findViewById(R.id.mylinearlayout_text1); myTextView.setText(getArg()); //设置控件属性,或事件函数,这里读取了存储在fragment中的参数 Log.v("frament生命周期", "fragment创建UI"); return view; } //一旦父activity和Fragment的UI已被创建,则调用该方法 @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); //完成Fragment的初始化,尤其是那些父activity被初始化完成后或者Fragment的view被完全填充后才能做的事情 Log.v("frament生命周期", "fragment的ui已创建"); } // 在可见生命周期的开始时被调用 @Override public void onStart(){ super.onStart(); // 应用所有需要的UI变化,现在Fragment是可见的 Log.v("frament生命周期", "fragment可见周期开始"); } //在活动生命周期开始时被调用 @Override public void onResume(){ super.onResume(); //恢复所有暂停的Fragment需要的UI更新,线程或进程,但在非活动状态它是暂停的 Log.v("frament生命周期", "fragment活动周期恢复"); } // 在活动生命周期结束时被调用 @Override public void onPause(){ // 当activity不是活动的前台activity时,需要暂停UI的更新、挂起线程或者暂停那些不需要更新的CPU的集中处理。由于调用这个方法后,进程可能被终止,所以要保存所有的编辑和状态改变信息 super.onPause(); Log.v("frament生命周期", "fragment活动周期暂停"); } //在活动生命周期结束时,调用该方法保存UI的状态变化 @Override public void onSaveInstanceState(Bundle savedInstanceState) { // 将UI的状态改变信息保存在savedInstanceState中 //这个Bundle会被传递到oncreate、oncreateview和onactivitycreate(如果它的父activity被终止并且重新启动)方法中 super.onSaveInstanceState(savedInstanceState); Log.v("frament生命周期", "fragment保存ui"); } //在可见生命周期结束时调用该方法 @Override public void onStop(){ // 当fragment不可见时,暂停其余的UI更新、挂起线程或暂停不再需要的处理 super.onStop(); Log.v("frament生命周期", "fragment可见周期结束"); } // 当fragment的view被分离时,调用该方法 @Override public void onDestroyView() { //清除资源相关view super.onDestroyView(); Log.v("frament生命周期", "fragment中view分离"); } //在整个生命周期结束时调用该方法 @Override public void onDestroy(){ // 清除所有的资源,包括结束线程和关闭数据库连接等 super.onDestroy(); Log.v("frament生命周期", "fragment结束"); } // 当fragment从它的父activity上分离时,调用该方法 @Override public void onDetach() { super.onDetach(); Log.v("frament生命周期", "fragment脱离activity"); }}
自定义fragment的布局文件使用一个简单的ViewGroup文件mylinearlayout.xml来实现。
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <TextView android:id="@+id/mylinearlayout_text1" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="一个linearlayout中的textview" /></LinearLayout>
ListFragment的生命周期
在自定义的ListFragment中,我们主要需要注意的是onCreate启动函数、onCreateView布局UI函数、onListItemClick选项点击函数。
使用自定义ListFragment文件Fragment_list.java实现基本的函数
import com.lp.app.R; import android.app.ListFragment;import android.content.Context;import android.os.Bundle;import android.util.Log;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.ArrayAdapter;import android.widget.ListView;public class Fragment_list extends ListFragment{ Context context; //指向父activity Interface1 interface1; //使用接口实现fragment和activity之间共享事件 private ArrayAdapter<String> adapter; //可以在ListFragment内绑定数据源(也可以在activity中为ListFragment绑定数据源) @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); context = getActivity(); //获得对父activity的引用 //获取对父Activity的引用,进而获取父activity中的函数(接口)和变量, interface1 = (Interface1)context; //定义一个数组 List<String> data = new ArrayList<String>(); for (int i = 0; i < 30; i++) { data.add("listfragment选项" + i); } //将数组加到ArrayAdapter当中 adapter = new ArrayAdapter<String>(context,R.layout.mytextview, data); //使用一个系统布局,当做list每个项的布局 //绑定适配器时,必须通过ListFragment.setListAdapter()接口,而不是ListView.setAdapter()或其它方法 setListAdapter(adapter); Log.v("ListFragment", "listfragment启动绑定数据源"); } //创建或者填充Fragment的UI,并返回它,如果这个Fragment没有UI,那么返回null @Override public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_list, container, false); Log.v("ListFragment", "listfragment布局整体UI"); return view; } //列表每一项的点击事件 @Override public void onListItemClick(ListView listview, View v, int position, long id) { super.onListItemClick(listview, v, position, id); interface1.callback("点击了选项"+String.valueOf(position)); //通过接口调用activity中函数 Log.v("ListFragment", "点击了选项"+String.valueOf(position)); }}
自定义ListFragment的布局文件要使用一个包含listview的ViewGroup来实现。
这里使用fragment_list.xml来实现
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <ListView android:id="@+id/android:list" android:layout_width="fill_parent" android:layout_height="wrap_content" /> </LinearLayout>
自定义ListFragment文件中的listview的每一项的布局文件,可以选用自定义的view或ViewGroup或系统自带的布局文件(android.R.layout.simple_list_item_1)。
这里使用仅有一个textview的布局文件mytextview.xml来实现
<?xml version="1.0" encoding="utf-8"?> <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="一个textview" android:id="@+id/mytext1"/>
构建fragment时传递参数。
一般在创建对象时,赋予参数,使用构造函数,但是在fragment创建时,我们一般使用Bundle存储数据。是因为activity重新创建,下属fragment的字段会丢失,但是bundle数据会保留。
所以在自定义fragment中使用以下代码创建构造fragment,并读取fragment绑定的参数
private static final String ARG = "arg"; public static Fragment1 newInstance(String arg) { Fragment1 fragment = new Fragment1(); Bundle bundle = new Bundle(); bundle.putString(ARG, arg); fragment.setArguments(bundle); //在fragment内通过getArguments读取参数 return fragment; } //获取fragment绑定的参数 public String getArg() { String arg = "这是一个fragment"; //默认参数值 if(getArguments()!=null) arg = getArguments().getString(ARG); return arg; }
在activity中可以使用下面两种方式构建自定义的fragment
Fragment1 fragmenttemp1 =Fragment1.newInstance("这是第1个fragment"); //构建一个绑定了参数的fragmentFragment1 fragmenttemp2 =new Fragment1(); //构建一个没有绑定参数的fragment
activity与fragment的相互引用
在activity中可以使用findFragmentById、findFragmentByTag获取对子fragment的引用
Fragment fragment1=getFragmentManager().findFragmentById(R.id.activity_fragment_item); //只能查找布局文件中的fragmentFragment fragment2=getFragmentManager().findFragmentByTag("tag2"); //通过tag查找java文件中添加的fragment,没保存前无法找到
在fragment中可以通过getActivity获得对父activity的引用。
Context context; //指向父activity//调用该方法时Fragment会被连接到它的父activity上 @Override public void onAttach(Activity activity) { super.onAttach(activity); context = getActivity(); //获得对父activity的引用 Log.v("frament生命周期", "fragment连接到activity"); }
fragment向activity传递数据
一个activity下往往包含多个fragment,多个fragment以及activity之间需要相互共享数据,一个有效的实现方法,是在fragment定义声明接口,并调用这个接口函数,而在activity中实现这个接口函数。
1、首先你要自定义一个接口文件。这里设置一个简单的接口Interface1.java
//在fragment中声明接口,调用接口函数,在activity中定义接口函数public interface Interface1{ public void callback(Object object); //声明接口函数}
2、在自定义fragment中定义一个接口变量
Interface1 interface1; //使用接口实现fragment和activity之间共享事件@Overridepublic void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); context = getActivity(); //获得对父activity的引用 //获取对父Activity的引用,进而获取父activity中的函数(接口)和变量, interface1 = (Interface1)context;}
3、在这个fragment中边可以调用接口函数。也就是向activity传递数据
public void returndata(Object object) { interface1.callback(object); //通过接口 }
4、在activity中实现这个接口,并接受fragment传递的数据
public class Activity_fragment extends Activity implements Interface1{ //activity和fragment之间的事件共享,通过接口,activity接收fragment传来的数据,以便在自身或其他fragment中应用 @Override public void callback(Object object) { Log.v("fragment的主窗口", object.toString()); //控制UI或调用其他fragment中的函数 }}
- 安卓中fragment的使用全解
- fragment的全讲解
- fragment的全讲解
- Fragment全解
- Fragment全解析系列(二):正确的使用姿势
- Fragment全解析系列(二):正确的使用姿势
- Fragment全解析系列(二):正确的使用姿势
- Fragment全解析系列(二):正确的使用姿势
- Fragment 全解析(2):正确的使用姿势
- Fragment全解析系列(二):正确的使用姿势
- Fragment全解析系列(二):正确的使用姿势
- Fragment全解析系列(二):正确的使用姿势
- Fragment全解析系列(二):正确的使用姿势
- Fragment全解析系列(二):正确的使用姿势
- Fragment全解析系列(二):正确的使用姿势
- Fragment常用的方法介绍,非常全。
- yum的使用全解
- ViewPage+Fragment的使用
- 图片轮播不带圆点
- Hibernate之HQL查询小Demo
- 10的阶乘
- Base64Utils
- 【转】DEM DTM DLG DRG DOM DSM
- 安卓中fragment的使用全解
- 两数之和(LintCode)
- c3po类/DateBaseUtils
- 惊现神作!!!
- Fiter 笔记
- 猜数字游戏
- 详解聚簇索引
- mesh三维画图[matlab]
- 记一次Deepin15.4.1下Android开发环境搭建