【Android笔记】Fragment用法(未完)
2015-09-29 16:45
417 查看
一、静态添加
1.写一个Fragment的布局文件fragment.xml:<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#00ff00" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="This is fragment" android:textColor="#000000" android:textSize="25sp" /> </LinearLayout>
2.继承Fragement类并载入布局:
public class MyFragment extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment, container, false); } }
3.在Activity的布局文件中引用它:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:baselineAligned="false" > <fragment android:id="@+id/fragment" android:name="com.example.fragmentdemo.MyFragment" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout>
4.在对应的Activity中获取该Fragment实例:
Fragment不是View的子类,不能使用findViewById()方法获取。
MyFragment myFragment = (MyFragment) getFragmentManager().findFragmentById(R.id.fragment);
二、动态添加
布局和继承Fragment如上。1.在Activity中指定一个放置Fragment的布局,如:
<FrameLayout android:id="@+id/fragment_layout" android:layout_width="match_parent" android:layout_height="match_parent" > </LinearLayout>
2.在Activity代码中动态添加Fragment:
MyFragment myFragment = new MyFragment(); // 获取到FragmentManager FragmentManager manager = getFragmentManager(); // 开启一个事务 FragmentTransaction transaction = manager.beginTransaction(); // 向容器内加入Fragment transaction.replace(R.id.fragment_layout, myFragment); // 提交事务 transaction.commit();
三、解耦
有时候,第二节中最后一段代码会放在某个Fragment里,以放在Button点击事件中为例。由于代码中指定了R.id.fragment_layout是某个指定Activity中的组件,此Fragment与该Activity耦合。如何解耦呢?在MyFragment中定义一个接口:
public interface MyFragmentListener { void onClick(); }
接下来在MyFragment有两种方法解耦。
方法一,仅需要Activity实现此接口:
public void onClick(View v) { if (getActivity() instanceof MyFragmentListener) { ((MyFragmentListener) getActivity()).onButtonClick(); } }
方法二,不仅需要Activity实现此接口,还要调用set方法传入接口对象:
public void setMyFragmentListener(MyFragmentListener myFragmentListener) { this.myFragmentListener = myFragmentListener; } @Override public void onClick(View v) { if (myFragmentListener != null) { myFragmentListener.onButtonClick(); } }
四、自定义控件
使用Fragment与引入自定义控件有类似之处,在这里穿插一下自定义控件的使用方法,结合Fragment体会其中的相同与相异点,可以加强记忆深化理解。以自定义顶部工具栏为例:
1.在layout文件夹下写一个工具栏的布局title.xml,此例使用LinearLayout
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" android:background="@drawable/title" > <!-- 这里添加控件 --> </LinearLayout>
如果不需要为其中的控件添加事件监听器,则直接在其他XML文件中用include语句引入此布局:
<include layout="@layout/title"/>否则继续如下步骤。
2.继承LinearLayout并在构造方法中导入布局、为相关组件添加监听器等。
public class TitleLayout extends LinearLayout { public TitleLayout(Context context, AttributeSet attrs) { super(context, attrs); LayoutInflater.from(context).inflate(R.layout.title, this); // 还可以为相关控件添加监听器等 } }
3.像添加组件一样在其他xml文件中使用它,注意须带完整的包名和类名,如:
<com.example.fragmenttest.TitleLayout android:layout_width="match_parent" android:layout_height="wrap_content" ></com.example.fragmenttest.TitleLayout>
五、生命周期
比Activity多出来几个方法:
onAttach(Activity) // Fragment与Activity建立关联时调用。 onCreateView(LayoutInflater, ViewGroup,Bundle) // 创建Fragment的视图(加载布局) onActivityCreated(Bundle) // 当Activity的onCreate方法返回时调用 onDestroyView() // Fragment的视图被移除时调用(注意,不是销毁视图) onDetach() // Fragment与Activity解除关联时调用
注意:除了onCreateView,如果重写了其他方法,必须调用父类对于该方法的实现。
OnDestroyView()不是销毁视图,而是移除视图!
六、常用类与方法
android.app.Fragment android.app.FragmentManager // 在Activity中操作Fragment,通过getFragmentManager()获取实例。 android.app.FragmentTransaction // 事务,用于保证对Fragment操作的原子性,通过fragmentManager.beginTransaction()获取实例。
1.主要操作:FragmentTransaction
主要操作都是FragmentTransaction的方法:add() 往Activity中添加一个Fragment
注:如果是新建的Fragment,则依次回调onAttach()、onCreate()、onCreateView()、onActivityCreated()、onStart()、onResume()。
remove() 从Activity中移除一个Fragment
注:如果没有调用transaction.addToBackStack(),则依次回调onPause()、onStop()、onDestroyView()、onDestroy()、onDetach()。否则只执行到onDestroyView()为止。
又注:Fragment中EditText等控件的数据会丢失
replace() 使用另一个Fragment替换当前,实际上就是remove()然后add()的合体
hide() 隐藏当前的Fragment,仅仅是设为不可见,并不会销毁
注:不会触发生命周期中的任何方法
又注:Fragment中EditText等控件的数据不会丢失
show() 显示之前隐藏的Fragment
注:同上,不会触发生命周期中的任何方法
detach() 会将view从UI中移除,和remove()不同,此时fragment的状态依然由FragmentManager维护。
注:这里没有把Fragment与Activity解除关联,不会触发onDetach()方法。仅onPause()、onStop()、onDestroyView()
attach() 重建view视图,附加到UI上并显示。
注:这里不是把Fragment与Activity建立关联,不会触发onAttach()方法。仅onCreateView()、onActivityCreated()、onStart()、onResume()
commit() 提交一个事务
注:同一个事务不能重复提交,commit()之后如需运行其他事务,需要先beginTransaction()获取一个新事务
又注:如果在Activity的onSaveInstanceState()方法之后commit()事务,则会抛出IllegalStateException,详见《Fragment提交transaction导致state loss异常》
addToBackStack() 将当前事务添加到返回栈,按下返回键时此事务从栈中弹出,会反转此事务的操作,回复之前的状态(如果用了remove()、replace()方法,则Fragment中控件的数据会丢失)
补充:按下Home键与Activity一样,只回调onPause()、onStop()。恢复亦然。
2.Fragment与Activity通信
Fragment中用getActivity()方法获取Activity对象Activity中用getFragmentManager.findFragmentById()方法获取Fragment对象
待整理:http://blog.csdn.net/lmj623565791/article/details/37992017
相关文章推荐
- 【Android笔记】Fragment用法(未完)
- Android ListView控件的学习
- Android Studio开发NDK
- Android5.X
- android MVVM DataBinding
- android:windowSoftInputMode属性详解
- Android Java混淆(ProGuard)
- Android 快速开发系列 打造万能的ListView GridView 适配器
- 小试jni
- Android基础控件02
- Android入门简介
- 使用Android Studio阅读整个Android源码
- 1.Android support design TextInputLayout
- 使用Gradle构建Android应用的渠道包
- Android StrictMode 严苛模式
- Android Universal Image Loader
- Android四大组件--Service,后台播放背景音乐
- Android fragment 使用Sharepreferences来获取值,更新界面
- Android出现“Read-only file system”解决办法
- Android MQTT协议和服务器的安装