android - 半屏滑动导航

标签 android android-layout navigation android-animation

我想在这个应用程序中为我的 android 应用程序创建一个屏幕 我想创建滑动导航功能,该功能在滑动时完全可见(从左到右),当用户再次滑动(从右到左)时,它再次滑动并关闭导航窗口一半和显示一半屏幕,我使用过抽屉导航,但我不知道这一点所以如果你有任何代码请帮助我所以请发给我这将是我的荣幸。 我正在发送一张图片以供引用。 required screen closed in red rectangle

最佳答案

找到下面的代码创建一个AnimationLayout类

    import usb.terminal.R;
    import android.content.Context;
    import android.util.AttributeSet;
    import android.view.MotionEvent;
    import android.view.View;
    import android.view.ViewGroup;
    import android.view.animation.Animation;
    import android.view.animation.TranslateAnimation;

    public class AnimationLayout extends ViewGroup {

    public final static int DURATION = 1000;

    protected boolean mPlaceLeft = true;
    public boolean mOpened;
    protected View mSidebar;
    protected View mContent;
    protected int mSidebarWidth = 100; /*
                                         * assign default value. It will be
                                         * overwrite in onMeasure by Layout xml
                                         * resource.
                                         */
    protected Animation mAnimation;
    protected OpenListener mOpenListener;
    protected CloseListener mCloseListener;
    protected Listener mListener;

    protected boolean mPressed = false;

    public AnimationLayout(Context context) {
        this(context, null);
    }

    public AnimationLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public void onFinishInflate() {
        super.onFinishInflate();
        mSidebar = findViewById(R.id.animation_layout_sidebar);
        mContent = findViewById(R.id.animation_layout_content);

        if (mSidebar == null) {
            throw new NullPointerException("no view id = animation_sidebar");
        }

        if (mContent == null) {
            throw new NullPointerException("no view id = animation_content");
        }

        mOpenListener = new OpenListener(mSidebar, mContent);
        mCloseListener = new CloseListener(mSidebar, mContent);
    }

    @Override
    public void onLayout(boolean changed, int l, int t, int r, int b) {
        /* the title bar assign top padding, drop it */
        int sidebarLeft = l;
        if (!mPlaceLeft) {
            sidebarLeft = r - mSidebarWidth;
        }
        mSidebar.layout(sidebarLeft, 0, sidebarLeft + mSidebarWidth,
                0 + mSidebar.getMeasuredHeight());

        if (mOpened) {
            if (mPlaceLeft) {
                mContent.layout(l + mSidebarWidth, 0, r + mSidebarWidth, b);
            } else {
                mContent.layout(l - mSidebarWidth, 0, r - mSidebarWidth, b);
            }
        } else {
            mContent.layout(l, 0, r, b);
        }
    }

    @Override
    public void onMeasure(int w, int h) {
        super.onMeasure(w, h);
        super.measureChildren(w, h);
        mSidebarWidth = mSidebar.getMeasuredWidth();
    }

    @Override
    protected void measureChild(View child, int parentWSpec, int parentHSpec) {
        /* the max width of Sidebar is 90% of Parent */
        if (child == mSidebar) {
            int mode = MeasureSpec.getMode(parentWSpec);
            int width = (int) (getMeasuredWidth() * 0.9);
            super.measureChild(child, MeasureSpec.makeMeasureSpec(width, mode),
                    parentHSpec);
        } else {
            super.measureChild(child, parentWSpec, parentHSpec);
        }
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        if (!isOpening()) {
            return false;
        }

        int action = ev.getAction();

        if (action != MotionEvent.ACTION_UP
                && action != MotionEvent.ACTION_DOWN) {
            return false;
        }

        /*
         * if user press and release both on Content while sidebar is opening,
         * call listener. otherwise, pass the event to child.
         */
        int x = (int) ev.getX();
        int y = (int) ev.getY();
        if (mContent.getLeft() < x && mContent.getRight() > x
                && mContent.getTop() < y && mContent.getBottom() > y) {
            if (action == MotionEvent.ACTION_DOWN) {
                mPressed = true;
            }

            if (mPressed && action == MotionEvent.ACTION_UP
                    && mListener != null) {
                mPressed = false;
                return mListener.onContentTouchedWhenOpening();
            }
        } else {
            mPressed = false;
        }

        return false;
    }

    public void setListener(Listener l) {
        mListener = l;
    }

    /* to see if the Sidebar is visible */
    public boolean isOpening() {
        return mOpened;
    }

    public void toggleSidebar() {
        if (mContent.getAnimation() != null) {
            return;
        }

        if (mOpened) {
            /* opened, make close animation */
            if (mPlaceLeft) {
                mAnimation = new TranslateAnimation(0, -mSidebarWidth, 0, 0);
            } else {
                mAnimation = new TranslateAnimation(0, mSidebarWidth, 0, 0);
            }
            mAnimation.setAnimationListener(mCloseListener);
        } else {
            /* not opened, make open animation */
            if (mPlaceLeft) {
                mAnimation = new TranslateAnimation(0, mSidebarWidth, 0, 0);
            } else {
                mAnimation = new TranslateAnimation(0, -mSidebarWidth, 0, 0);
            }
            mAnimation.setAnimationListener(mOpenListener);
        }
        mAnimation.setDuration(DURATION);
        mAnimation.setFillAfter(true);
        mAnimation.setFillEnabled(true);
        mContent.startAnimation(mAnimation);
    }

    public void openSidebar() {
        if (!mOpened) {
            toggleSidebar();
        }
    }

    public void closeSidebar() {
        if (mOpened) {
            toggleSidebar();
        }
    }

    class OpenListener implements Animation.AnimationListener {
        View iSidebar;
        View iContent;

        OpenListener(View sidebar, View content) {
            iSidebar = sidebar;
            iContent = content;
        }

        public void onAnimationRepeat(Animation animation) {
        }

        public void onAnimationStart(Animation animation) {
            iSidebar.setVisibility(View.VISIBLE);
        }

        public void onAnimationEnd(Animation animation) {
            iContent.clearAnimation();
            mOpened = !mOpened;
            requestLayout();
            if (mListener != null) {
                mListener.onSidebarOpened();
            }
        }
    }

    class CloseListener implements Animation.AnimationListener {
        View iSidebar;
        View iContent;

        CloseListener(View sidebar, View content) {
            iSidebar = sidebar;
            iContent = content;
        }

        public void onAnimationRepeat(Animation animation) {
        }

        public void onAnimationStart(Animation animation) {
        }

        public void onAnimationEnd(Animation animation) {
            iContent.clearAnimation();
            iSidebar.setVisibility(View.INVISIBLE);
            mOpened = !mOpened;
            requestLayout();
            if (mListener != null) {
                mListener.onSidebarClosed();
            }
        }
    }

    public interface Listener {
        public void onSidebarOpened();

        public void onSidebarClosed();

        public boolean onContentTouchedWhenOpening();
    }
}

创建一个mainlayout.xml

<?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"
    android:orientation="vertical" >


    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
      >

        <yourpackage..AnimationLayout
            android:id="@+id/animation_layout"
            android:layout_width="match_parent"
            android:layout_height="match_parent" >
      <!--Create you Layout which you want and just call in this include-->
            <include
                android:id="@id/animation_layout_sidebar"
                android:layout_width="470dp"
                android:layout_height="match_parent"
                layout="@layout/my_cook_menu"
                android:orientation="vertical" >
            </include>
      <!--Create you Layout which you want and just call in this include-->
            <include
                android:id="@id/animation_layout_content"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                layout="@layout/sound_my_cook"
                android:clickable="true"
                android:focusable="true"
                android:orientation="vertical" >
            </include>
        </yourpackage.AnimationLayout>
    </RelativeLayout>

</RelativeLayout>

在值文件夹中创建 id.xml

 <?xml version="1.0" encoding="utf-8"?>
 <resources>
 <item type="id" name="animation_layout_sidebar" />
 <item type="id" name="animation_layout_content" />
 </resources>

在您调用的 Activity 中编写这段代码

 public class MainActivity extends Activity implements
         AnimationLayout.Listener, OnClickListener{
    AnimationDrawable frameAnimation;
    AnimationLayout animationLayout;


    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);

        setContentView(R.layout.mainlayout);


    }

    public void onClick(View v) {
          try {
                    animationLayout = (AnimationLayout) findViewById(R.id.animation_layout);
                } catch (Exception e) {
                    // TODO: handle exception
                    e.printStackTrace();
                }
                animationLayout.toggleSidebar();
      }

       @Override
       public void onSidebarOpened() {
        // TODO Auto-generated method stub

       }

      @Override
      public void onSidebarClosed() {
        // TODO Auto-generated method stub

      }

      @Override
      public boolean onContentTouchedWhenOpening() {
        // TODO Auto-generated method stub
        return false;
        }
     }

关于android - 半屏滑动导航,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20369362/

相关文章:

html - 使导航菜单跨度浏览器的长度

swift - 使用数据在 2 个不同的 NSViewController 之间切换

android - Admob 内存泄漏 - 通过使用空 Activity 来避免

android - 没有任何代码更改的 Android Studio 的 Gradle 构建失败

android - 如何为 inflatedView (按钮)设置动态宽度和高度

android - 如何在 ViewPager 中禁用 Horizo​​ntalScrollView 的滚动

menu - 带有路线或导航的 react-native-side-menu 的完整工作示例

java - android 添加 java.lang.management API

android - 如何在 android 中仅从 lat, long 获取 City, State, Country

android - ScrollView 内的可点击 LinearLayout 不会触发 onClick