Fragment从字面意思理解就是碎片的意思,当然是为了解决安卓各类设备碎片化严重的问题,比如同样一个App在手机上显示效果还不错,但是一旦上了16:9的平板立刻就变了味,使用安卓平板的同学可能体(bei)会(keng)更深,为此Google官方从android 3.0(对应API 11)引入Fragment,简单理解就是把界面分割成很多碎片,然后根据实际要求最后选择性的进行拼接,比如在手机竖屏模式下只能显示一本书的目录列表,但是如果是横屏模式(也可以立即为平板模式)下就可以在屏幕的左半边显示目录列表,然后在屏幕的右半边显示每个列表项目的简介,这样用户体验就会好很多。好了。下面开始实现一个简单的Fragment Demo
最后显示效果如下:(一个平板模式下左半边显示fragment1,右边显示fragment2)
1:分别创建fragment1和fragment2的布局
fragment1.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="match_parent" android:orientation="vertical" > <TextView android:text="这是fragment1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="20sp" android:textColor="#00CD00"/> </LinearLayout>
fragment2.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="match_parent" android:orientation="vertical" > <TextView android:text="这是fragment2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="20sp" android:textColor="#EEEE00"/> </LinearLayout>
2:这里仅仅是声明了静态界面,将来要引用的话还需要创建继承自Fragment的Activity(fragment1和fragment2都要创建)
Fragment1.class
package com.example.fragment; import android.app.Fragment; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; public class Fragment1 extends Fragment{ @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // TODO Auto-generated method stub return inflater.inflate(R.layout.fragment, container,false) ; } }
<span style="font-size:18px;"> </span>
Fragment2.class
package com.example.fragment; import android.app.Fragment; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; public class Fragment2 extends Fragment{ @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // TODO Auto-generated method stub return inflater.inflate(R.layout.fragment2, container, false) ; } }
3:到此基础的两个碎片都已经实现完毕,现在开始创建主界面局部
activity_main.xml
<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:baselineAligned="false" tools:context="com.example.fragment.MainActivity" > <fragment android:id="@+id/fragment1" android:name="com.example.fragment.Fragment1" android:layout_height="wrap_content" android:layout_width="0dp" android:layout_weight="1"/> <fragment android:id="@+id/fragment2" android:name="com.example.fragment.Fragment2" android:layout_height="wrap_content" android:layout_width="0dp" android:layout_weight="1"/> </LinearLayout>
最后简单写一下主Activity启动项目
package com.example.fragment; import android.support.v7.app.ActionBarActivity; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; public class MainActivity extends ActionBarActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } }
项目运行截图就不贴了。能正常运行。
看到这里,我们已经能够实现简单的静态界面了,但是Fragment最强大的地方却在动态加载上,我们在以上代码的基础上进行改造一下实现一个自动感应屏幕旋转,然后分别显示不同的Fragment的 Demo
同样先定义横屏竖屏的布局代码(因为在平板中调试的,为了演示效果,设置了300多的字体大小。。。。)
fragment1.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="match_parent" android:orientation="vertical" > <TextView android:text="这是竖屏" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="300sp" android:textColor="#00CD00"/> </LinearLayout>
fragment2.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="match_parent" android:orientation="vertical" > <TextView android:text="这是横屏" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="300sp" android:textColor="#EEEE00"/> </LinearLayout>
接下来当然是分别实现加载刚刚写好的fragment1和fragment2的布局
Fragment1.java
package com.example.dynamicfragment; import android.app.Fragment; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; public class Fragment1 extends Fragment{ @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // TODO Auto-generated method stub return inflater.inflate(R.layout.fragment1, container, false) ; } }
Fragment2.java
package com.example.dynamicfragment; import android.annotation.SuppressLint; import android.app.Fragment; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @SuppressLint("NewApi") public class Fragment2 extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // TODO Auto-generated method stub return inflater.inflate(R.layout.fragment2, container,false) ; } }
好了碎片准备完毕,现在开始写主界面布局,因为是需要一会动态加载,所以我们的主界面里只放一个布局,什么控件都不放
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/layout" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="com.example.dynamicfragment.MainActivity" > </LinearLayout>
最后最关键的主Activity调用.项目启动!
MainActivity.java
package com.example.dynamicfragment; import android.view.Display; import android.annotation.SuppressLint; import android.app.Activity; import android.app.Fragment; import android.support.v4.app.*; import android.os.Bundle; @SuppressLint("NewApi") public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Display display = getWindowManager().getDefaultDisplay() ; if(display.getHeight() > display.getWidth()) { Fragment1 shuping = new Fragment1(); getFragmentManager().beginTransaction().replace(R.id.layout, shuping).commit() ; } else { Fragment2 hengping = new Fragment2() ; getFragmentManager().beginTransaction().replace(R.id.layout, hengping).commit() ; } } }
运行截图当然比较霸气,要不怎么对得起300sp大小的字体加大平板。。。。
附录:安卓各个版本API level与版本的对应关系。