Android四大控件之Fragment的使用

10 篇文章 0 订阅
1 篇文章 0 订阅

Hi,众猿们,今天和大家讲讲Fragment(碎片)的使用。
先看碎片的定义,碎片是一种可以嵌入到活动中的UI片段,它可以让程序更合理和充分的利用大屏的空间,也就是说,碎片是一种可以兼顾手机和平板设备的技术,碎片的生命周期和活动非常相似,但碎片是要依赖于活动的,因此它又比活动多出了如下几个生命周期的方法(这些方法名什么时候被调用,一看方法名就应该知道了):

  1. onAttach():当碎片与活动关联的时候被调用
  2. onCreateView():
  3. onActivityCreated():
  4. onDestoryView():
  5. onDetach():

    碎片的生命周期图为(官方文档上貌似没有这张图,本猿猿就在其它书上盗了一张了):

碎片的生命周期

通常在创建自定义碎片时,我们需要重写onCreateView方法以返回碎片的界面,重写onCreated方法以保存上下文对象,重写onActivityCreated方法以初始化界面数据,因此我们可以对碎片进行包装,定义一个基类的碎片(推荐使用android.support.v4.app包下的碎片对象):

public abstract class BaseFragment  extends Fragment {
    protected Activity mActivity;
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mActivity = getActivity();
    }
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        return initView(inflater, container);
    }
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        initData();
    }

    protected void initData() {
    }
    protected abstract View initView(LayoutInflater inflater, ViewGroup container);
}

现在碎片已不仅仅是兼顾平板设备了,随着APP的界面越来越复杂,现在活动基本已经把管理界面的工作交给了碎片, 下面本猿猿就写一个基本的UI框架吧(老猿们勿笑呀):
其运行效果截图如下:
这里写图片描述
这里写图片描述

其项目包结构如下:

要理解这个项目,众猿猿们要对ViewPager控件和SlidingMenu开源项目有所了解,下面贴出几个主要类的源码吧:
MainActivity类的源码:

/**
 * 
 * 注意:该类需要继承自SlidingFragmentActivity,这样以便于用Fragment来管理其侧边栏
 */
public class MainActivity extends SlidingFragmentActivity {

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        //其布局会交由一个Fragment来管理
        setContentView(R.layout.fgm_main);
        //设置侧边栏的布局,会交由一个Fragment管理
        setBehindContentView(R.layout.fgm_left);

        //设置
        SlidingMenu slidingMenu = getSlidingMenu();
        slidingMenu = super.getSlidingMenu();
        slidingMenu.setMode(SlidingMenu.LEFT);
        slidingMenu.setTouchModeAbove(SlidingMenu.TOUCHMODE_FULLSCREEN);
        slidingMenu.setBehindOffset(160);
        slidingMenu.setFadeEnabled(true);
        slidingMenu.setFadeDegree(1);


        initFragment();
    }

    private void initFragment() {
        //获取Fragment对象的管理器并启动Fragment事务,学过数据库的猿猿对事务应该很清楚
        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction transaction = fragmentManager.beginTransaction();
        transaction.replace(R.id.fgm_left, new LeftFragment());
        transaction.replace(R.id.fgm_content, new ContentFragment());
        transaction.commit();
    }
}

BasePager的源码为:

public abstract class BasePager {
    protected Activity mActivity;
    //保存该页面的根布局,ViewPager对象会用到它
    public View mRootView;
    public BasePager(Activity activity){
        mActivity = activity;
        mRootView = initView();
    }
    protected abstract View initView();
}

NewsPager的源码为:

public class NewsPager extends BasePager{

    public NewsPager(Activity activity) {
        super(activity);
    }
    /**
     * 返回其布局文件,其布局中只有一个文本框
     */
    @Override
    protected View initView() {
        return View.inflate(mActivity, R.layout.pager_news, null);
    }
}

ContactsPager和DynamicsPager的源码就不贴出来了,其布局文件和源码与NewsPager相似,都很简单。

ContentFragment的源码为:

public class ContentFragment extends BaseFragment{
    NoScrollViewPager viewPager;
    List<BasePager> pagers = new ArrayList<BasePager>();
    RadioGroup mRadioGroup;

    @Override
    protected View initView(LayoutInflater inflater, ViewGroup container) {
        View view = inflater.inflate(R.layout.content, container, false);
        viewPager = (NoScrollViewPager) view.findViewById(R.id.viewPager);
        mRadioGroup = (RadioGroup) view.findViewById(R.id.bottom_tabs);
        mRadioGroup.setOnCheckedChangeListener(new OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(RadioGroup group, int checkedId) {
                switch(checkedId){
                case R.id.rb_news:
                    //设置viewpager切换时无动画
                    viewPager.setCurrentItem(0, false);
                    break;
                case R.id.rb_contacts:
                    viewPager.setCurrentItem(1, false);
                    break;
                case R.id.rb_dynamics:
                    viewPager.setCurrentItem(2, false);
                    break;
                }
            }
        });
        pagers.add(new NewsPager(mActivity));
        pagers.add(new ContactsPager(mActivity));
        pagers.add(new DynamicsPager(mActivity));

        viewPager.setAdapter(new PagerAdapter() {
            @Override
            public int getCount() {
                return pagers.size();
            }
            @Override
            public boolean isViewFromObject(View arg0, Object arg1) {
                return arg0 == arg1;
            }
            @Override
            public Object instantiateItem(ViewGroup container, int position) {
                BasePager pager = pagers.get(position);
                View view = pager.mRootView;
                container.addView(view);
                return view;
            }
            @Override
            public void destroyItem(ViewGroup container, int position,
                    Object object) {
                container.removeView((View)object);
            }
        });
        return view;
    }
}

其布局文件的源码为:

<?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" >
    <lmz.fragmentexample.view.NoScrollViewPager
        android:id="@+id/viewPager"
        android:layout_width="fill_parent"
        android:layout_height="0dp"
        android:layout_weight="1">
    </lmz.fragmentexample.view.NoScrollViewPager>
    <RadioGroup 
        android:id="@+id/bottom_tabs"
        android:layout_width="fill_parent"
        android:layout_height="45dp"
        android:orientation="horizontal"
        android:background="#000">
        <RadioButton 
            android:id="@+id/rb_news"
            android:layout_width="0dp"
            style="@style/bottom_tab_style"
            android:layout_height="fill_parent"
            android:text="消息"
            android:layout_weight="1"/>
        <RadioButton 
            android:id="@+id/rb_contacts"
            android:layout_width="0dp"
            style="@style/bottom_tab_style"
            android:layout_height="fill_parent"
            android:text="联系人"
            android:layout_weight="1"/>
        <RadioButton 
            android:id="@+id/rb_dynamics"
            android:layout_width="0dp"
            style="@style/bottom_tab_style"
            android:layout_height="fill_parent"
            android:layout_weight="1"
            android:text="动态"/>
    </RadioGroup>
</LinearLayout>

其它的代码和布局文件就不贴了,都挺简单的。在这个框架的基础上大家去修改和继承Pager的布局和源码,就可以搭建出界面丰富、功能复杂的App了。
关注微信公众号:猿聚于此,可获取更多文章。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值