android 左右滑动菜单

Posted

技术标签:

【中文标题】android 左右滑动菜单【英文标题】:android slide menu right left 【发布时间】:2016-02-28 09:58:26 【问题描述】:

我尝试创建从右到左的幻灯片菜单。我搜索了自定义幻灯片菜单并找到了来源,但这个来源是从左到右的幻灯片菜单 这是一个来源

public class MainLayout extends LinearLayout 

    private static final int SLIDING_DURATION = 500;
    private static final int QUERY_INTERVAL = 16;
    int mainLayoutWidth;
    private View menu;
    private View content;
    private static int menuRightMargin = 5;

    private enum MenuState 
        HIDING, HIDDEN, SHOWING, SHOWN,
    ;

    private int contentXOffset;
    private MenuState currentMenuState = MenuState.HIDDEN;
    private Scroller menuScroller = new Scroller(this.getContext(),
            new EaseInInterpolator());
    private Runnable menuRunnable = new MenuRunnable();
    private Handler menuHandler = new Handler();
    int prevX = 0;
    boolean isDragging = false;
    int lastDiffX = 0;

    public MainLayout(Context context, AttributeSet attrs) 
        super(context, attrs);
    

    public MainLayout(Context context) 
        super(context);
    

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) 
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        mainLayoutWidth = MeasureSpec.getSize(widthMeasureSpec);
        menuRightMargin = mainLayoutWidth * 60 / 100;
    

    @Override
    protected void onAttachedToWindow() 
        super.onAttachedToWindow();

        menu = this.getChildAt(0);
        content = this.getChildAt(1);
        content.setOnTouchListener(new OnTouchListener() 
            @Override
            public boolean onTouch(View v, MotionEvent event) 
                return MainLayout.this.onContentTouch(v, event);
            
        );
        menu.setVisibility(View.GONE);
    

    @Override
    protected void onLayout(boolean changed, int left, int top, int right,
            int bottom) 
        if (changed) 
            LayoutParams contentLayoutParams = (LayoutParams) content
                    .getLayoutParams();
            contentLayoutParams.height = this.getHeight();
            contentLayoutParams.width = this.getWidth();
            LayoutParams menuLayoutParams = (LayoutParams) menu
                    .getLayoutParams();
            menuLayoutParams.height = this.getHeight();
            menuLayoutParams.width = this.getWidth() - menuRightMargin;
        
        menu.layout(left, top, right - menuRightMargin, bottom);
        content.layout(left + contentXOffset, top, right + contentXOffset,
                bottom);

    

    public void toggleMenu() 

        if (currentMenuState == MenuState.HIDING
                || currentMenuState == MenuState.SHOWING)
            return;

        switch (currentMenuState) 
        case HIDDEN:
            currentMenuState = MenuState.SHOWING;
            menu.setVisibility(View.VISIBLE);
            menuScroller.startScroll(0, 0, menu.getLayoutParams().width, 0,
                    SLIDING_DURATION);
            break;
        case SHOWN:
            currentMenuState = MenuState.HIDING;
            menuScroller.startScroll(contentXOffset, 0, -contentXOffset, 0,
                    SLIDING_DURATION);
            break;
        default:
            break;
        
        menuHandler.postDelayed(menuRunnable, QUERY_INTERVAL);
        this.invalidate();
    

    protected class MenuRunnable implements Runnable 
        @Override
        public void run() 
            boolean isScrolling = menuScroller.computeScrollOffset();
            adjustContentPosition(isScrolling);
        
    

    private void adjustContentPosition(boolean isScrolling) 
        int scrollerXOffset = menuScroller.getCurrX();

        content.offsetLeftAndRight(scrollerXOffset - contentXOffset);

        contentXOffset = scrollerXOffset;
        this.invalidate();
        if (isScrolling)
            menuHandler.postDelayed(menuRunnable, QUERY_INTERVAL);
        else
            this.onMenuSlidingComplete();
    

    private void onMenuSlidingComplete() 
        switch (currentMenuState) 
        case SHOWING:
            currentMenuState = MenuState.SHOWN;
            break;
        case HIDING:
            currentMenuState = MenuState.HIDDEN;
            menu.setVisibility(View.GONE);
            break;
        default:
            return;
        
    

    protected class EaseInInterpolator implements Interpolator 
        @Override
        public float getInterpolation(float t) 
            return (float) Math.pow(t - 1, 5) + 1;
        

    

    public boolean isMenuShown() 
        return currentMenuState == MenuState.SHOWN;
    

    public boolean onContentTouch(View v, MotionEvent event) 
        if (currentMenuState == MenuState.HIDING
                || currentMenuState == MenuState.SHOWING)
            return false;
        int curX = (int) event.getRawX();
        int diffX = 0;

        switch (event.getAction()) 
        case MotionEvent.ACTION_DOWN:

            prevX = curX;
            return true;

        case MotionEvent.ACTION_MOVE:
            if (!isDragging) 
                isDragging = true;
                menu.setVisibility(View.VISIBLE);
            
            diffX = curX - prevX;
            if (contentXOffset + diffX <= 0) 
                diffX = -contentXOffset;
             else if (contentXOffset + diffX > mainLayoutWidth
                    - menuRightMargin) 
                diffX = mainLayoutWidth + menuRightMargin + contentXOffset;
            
            content.offsetLeftAndRight(diffX);
            contentXOffset += diffX;
            this.invalidate();

            prevX = curX;
            lastDiffX = diffX;
            return true;

        case MotionEvent.ACTION_UP:
            Log.d("MainLayout.java onContentTouch()", "Up lastDiffX "
                    + lastDiffX);

            if (lastDiffX > 0) 
                currentMenuState = MenuState.SHOWING;
                menuScroller.startScroll(contentXOffset, 0,
                        menu.getLayoutParams().width - contentXOffset, 0,
                        SLIDING_DURATION);
             else if (lastDiffX < 0) 
                currentMenuState = MenuState.HIDING;
                menuScroller.startScroll(contentXOffset, 0, -contentXOffset, 0,
                        SLIDING_DURATION);
            
            menuHandler.postDelayed(menuRunnable, QUERY_INTERVAL);
            this.invalidate();
            isDragging = false;
            prevX = 0;
            lastDiffX = 0;
            return true;

        default:
            break;
        

        return false;
    

此代码运行完美。我可以创建幻灯片菜单,但现在我想重写此代码。我想从右到左接收幻灯片菜单。我想交换这个例子。 p.s 我知道关于幻灯片菜单的同样好的例子,但我想重写这个源。 我怎样才能解决我的问题?如果有人知道解决方案,请帮助我。谢谢大家

【问题讨论】:

您只是想创建一个导航抽屉吗?您只需使用DrawerLayout,只需几行代码即可获得完整的菜单幻灯片。 @drschultz 谢谢我知道 DrawerLayout 但我不需要它因为我想像这样从右到左移动框架布局alexanderblom.se/images/facebook-ios.jpeg 啊!好的,所以你想让你的内容滑动,显示下面的菜单?看看这个答案:http://***.com/questions/33587371/android-move-main-content-to-reveal-drawer 哇,这太完美了,但我的抽屉布局是正确的,我该如何重写这段代码? drawerContent.setX(drawerView.getWidth() * (1 - slideOffset)); mainContent.setX(drawerView.getWidth() * slideOffset); @drschultz @drschultz 检查我的评论 【参考方案1】:

要让你的主要内容幻灯片,在下面显示一个菜单,这里有一个很好的例子来说明如何做到这一点:https://***.com/questions/33587371/android-move-main-content-to-reveal‌​-drawer

由于您希望菜单显示在右侧,您只需从父视图的宽度中减去 X 计算,在示例中为 DrawerLayout,称为 drawerLayout。因此,您将对这些行进行以下调整:

这是设置抽屉X位置和内容的原始代码:

drawerContent.setX(drawerView.getWidth() * (1 - slideOffset));
mainContent.setX(drawerView.getWidth() * slideOffset);

这些计算从位置 0 开始滑动,并将内容滑动到抽屉的宽度。相反,我们想要父布局宽度的起始位置(我们的drawerLayout 视图),然后滑回零(直到抽屉的宽度)。所以我们将这些行改为:

drawerContent.setX(drawerLayout.getWidth() - (drawerView.getWidth() * (1 - slideOffset)));
mainContent.setX(drawerLayout.getWidth() - (drawerView.getWidth() * slideOffset));

【讨论】:

感谢您的回答,但是当我右侧有抽屉布局时,您的第二个代码无法正常工作

以上是关于android 左右滑动菜单的主要内容,如果未能解决你的问题,请参考以下文章

【求助】SlidingMenu 左右滑动菜单与viewpage冲突问题

Android QQ 左右滑动菜单弹出效果怎么实现

ViewPager--左右可滑动的

Android 实现仿美团首页左右滑动GridView+ViewPager菜单栏的功能

Android自定义LinearLayout实现左右侧滑菜单,完美兼容ListViewScrollViewViewPager等滑动控件

Android导航菜单横向左右滑动并和下方的控件实现联动