静态加载:
把fragment当成普通类来使用。
1.继承fragment类,重载fragment的onCreateView方法,此方法主要是创建fragment的布局。
2.在Activity的XMl文件中,通过fragment标签就可以使用我们自定义的fragment,这里通过指定fragment标签的name属性来确定使用哪一个Fragment。
例子:
ContentFragment的布局:
<FrameLayout 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:background="@color/sport_items_bg"
tools:context="com.example.liaoli.fragmentdemo.fragment.ContentFragment">
<TextView
android:id="@+id/content"
android:layout_width="wrap_content"
android:gravity="center"
android:layout_gravity="center"
android:layout_height="wrap_content"
android:textSize="20dp"
android:text="@string/hello_blank_fragment"/>
</FrameLayout>
ContentFragment的代码:
package com.example.liaoli.fragmentdemo.fragment; import android.os.Bundle; import android.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; import com.example.liaoli.fragmentdemo.R; public class ContentFragment extends Fragment { private TextView title; public static ContentFragment newInstance(String param1, String param2) { ContentFragment fragment = new ContentFragment(); return fragment; } public ContentFragment() { } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment View view = inflater.inflate(R.layout.fragment_content, container, false); title = (TextView) view.findViewById(R.id.content); title.setText("我是内容"); return view ; } }
TitleFragment的布局文件:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="50dp" android:background="@color/entertainment_items_bg" tools:context="com.example.liaoli.fragmentdemo.fragment.TitleFragment"> <TextView android:id="@+id/title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:text="@string/hello_blank_fragment" android:textSize="25dp" /> <Button android:id="@+id/share_bt" android:layout_width="60dp" android:layout_height="40dp" android:layout_centerVertical="true" android:layout_alignParentRight="true" android:text="分享" android:onClick="share" /> </RelativeLayout>
TitleFragment的代码:
package com.example.liaoli.fragmentdemo.fragment; import android.os.Bundle; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.Button; import android.widget.TextView; import android.widget.Toast; import com.example.liaoli.fragmentdemo.R; public class TitleFragment extends Fragment { private TextView title; public static TitleFragment newInstance(String param1, String param2) { TitleFragment fragment = new TitleFragment(); return fragment; } public TitleFragment() { // Required empty public constructor } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment View view = inflater.inflate(R.layout.fragment_title, container, false); title = (TextView) view.findViewById(R.id.title); title.setText("我是标题"); Button share = (Button) view.findViewById(R.id.share_bt); share.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(getActivity(), "分享这篇文章", Toast.LENGTH_SHORT).show(); } }); return view ; } }
StaticLoadActivity的布局文件
<RelativeLayout 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:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.example.liaoli.fragmentdemo.StaticLoadActivity"> <fragment android:id="@+id/title_fragment" android:layout_width="fill_parent" android:layout_height="wrap_content" android:name="com.example.liaoli.fragmentdemo.fragment.TitleFragment"/> <fragment android:id="@+id/content_fragment" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_below="@+id/title_fragment" android:name="com.example.liaoli.fragmentdemo.fragment.ContentFragment"/> </RelativeLayout>
StaticLoadActivity的代码:
package com.example.liaoli.fragmentdemo; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; public class StaticLoadActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_static_load); } }
效果
二,动态加载
在程序的运行过程中动态的添加,删除,替换Fragment
TopNewsFragment的布局文件
<FrameLayout 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:background="@color/top_item_bg" tools:context="com.example.liaoli.fragmentdemo.fragment.TopNewsFragment"> <TextView android:id="@+id/content" android:layout_width="wrap_content" android:gravity="center" android:layout_gravity="center" android:layout_height="wrap_content" android:textSize="20dp" android:text="头条新闻条目列表" /> </FrameLayout>
TopNewsFragment的代码:
package com.example.liaoli.fragmentdemo.fragment; import android.app.Activity; import android.net.Uri; import android.os.Bundle; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import com.example.liaoli.fragmentdemo.R; public class TopNewsFragment extends Fragment { public static TopNewsFragment newInstance(String param1, String param2) { TopNewsFragment fragment = new TopNewsFragment(); return fragment; } public TopNewsFragment() { } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment return inflater.inflate(R.layout.fragment_top_news, container, false); } }
HotNewsFragment的布局
<FrameLayout 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:background="@color/hot_items_bg" tools:context="com.example.liaoli.fragmentdemo.fragment.HotNewsFragment"> <TextView android:id="@+id/content" android:layout_width="wrap_content" android:gravity="center" android:layout_gravity="center" android:layout_height="wrap_content" android:textSize="20dp" android:text="热点新闻条目列表" /> </FrameLayout>
HotNewsFragment的代码
package com.example.liaoli.fragmentdemo.fragment; import android.os.Bundle; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import com.example.liaoli.fragmentdemo.R; public class HotNewsFragment extends Fragment { public static HotNewsFragment newInstance(String param1, String param2) { HotNewsFragment fragment = new HotNewsFragment(); return fragment; } public HotNewsFragment() { // Required empty public constructor } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment return inflater.inflate(R.layout.fragment_hot_news, container, false); } }
其他两个Fragment :EntertainmentFragment 和SportsFragment的代码和布局与上面两个几乎差不多,再次不在多说
DynamicLoadActivity的布局:
<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="vertical" tools:context="com.example.liaoli.fragmentdemo.StaticLoadActivity"> <FrameLayout android:id="@+id/news_fragment" android:layout_width="fill_parent" android:layout_height="0dp" android:layout_weight="1" /> <include layout="@layout/bottom_bar" /> </LinearLayout>
bottom_bar.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/bottom_bar_bg" android:orientation="horizontal"> <Button android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="头条" android:onClick="tops" /> <Button android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:onClick="hots" android:text="热点" /> <Button android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="娱乐" android:onClick="entertainments"/> <Button android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="体育" android:onClick="sports"/> </LinearLayout>
colors.xml
<?xml version="1.0" encoding="utf-8"?> <resources> <color name="bottom_bar_bg">#ff224e</color> <color name="top_item_bg">#5477ff</color> <color name="hot_items_bg">#dc97ff</color> <color name="entertainment_items_bg">#ffd60d</color> <color name="sport_items_bg">#21ff74</color> </resources>
DynamicLoadActivity的代码:
package com.example.liaoli.fragmentdemo; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentTransaction; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import com.example.liaoli.fragmentdemo.fragment.EntertainmentFragment; import com.example.liaoli.fragmentdemo.fragment.HotNewsFragment; import com.example.liaoli.fragmentdemo.fragment.SportsFragment; import com.example.liaoli.fragmentdemo.fragment.TopNewsFragment; public class DynamicLoadActivity extends AppCompatActivity { private TopNewsFragment topNewsFragment; private HotNewsFragment hotNewsFragment; private EntertainmentFragmententertainmentFragment; private SportsFragment sportsFragment; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_dynamic_load); initdata(); } private void initdata() { FragmentManager fragmentManager = getSupportFragmentManager(); FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); if (topNewsFragment == null) { topNewsFragment = new TopNewsFragment(); } fragmentTransaction.add (R.id.news_fragment, topNewsFragment); fragmentTransaction.commit(); } public void tops(View view) { FragmentManager fragmentManager = getSupportFragmentManager(); FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); if (topNewsFragment == null) { topNewsFragment = new TopNewsFragment(); } fragmentTransaction.replace(R.id.news_fragment, topNewsFragment); fragmentTransaction.commit(); } public void hots(View view) { FragmentManager fragmentManager = getSupportFragmentManager(); FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); if (hotNewsFragment == null) { hotNewsFragment = new HotNewsFragment(); } fragmentTransaction.replace(R.id.news_fragment, hotNewsFragment); fragmentTransaction.commit(); } public void entertainments(View view) { FragmentManager fragmentManager = getSupportFragmentManager(); FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); if (entertainmentFragment == null) { entertainmentFragment = new EntertainmentFragment(); } fragmentTransaction.replace(R.id.news_fragment, entertainmentFragment); fragmentTransaction.commit(); } public void sports(View view) { FragmentManager fragmentManager = getSupportFragmentManager(); FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); if (sportsFragment == null) { sportsFragment = new SportsFragment(); } fragmentTransaction.replace(R.id.news_fragment, sportsFragment); fragmentTransaction.commit(); } }
效果:
点击头条按钮
点击热点按钮:
点击娱乐按钮:
点击体育按钮
fragment常用的三个类,
Fragment 封装了Fragment
FragmentManager 封装了Activity对Fragment的管理
FragmentTransaction 封装了对Fragment的事务处理流程
FragmentManager的获取方式
3.0以上getFragmentManager()
v4中getSupportFragmentManager
FragmentTransaction 处理操作Fragment事物的方法如下
1.开启一个事务:
FragmentManager fragmentManager = getSupportFragmentManager(); FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();//开启一个事务
2.向Activity中添加fragment
abstract FragmentTransaction | add(int containerViewId, Fragment fragment) Calls add(int, Fragment, String) with a null tag. |
abstract FragmentTransaction | add(Fragment fragment, String tag) Calls add(int, Fragment, String) with a 0 containerViewId. |
fragmentTransaction.add (R.id.news_fragment, topNewsFragment);
3.删除一个fragment,如果被移除的Fragment没有添加到回退栈中,这个Fragment实例将被销毁。
abstract FragmentTransaction | Remove an existing fragment. |
4.隐藏一个Fragment
此时仅仅是不可见,而并没有被销毁
abstract FragmentTransaction | Hides an existing fragment. |
5.显示之前隐藏的Fragment
abstract FragmentTransaction | Shows a previously hidden fragment. |
6.将view从UI中移除
此方法跟Remove不一样,此时Fragment还是有FragmentManager维护管理
abstract FragmentTransaction | Detach the given fragment from the UI. |
7.重建Fragment的View布局,并附添加到UI并显示出来
abstract FragmentTransaction | Re-attach a fragment after it had previously been detached from the UI with detach(Fragment). |
8.替换Fragment,通过源码我们会知道,其实就是先删除,在添加
abstract FragmentTransaction | replace(int containerViewId, Fragment fragment, String tag) Replace an existing fragment that was added to a container. |
abstract FragmentTransaction | replace(int containerViewId, Fragment fragment) Calls replace(int, Fragment, String) with a null tag. |
在一个事务的开启到提交的过程中可以多次添加、移除、替换等相关操作。
在我们使用Fragment的过程中一定要弄清楚事务处理的各个方法那些会销毁视图,那些会销毁Fragment实例。
常见错误:State loss这样的错误。主要是因为:commit方法一定要在Activity.onSaveInstance()之前调用。