我们平常显示界面的话都是使用的Activity,Fragment作为一个"小Activity"在有些情况下作为嵌入Activity的一部分,能够在很大程度上提升用户的体验度,更方便的在屏幕横竖切换的时候动态的更新Activity用户界面;
比如:
我们知道平板的显示屏幕不同于手机,某种程度上我们可以将它理解为是横屏版的手机,那么这时候如果我们还是照样按照竖屏的界面显示的话,界面效果不是很好,同时也没充分利用起横屏状态下宽度大于高度这个特点,此时Fragment的作用就显现出来了,如下图:
左边是横屏状态,其界面的左边作为选项列表是一个Fragment,在点击不同选项的时候会在右边显示各自对应的Fragment,但他们是处于同一Activity中的;
右边是竖屏状态,由于Fragment是可以复用的,ActivityA可以是左边横屏状态的选项列表Fragment,ActivityB可以是点击完某个选项之后显示的Fragment,很明显,他们两个属于不同的Activity;
Fragment概述:
(1) Fragment总是Activity的一部分,因此当Activity暂停的时候,Fragment也会暂停,只有当Activity处于活动状态我们才可以操作Fragment;
(2) Activity可以通过FragmentManager的findFragmentById()或者findFragmentByTag()来获得Fragment,Fragment可以通过getActivity()方法来获得他所在的Activity;
(3) 一个Activity可以有多个Fragment,一个Fragment可以被多个Activity共享;
(4) Fragment可以响应自己的输入事件,拥有自己的生命周期,但他的生命周期直接被其所属的Activity的生命周期所控制;
下面我们实现一个在横竖屏不同状态下采用Fragment来实现屏幕适配的例子:
首先需要知道为了使用Fragment通常我们都是定义自己的Fragment直接继承自Fragment或者间接继承自Fragment的子类,然后重写onCreateView方法,这个方法有一个View返回值,这个返回值将作为当前Fragment的显示组件,当Fragment绘制界面组件的时候将会回调这个方法;
首先先来看看静态使用Fragment的实例:
定义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"
android:background="#ffff00">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/Koala"/>
</LinearLayout>
定义Fragment1.java
public class Fragment1 extends Fragment{
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment1, container, false);
}
}
很简单,就是通过onCreateView调用inflater.inflate方法来返回指定.xml的View,至于LayoutInflater的inflater方法参数,下一篇我们从源码角度查看他到底做了些什么;
定义fragment2.xml,类似于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"
android:background="#00ff00">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/Tulips"/>
</LinearLayout>
定义Fragment2.java,也类似于Fragment1.java
public class Fragment2 extends Fragment{
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment2,container,false);
}
}
定义activity_fragment.xml用来显示上面两个Fragment
<?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:baselineAligned="false">
<fragment
android:id="@+id/activity_frament1"
android:name="com.hzw.programmingtest.Fragment1"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
/>
<fragment
android:id="@+id/activity_frament2"
android:name="com.hzw.programmingtest.Fragment2"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
/>
</LinearLayout>
定义MyFragmentActivity.java来加载带有Fragment的Activity
public class MyFragmentActivity extends FragmentActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fragment);
}
}
注意这里继承的是FragmentActivity而不是Activity,如果继承Activity的话,会出现下面错误:
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.hzw.programmingtest/com.hzw.programmingtest.MyFragmentActivity}: android.view.InflateException: Binary XML file line #6: Error inflating class fragment
程序的运行界面:
上面我们通过静态<fragment>标签的形式让Fragment在Activity上面显示出来,接下来我们可以通过动态代码的方式来加载不同的Fragment,这样在能够在屏幕发生横竖变化的时候进行动态适应呈现不同的界面;
首先同样的步骤,新建fragment1.xml,Fragment1.java,fragment2.xml,Fragment2.java,这四个代码和上面的一样,我们直接复用;
新建fragment_list.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" >
<Button
android:id="@+id/btFragment1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="显示Fragment1"/>
<Button
android:id="@+id/btFragment2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="显示Fragment2"/>
</LinearLayout>
新建FragmentList.java,作为左边选项列表的Fragment
public class FragmentList extends Fragment implements OnClickListener{
public Button mBtFragment1;
public Button mBtFragment2;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_list, container, false);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mBtFragment1 = (Button) getActivity().findViewById(R.id.btFragment1);
mBtFragment2 = (Button) getActivity().findViewById(R.id.btFragment2);
mBtFragment1.setOnClickListener(this);
mBtFragment2.setOnClickListener(this);
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.btFragment1:
Fragment1 fragment1 = new Fragment1();
getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.activity_fragmentLayout, fragment1).commit();
break;
case R.id.btFragment2:
Fragment2 fragment2 = new Fragment2();
getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.activity_fragmentLayout, fragment2).commit();
break;
default:
break;
}
}
}
新建activity_landscape.xml,作为横向屏幕的Activity布局文件:
<?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:baselineAligned="false">
<fragment
android:id="@+id/activity_framentlist"
android:name="com.hzw.programmingtest.FragmentList"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
/>
<FrameLayout
android:id="@+id/activity_fragmentLayout"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="3"/>
</LinearLayout>
这个文件将屏幕划分成四份,最左边的一份通过<fragment>标签静态加入了选项列表的Fragment,右边四分之三的空间定义了一个FragmentLayout容器,该容器根据左边选项的选中状况动态更新其显示的Fragment
新建MyLandscapeFragmentActivity.java
public class MyLandscapeFragmentActivity extends FragmentActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_landscape);
}
}
很简单,只是显示出对应的布局文件即可;
新建activity_protrait.xml,作为纵向屏幕的Activity布局文件
<?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" >
<Button
android:id="@+id/bt1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="显示Fragment1"/>
<Button
android:id="@+id/bt2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="显示Fragment2"/>
</LinearLayout>
新建用于显示纵向屏幕布局文件的MyProtraitFragmentActivity
public class MyProtraitFragmentActivity extends FragmentActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_protrait);
}
}
新建选中纵向屏幕中“显示Fragment1”的显示界面Activity,叫Fragment1Activity.java
public class Fragment1Activity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment1);
}
}
新建选中纵向屏幕中“显示Fragment2”的显示界面Activity,叫Fragment2Activity.java
public class Fragment2Activity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment2);
}
}
接下来我们对MyProtraitFragmentActivity进行修改,使得他可以根据屏幕的横竖状态来动态的切换不同的显示界面
public class MyProtraitFragmentActivity extends FragmentActivity implements OnClickListener {
public Button bt1 = null;
public Button bt2 = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Display display = getWindowManager().getDefaultDisplay();
if(display.getWidth() < display.getHeight())
{
//表示是竖屏
setContentView(R.layout.activity_protrait);
bt1 = (Button) findViewById(R.id.bt1);
bt2 = (Button) findViewById(R.id.bt2);
bt1.setOnClickListener(this);
bt2.setOnClickListener(this);
}else
{
//表示是横屏
setContentView(R.layout.activity_landscape);
}
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.bt1:
Intent intent1 = new Intent(MyProtraitFragmentActivity.this, Fragment1Activity.class);
startActivity(intent1);
break;
case R.id.bt2:
Intent intent2 = new Intent(MyProtraitFragmentActivity.this, Fragment2Activity.class);
startActivity(intent2);
break;
default:
break;
}
}
}
当我们首次运行的时候,如果是横屏的话,界面显示为:
点击"显示Fragment1"出现的界面为:
点击"显示Fragment2"出现的界面是:
按住Ctrl+F12,由横屏切换到竖屏状态,显示为:
随后点击"显示Fragment1"和显示"显示Fragment2"的时候弹出的都是新的Activity,而不是在原先的Activity里面弹出来的;
至此,介绍了Fragment的简单应用,以及通过Fragment简单实现了横竖屏切换不同状态下显示不同类型页面的实例,这样我们在以后开发过程中如果遇到屏幕太大的情况,可以通过Fragment来填充那些多余的地方;
下一篇我们介绍下Fragment的生命周期!!!!!