您的位置:首页 > 移动开发 > Android开发

Android使用Fragment实现标签页

2015-09-22 22:44 471 查看
介绍
       Fragment的概念是从Android3.0开始引入的,直译为碎片、片段,目的是为不同屏幕大小的设备(手机、平板等)创建灵活动态的UI。诚如其名,你可以把Fragment当作是Activity的模块化组件,它拥有自己的生命周期和UI,接受自身的处理事件,可以在Activity运行中被动态的添加、移除、替换。

       Fragment必须被写成可重用的模块,你可以将多个Fragment组合到一个Activity中创建一个多模块界面,也可以在多个Activity中包含同一个Fragment的不同实例,这对于你的界面在不同屏幕尺寸下都能给用户完美的体验至关重要。

       Fragment不能独立存在,它必须嵌入到Activity中,因此 Fragment的生命周期也依赖于Activity的生命周期,当其依赖的Activity的某个生命周期方法被调用时,该Activity下包含的所有Fragment的相应生命周期方法也将被调用,如onPause(),onStop(),onDestroy()等。官网示图很好地解释了两者的关系:

 


        由上图可看到Fragment 比Activity多出了几个额外的生命周期。

               onAttach():当Fragment对象与Activity关联时调用

               onCreateView():用于创建和返回跟Fragment相关联的View对象

               onActivityCreate():当Fragment所依附的Activity对象已经完成了onCreate()方法的执行

               onDestoryView():清除跟Fragment的View对象相关联的资源

               onDetach():当Fragment对象不再与其依附的Activity关联的时候调用

        Fragment可以解决Activity间切换不流畅的问题,属于轻量切换。

        Fragment替代TabHost做导航,性能更好。

        Fragment做局部更新更方便,原先到达到这一点需要将多个布局放到一个Activity里,现在可以用多Fragment代替,只在需要的时候才加载Fragment,提高性能。

        Fragment可以从startActivityForResult接收返回结果,但是View不能。

实现

、使用Support Library

       Support Library是一个提供了API函数的Jar文件,这样就可以在旧版本的Android上使用一些新的APIs;

       这里我们要使用的是android-support-v4.jar文件,可以在Android SDK目录/extras/android/support/v4/路径下找到该文件,拷贝到项目的libs文件夹下即可。

二、创建几个继承Fragment的类,分别覆写onCreatView方法返回Fragment的布局。

public class DealFragment extends Fragment{

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState){
return inflater.inflate(R.layout.fragment_deal, container, false);
}

}
public class PoiFragment extends Fragment{

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState){
return inflater.inflate(R.layout.fragment_poi, container, false);
}

}
public class UserFragment extends Fragment{

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState){
return inflater.inflate(R.layout.fragment_user, container, false);
}

}
public class MoreFragment extends Fragment{

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState){
return inflater.inflate(R.layout.fragment_more, container, false);
}

}

inflate方法里三个参数的含义:

第一个参数是resource Id,指明了当前Fragment对应的布局文件;

第二个参数是父容器;

第三个布尔值参数是否连接该布局与其父容器,一般设为false,因为系统已经将该布局插入到了父控件,设为true会产生一个多余的ViewGroup。

布局文件如下,都只是简单包含一个TextView,不再重复写出:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
>

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="团购"
android:textColor="#20B2AA"
android:textSize="26sp" />

</RelativeLayout>

三、创建MainAcitvity类,添加4个用于切换标签的按钮
public class MainActivity extends FragmentActivity implements OnClickListener,
        FragmentConstants {

    private Button btnDeal;
    private Button btnPoi;
    private Button btnUser;
    private Button btnMore;

    private FragmentTransaction fragmentTransaction;

    private DealFragment dealFragments;
    private PoiFragment poiFragments;
    private UserFragment userFragments;
    private MoreFragment moreFragments;

    private int currentTabIndex = 0;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initViews();
    }

    private void initViews() {
        // TODO 自动生成的方法存根
        btnDeal = (Button) findViewById(R.id.btn_deal);
        btnPoi = (Button) findViewById(R.id.btn_poi);
        btnUser = (Button) findViewById(R.id.btn_user);
        btnMore = (Button) findViewById(R.id.btn_more);

        btnDeal.setOnClickListener(this);
        btnPoi.setOnClickListener(this);
        btnUser.setOnClickListener(this);
        btnMore.setOnClickListener(this);

        setTabSelected(TAB_DEAL_INDEX); // 默认选中【团购】标签
    }

    @Override
    public void onClick(View v) {
        // TODO 自动生成的方法存根
        switch (v.getId()) {
        case R.id.btn_deal:
            setTabSelected(TAB_DEAL_INDEX);
            break;
        case R.id.btn_poi:
            setTabSelected(TAB_POI_INDEX);
            break;
        case R.id.btn_user:
            setTabSelected(TAB_USER_INDEX);
            break;
        case R.id.btn_more:
            setTabSelected(TAB_MORE_INDEX);
            break;
        }
    }

    private void setSelectedState(int i) {
        // TODO 自动生成的方法存根
        switch (i) {
        case TAB_DEAL_INDEX:
            btnDeal.setSelected(true);
            break;
        case TAB_POI_INDEX:
            btnPoi.setSelected(true);
            break;
        case TAB_USER_INDEX:
            btnUser.setSelected(true);
            break;
        case TAB_MORE_INDEX:
            btnMore.setSelected(true);
            break;
        }
    }
    
    private void clearSelectedState() {
        // TODO 自动生成的方法存根
        btnDeal.setSelected(false);
        btnPoi.setSelected(false);
        btnUser.setSelected(false);
        btnMore.setSelected(false);
    }

布局文件如下,其中FrameLayout即为4个Fragment的父容器:
<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" >

<FrameLayout
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" >
</FrameLayout>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#F5F5F5"
android:orientation="horizontal" >

<Button
android:id="@+id/btn_deal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.25"
android:background="@null"
android:drawableTop="@drawable/tab_deal_img_selector"
android:padding="5dp"
android:text="团购"
android:textColor="@drawable/tab_txt_selector"
android:textSize="12sp" />

<Button
android:id="@+id/btn_poi"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.25"
android:background="@null"
android:drawableTop="@drawable/tab_poi_img_selector"
android:padding="5dp"
android:text="商家"
android:textColor="@drawable/tab_txt_selector"
android:textSize="12sp" />

<Button
android:id="@+id/btn_user"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.25"
android:background="@null"
android:drawableTop="@drawable/tab_user_img_selector"
android:padding="5dp"
android:text="我的"
android:textColor="@drawable/tab_txt_selector"
android:textSize="12sp" />

<Button
android:id="@+id/btn_more"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.25"
android:background="@null"
android:drawableTop="@drawable/tab_more_img_selector"
android:padding="5dp"
android:text="更多"
android:textColor="@drawable/tab_txt_selector"
android:textSize="12sp" />
</LinearLayout>

</LinearLayout>

四、动态地添加、隐藏、显示Fragment
首先,需要获得一个FragmentTransaction(Fragment事务类)实例,可以在一个给定的事务中设置你想执行的所有变化,使用诸如 add(), remove(), 和 replace()等方法;然后, 要给Activity应用事务, 必须调用 commit()方法.

fragmentTransaction = getSupportFragmentManager().beginTransaction();

当选中某个按钮时,先隐藏所有不为空的Fragment标签页(仅仅是设为不见,并不会销毁)

hideFragment(fragmentTransaction);
private void hideFragment(FragmentTransaction fragmentTransaction) {
// TODO 自动生成的方法存根
if (dealFragments != null)
fragmentTransaction.hide(dealFragments);
if (poiFragments != null)
fragmentTransaction.hide(poiFragments);
if (userFragments != null)
fragmentTransaction.hide(userFragments);
if (moreFragments != null)
fragmentTransaction.hide(moreFragments);
}

再判断被选中的按钮对应的Fragment是否为空,如果为空则实例化该Fragment标签页并添加到Activity中;如果不为空,则直接显示之前被隐藏的该标签页。

switch (tabIndex) {
case TAB_DEAL_INDEX:
setSelectedState(TAB_DEAL_INDEX);
if (dealFragments == null) {
dealFragments = new DealFragment();
fragmentTransaction.add(R.id.content, dealFragments);
} else {
fragmentTransaction.show(dealFragments);
}
break;
case TAB_POI_INDEX:
setSelectedState(TAB_POI_INDEX);
if (poiFragments == null) {
poiFragments = new PoiFragment();
fragmentTransaction.add(R.id.content, poiFragments);
} else {
fragmentTransaction.show(poiFragments);
}
break;
case TAB_USER_INDEX:
setSelectedState(TAB_USER_INDEX);
if (userFragments == null) {
userFragments = new UserFragment();
fragmentTransaction.add(R.id.content, userFragments);
} else {
fragmentTransaction.show(userFragments);
}
break;
case TAB_MORE_INDEX:
setSelectedState(TAB_MORE_INDEX);
if (moreFragments == null) {
moreFragments = new MoreFragment();
fragmentTransaction.add(R.id.content, moreFragments);
} else {
fragmentTransaction.show(moreFragments);
}
break;

}
fragmentTransaction.commit(); // 该fragmentTransaction是全局变量,只能被commit一次


效果


 
     


源码
http://download.csdn.net/detail/alfred_c/9131593
参考
http://www.cnblogs.com/mengdd/archive/2013/01/08/2851368.html http://zhidao.baidu.com/link?url=_7VMlAKu4cHz6PcfTMNrGJkM6ZUlK3_Hil2wre1WzcqFTe1neBXRq4gmRJOdVr3Iv_nWgCq4kyp61GIyv-exKLJuPQsGhuZIIaRnw62fF93
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Android开发