开源侧滑菜单控件SlidingMenu浅析

引子

   最近一直在思考Acitity、Fragment、layouts在开发时到底如何抉择?
自然,Activity+layouts对于一个andorid App是不可缺少的,然而为何google又要提出碎片呢?
貌似用Activity+layouts已然能开发所有的应用了吧,API指出Fragment可以将多个Activity合并,然而我们用layouts难道不能做到吗?
将多个Activity视为多个layouts不也可实现吗?然而,我现在的所理解的Fragment更像一个Activity与Layouts的中间层、一个框架,它有自己的生命周期,可能使用起来比自己写的layouts要更完善,但是本人依旧无法体会到引入Fragment带来哪些实际的好处,所以开发中并未太多的使用他,最直接的理解是Fragment是因Pad而引入的可能是为Pad更易开发UI而新增的框架或组件吧。

正文

   貌似引子和正文没多大的联系,但由于看SlidingMenu的同时一直在思考这个问题,姑且记在这里吧。
放个某个example的效果图:

下载地址:https://github.com/jfeinstein10/SlidingMenu

写到此处其实我的博客已经写完了99%了,下面就是本人的赘述了:

   1、我理解的SlidingMenu:它是一个包含CustomViewAbove和CustomViewBehind的一个layouts,最突出的特点是,它是通过scrollTo来定位
这两个子布局的。当然这样的描述有些片面,其里面的逻辑真心看起来挺死脑细胞的~~。

   2、浅析运用SlidingMenu:

   主要指com.slidingmenu.lib.app.SlidingFragmentActivity:

   此类中主要是使用com.slidingmenu.lib.app.SlidingActivityHelper来实现对SlidingMenu的呈现。

   依次在onCreate()中实例化SlidingMenu、setBehindContentView()、setContentView(),貌似这一句挺废话的,但是我也没法描述了

   主要实现逻辑是SlidingFragmentActivity类中的onPostCreate()的此段代码:

/**
 * Further SlidingMenu initialization. Should be called within the activitiy's onPostCreate()
 *
 * @param savedInstanceState the saved instance state (unused)
 */
public void onPostCreate(Bundle savedInstanceState) {
    if (mViewBehind == null || mViewAbove == null) {
        throw new IllegalStateException("Both setBehindContentView must be called " +
                "in onCreate in addition to setContentView.");
    }
    mOnPostCreateCalled = true;
    // get the window background
    TypedArray a = mActivity.getTheme().obtainStyledAttributes(new int\[\] {android.R.attr.windowBackground});
    int background = a.getResourceId(0, 0);
    a.recycle();
    if (mEnableSlide) {
        // move everything into the SlidingMenu
        ViewGroup decor = (ViewGroup) mActivity.getWindow().getDecorView();
        ViewGroup decorChild = (ViewGroup) decor.getChildAt(0);
        // save ActionBar themes that have transparent assets
        decorChild.setBackgroundResource(background);
        decor.removeView(decorChild);
        mSlidingMenu.setContent(decorChild);
        decor.addView(mSlidingMenu);
    } else {
        // take the above view out of
        ViewGroup parent = (ViewGroup) mViewAbove.getParent();
        if (parent != null) {
            parent.removeView(mViewAbove);
        }
        // save people from having transparent backgrounds
        if (mViewAbove.getBackground() == null) {
            mViewAbove.setBackgroundResource(background);
        }
        mSlidingMenu.setContent(mViewAbove);
        parent.addView(mSlidingMenu, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
    }
    this.showContent();
}

   明显看出不论mEnableSlide是false,还是true,最终都将SlidingMenu的实例充当为了仅此于DecorView的存在,属于最大的外层View了,这中布局的思路和上面提到的scrollTo来定位布局真心膜拜了。

   将SlidingMenu视为最外层View后,就不难理解CustomViewAbove和CustomViewBehind的onInterceptTouchEvent和onTouchEvent的一些逻辑了