【问题标题】:the Navigation that facebook app is usingfacebook 应用程序正在使用的导航
【发布时间】:2014-07-23 18:12:20
【问题描述】:

您一定使用过 facebook 安卓应用。我想实现 facebook 使用的相同导航,例如: 向左滑动菜单打开,向右滑动显示聊天列表。在中间,活动和布局不断变化。但我很困惑如何进行这样的导航。 (最值得注意的是,左右滑动时中间页面显示一半。)帮助?

【问题讨论】:

    标签: android


    【解决方案1】:

    你有两个不错的选择。

    1. 导航抽屉:http://developer.android.com/design/patterns/navigation-drawer.html
    2. 滑动抽屉:https://github.com/jfeinstein10/SlidingMenu

    您可以为您的用例制作多个导航抽屉。

    【讨论】:

    • 我也打算进行抽屉布局。但是在这个抽屉里是在当前布局上打开的,而不是把它滑到左边(无论如何)
    • 任何想法让它同上 facebook 导航。
    • 问题:在滑动抽屉中,没有后退导航,因为所有内容都只显示在一个布局上。如何解决?
    • 如果你想要它就像 facebook 一样,滑动菜单就是你的最佳选择。它还提供 api 来轻松切换菜单。如果菜单已经打开,您可以在活动中的 onBackPressed 中编写代码以首先关闭菜单。
    • 如果您的问题得到解答,您可能希望接受一个解决方案,以便其他人可以轻松找到最合适的解决方案。更多信息:meta.stackexchange.com/questions/5234/…
    【解决方案2】:

    我在一小时前安装了 FB 应用程序。当您点击主要内容右上角的图标时,主要内容会向左移动以显示右侧的内容。在移动过程中,显示​​的内容保持固定并位于主要内容之后。

    我根据上面的分析写了这个轻量级抽象:

    package org.yourdomain.app;
    
    import android.animation.Animator;
    import android.animation.ValueAnimator;
    import android.app.Activity;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.KeyEvent;
    import android.view.LayoutInflater;
    import android.view.ViewGroup;
    import android.widget.FrameLayout;
    import android.widget.RelativeLayout;
    
    abstract public class NavigatorActivity extends Activity {
        static public final String TAG = "NavigatorActivity";
        static public final Boolean DEBUG_LIFECYCLE = false;
    
        /**
         * True when menu is on and vice versa
         */
        private boolean mToggled;
        /**
         * Percentage of the main content to keep shown
         */
        private float mDistance;
        /**
         * Navigator listener
         */
        private NavigatorListener mListener;
        /**
         * Content view
         */
        private ViewGroup mContentLayout;
        /**
         * Menu frame
         */
        private FrameLayout mMenuLayout;
        /**
         * Main frame
         */
        private FrameLayout mMainLayout;
        /**
         * Speed of toggle animation
         */
        private long mSpeed;
        /**
         * Width of the content view
         */
        private int mContentWidth;
        /**
         * Height of the content view
         */
        private int mContentHeight;
        /**
         * The current distance to slide the main frame
         */
        private int mToggleDistance;
    
        /**
         *
         */
        public NavigatorActivity() {
            mToggled = false;
            mDistance = 80;
            mSpeed = 300l;
        }
    
        /**
         * Speed setter.
         *
         * Controls how fast the menu frame is revealed.
         *
         * @param speed
         */
        public void setSpeed(long speed) {
            mSpeed = speed;
        }
    
        /**
         * Distance setter.
         *
         * The distance is the % of the oriented screen to pull the main frame in order to reveal the
         * menu frame.
         *
         * @param distance
         */
        public void setDistance(float distance) {
            mDistance = distance;
        }
    
        /**
         * Navigator listener setter.
         *
         * @param listener
         */
        public void setNavigatorListener(NavigatorListener listener) {
            mListener = listener;
        }
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            if (DEBUG_LIFECYCLE) Log.v(TAG, "onCreate " + this + ": " + savedInstanceState);
            initContentLayout();
            setContentView(mContentLayout);
            initMenuLayout();
            mContentLayout.addView(mMenuLayout);
            initMainLayout();
            mContentLayout.addView(mMainLayout);
        }
    
        /**
         * Initializes the main frame.
         */
        private void initMainLayout() {
            int hw = RelativeLayout.LayoutParams.MATCH_PARENT;
            mMainLayout = new FrameLayout(this) {
                @Override
                protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
                    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
                    setMeasuredDimension(mContentWidth, mContentHeight);
                }
            };
            RelativeLayout.LayoutParams p = new RelativeLayout.LayoutParams(hw, hw);
            p.addRule(RelativeLayout.ALIGN_PARENT_TOP);
            p.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
            mMainLayout.setLayoutParams(p);
        }
    
        /**
         * Initializes the menu frame.
         */
        private void initMenuLayout() {
            int hw = RelativeLayout.LayoutParams.MATCH_PARENT;
            mMenuLayout = new FrameLayout(this);
            RelativeLayout.LayoutParams p = new RelativeLayout.LayoutParams(hw, hw);
            p.addRule(RelativeLayout.ALIGN_PARENT_TOP);
            p.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
            mMenuLayout.setLayoutParams(p);
        }
    
        /**
         * Initialize the activity's content layout.
         */
        private void initContentLayout() {
            final int hw = RelativeLayout.LayoutParams.MATCH_PARENT;
            mContentLayout = new RelativeLayout(this) {
                @Override
                protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
                    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
                    mContentWidth = MeasureSpec.getSize(widthMeasureSpec);
                    mContentHeight = MeasureSpec.getSize(heightMeasureSpec);
                    setMeasuredDimension(mContentWidth, mContentHeight);
                    mToggleDistance = Math.round((mDistance / 100f) * (float) mContentWidth);
                }
            };
            mContentLayout.setLayoutParams(new RelativeLayout.LayoutParams(hw, hw));
        }
    
        /**
         * Inflates two project XML layout and adds them to the menu and main layout frames.
         *
         * @param menuLayoutResId
         * @param mainLayoutResId
         */
        protected void setContentViews(int menuLayoutResId, int mainLayoutResId) {
            final LayoutInflater inflater = getLayoutInflater();
            inflater.inflate(menuLayoutResId, mMenuLayout);
            inflater.inflate(mainLayoutResId, mMainLayout);
        }
    
        /**
         * Toggle the menu frame.
         */
        final public void toggleNavigator() {
            final boolean isToggled = mToggled = !mToggled;
            if (DEBUG_LIFECYCLE) Log.v(TAG, "toggleNavigatorMenu " + this);
            RelativeLayout.LayoutParams menuParams = (RelativeLayout.LayoutParams) mMenuLayout.getLayoutParams();
            menuParams.setMargins(mContentWidth - mToggleDistance, 0, 0, 0);
            final RelativeLayout.LayoutParams mainParams = (RelativeLayout.LayoutParams) mMainLayout.getLayoutParams();
            ValueAnimator animator = ValueAnimator.ofInt(mainParams.leftMargin, mToggled ? -mToggleDistance : 0);
            animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator valueAnimator) {
                    mainParams.leftMargin = (Integer) valueAnimator.getAnimatedValue();
                    mMainLayout.requestLayout();
                }
            });
            animator.addListener(new Animator.AnimatorListener() {
    
                @Override
                public void onAnimationStart(Animator animation) {}
    
                @Override
                public void onAnimationEnd(Animator animation) {
                    if (mListener != null) {
                        mListener.onNavigatorToggled(isToggled);
                    }
                }
    
                @Override
                public void onAnimationCancel(Animator animation) {}
    
                @Override
                public void onAnimationRepeat(Animator animation) {}
            });
            animator.setDuration(mSpeed);
            animator.start();
        }
    
        public static interface NavigatorListener {
            public void onNavigatorToggled(boolean isToggled);
        }
    
        @Override
        public boolean onKeyUp(int keyCode, KeyEvent event) {
            if (keyCode == KeyEvent.KEYCODE_MENU) {
                toggleNavigator();
            }
            return super.onKeyUp(keyCode, event);
        }
    }
    

    使用示例:

    package org.yourdomain.project;
    
    import android.os.Bundle;
    import org.yourdomain.app.NavigatorActivity;
    
    public class YourActivity extends NavigatorActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setDistance(80); // will leave 20% of the main content in view
            setNavigatorListener(new NavigatorListener() {
                @Override
                public void onNavigatorToggled(boolean isToggled) {
                    // Load content dynamically, like FB does?
                }
            });
            setContentViews(R.layout.layout_menu, R.layout.activity_your);
        }
    }
    
    • compileSdkVersion 20
    • minSdkVersion 16
    • targetSdkVersion 20

    单击 Android 设备上的物理菜单按钮将切换导航器。

    我计划在我自己的几个启动项目中使用它。

    如果您有任何问题,请告诉我。希望对您有所帮助。

    【讨论】:

      猜你喜欢
      • 2012-01-15
      • 2012-03-31
      • 1970-01-01
      • 2013-10-03
      • 2021-10-01
      • 1970-01-01
      • 2011-11-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多