[仿南航app开发日记3]侧滑菜单实现

前言

这个是接着上面两篇开发的日记,上面两篇的日记:

[仿南航app开发日记1]开篇-总体布局分析
[仿南航app开发日记2]主界面完成

纠正

因为我看到南航app侧滑的时候是内容菜单整个滑动,如果使用ActionBar的话。那么ActionBar是不会移动的,所以要达到这种效果就只有取消ActionBar,因为我的开发环境是android 5.0,所以取消ActionBar依然是在AndroidMenifest.xml文件里面修改主题:

android:theme="@style/Theme.AppCompat.DayNight.NoActionBar"

完整的AndroidMenifest.xml文件如下:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="cn.karent.nanhang">

    <application
        android:allowBackup="true"
        android:name=".util.MyApplication"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/Theme.AppCompat.DayNight.NoActionBar">

        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

分析

既然要加入侧滑,那么首先先编写侧滑菜单的布局:

<?xml version="1.0" encoding="utf-8"?>
<!--侧滑菜单的布局-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="300dp"
    android:layout_marginRight="-150dp"
    android:layout_alignParentRight="true"
    android:layout_height="match_parent">
    <!--显示头像和一个背景-->
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:clipChildren="false"
        android:background="@drawable/me_bg">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="80dp"
            android:gravity="left"
            android:orientation="vertical"
            android:layout_alignParentBottom="true">
            <ImageView
                android:layout_width="60dp"
                android:layout_height="60dp"
                android:layout_marginTop="-20dp"
                android:layout_marginLeft="30dp"
                android:src="@drawable/userhead_dealfut"/>
            <ImageView
                android:layout_width="60dp"
                android:layout_height="40dp"
                android:layout_marginTop="5dp"
                android:layout_marginLeft="30dp"
                android:src="@drawable/wujiaoxing"/>
        </LinearLayout>

    </RelativeLayout>
    <!--我的资料-->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="62dp"
        android:gravity="center"
        android:divider="@drawable/under_line"
        android:showDividers="end"
        android:background="@color/menuColor"
        android:orientation="horizontal">
        <ImageView
            android:layout_width="25dp"
            android:layout_height="25dp"
            android:layout_marginLeft="20dp"
            android:src="@drawable/user_icon1"/>
        <TextView
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:gravity="center"
            android:textSize="20sp"
            android:textColor="@android:color/black"
            android:text="@string/menu_home"/>
        <ImageView
            android:layout_width="25dp"
            android:layout_marginLeft="10dp"
            android:layout_height="wrap_content"
            android:layout_marginRight="20dp"
            android:src="@drawable/btn_icon_arrow"/>
    </LinearLayout>
    <!--修改密码-->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="62dp"
        android:gravity="center"
        android:divider="@drawable/under_line"
        android:background="@color/menuColor"
        android:showDividers="end"
        android:orientation="horizontal">
        <ImageView
            android:layout_width="25dp"
            android:layout_height="25dp"
            android:layout_marginLeft="20dp"
            android:src="@drawable/pwd_icon1"/>
        <TextView
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:gravity="center"
            android:textSize="20sp"
            android:textColor="@android:color/black"
            android:text="@string/menu_modify_pwd"/>
        <ImageView
            android:layout_width="25dp"
            android:layout_marginLeft="10dp"
            android:layout_marginRight="20dp"
            android:layout_height="wrap_content"
            android:src="@drawable/btn_icon_arrow"/>
    </LinearLayout>
    <!--关于-->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="62dp"
        android:gravity="center"
        android:divider="@drawable/under_line"
        android:background="@color/menuColor"
        android:showDividers="end"
        android:orientation="horizontal">
        <ImageView
            android:layout_width="25dp"
            android:layout_height="25dp"
            android:layout_marginLeft="20dp"
            android:src="@drawable/question"/>
        <TextView
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:textSize="20sp"
            android:gravity="center"
            android:textColor="@android:color/black"
            android:layout_marginLeft="20dp"
            android:text="@string/menu_abount"/>
        <ImageView
            android:layout_width="25dp"
            android:layout_marginLeft="10dp"
            android:layout_height="wrap_content"
            android:layout_marginRight="20dp"
            android:src="@drawable/btn_icon_arrow"/>
    </LinearLayout>
    <!--我的二维码-->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="62dp"
        android:gravity="center"
        android:divider="@drawable/under_line"
        android:background="@color/menuColor"
        android:showDividers="end"
        android:orientation="horizontal">
        <ImageView
            android:layout_width="25dp"
            android:layout_height="25dp"
            android:layout_marginLeft="20dp"
            android:src="@drawable/qcode"/>
        <TextView
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:layout_marginLeft="20dp"
            android:gravity="center"
            android:textSize="20sp"
            android:textColor="@android:color/black"
            android:text="@string/menu_qcode"/>
        <ImageView
            android:layout_width="25dp"
            android:layout_marginLeft="10dp"
            android:layout_height="wrap_content"
            android:layout_marginRight="20dp"
            android:src="@drawable/btn_icon_arrow"/>
    </LinearLayout>

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:background="@color/menuColor"
        android:layout_weight="1">
        <Button
            android:layout_width="230dp"
            android:layout_height="wrap_content"
            android:text="登录"
            android:background="@drawable/login_btn_shape"
            android:textColor="@android:color/white"
            android:layout_centerInParent="true"/>
    </RelativeLayout>

</LinearLayout>

上面也没什么好说的,也是堆出来的布局,然后自定义一个侧滑菜单Layout,具体可以参考我的博客:

http://blog.csdn.net/supervictim/article/details/53821577

我上面写的不完全,感兴趣的可以自己修改下,增加Touch事件监听,如果用我上面的代码会屏蔽掉Banner的滚动,而且原南航app好像也没有滑动侧滑,而是点击右上角的头像侧滑,所以我直接取消了滑动侧滑,修改后的源码如下:

package cn.karent.nanhang.UI;

import android.content.Context;
import android.os.AsyncTask;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
import android.view.View;
import android.widget.RelativeLayout;

import cn.karent.nanhang.R;
import cn.karent.nanhang.util.ScreenUtil;

/**
 * Created by wan on 2016/12/6.
 * 侧滑菜单,内容会偏移
 */
public class SlideLayout extends RelativeLayout {

    private Context mContext;

    private static final int MOTION_VELOCITY = 300;

    /*
        是否是第一次调用onLayout方法
     */
    private boolean mLoadOnece = false;

    /*
        左边侧滑菜单的布局参数
     */
    private MarginLayoutParams mLeftParams;

    /*
        右边内容的布局参数
     */
    private MarginLayoutParams mMenuParams;

    /*
        左边的侧滑View
     */
    private View mLeftView;

    /*
        中间的内容View
     */
    private View mMenuView;

    private float mOldX;

    private float mOldY;

    /*
     * 屏幕的宽度
     */
    private int mScreenWidth;

    /**
     * 控件能够移动到的左边界
     */
    private int mLeftEdge = 300;

    public SlideLayout(Context context) {
        super(context);
        mContext = context;
    }

    public SlideLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        mContext = context;
    }

    /**
     * 布局
     */
    public void onLayout(boolean change, int l, int t, int r, int b) {
        super.onLayout(change, l, t, r, b);
        if( change && !mLoadOnece) {
            mLeftEdge = ScreenUtil.dp2px(300);
            mLeftView = findViewById(R.id.slide_content);
            mMenuView = findViewById(R.id.slide_menu);
            mLeftParams =  (MarginLayoutParams) mLeftView.getLayoutParams();
            mMenuParams = (MarginLayoutParams)mMenuView.getLayoutParams();
            DisplayMetrics dm = getResources().getDisplayMetrics();
            mScreenWidth = dm.widthPixels;
            mLoadOnece = true;
        }
    }

    /**
     * 切换菜单的显示和隐藏
     */
    public void switchMenu() {
        if( mLeftParams.leftMargin == 0) {
            showMenu();
        } else {
            hideMenu();
        }
    }

    /**
     * 显示菜单
     */
    public void showMenu() {
        new SmoothScrollTack().execute(-mLeftEdge, mLeftParams.leftMargin);
    }

    /**
     * 隐藏菜单
     */
    public void hideMenu() {
        new SmoothScrollTack().execute(0, mLeftParams.leftMargin);
    }


    /**
     * 修改View的边距来达到移动的效果
     * @param leftMargin
     */
    private void modifyLeftMargin(int leftMargin) {
        //如果左边距大于0代表将要向右变压缩,应该禁止
        if( leftMargin > 0 ) {
            mLeftParams.leftMargin = 0;
            mMenuView.setTranslationX(0);
            //控制左边界滑动
        } else if( leftMargin < -mLeftEdge) {
            mLeftParams.leftMargin = -mLeftEdge;
            mMenuView.setTranslationX(-mLeftEdge / 2);
        } else {
            mLeftParams.leftMargin = leftMargin;
            mMenuView.setTranslationX(leftMargin / 2);
        }
        mLeftParams.width = mScreenWidth;
        mLeftView.setLayoutParams(mLeftParams);
    }

    /**
     * 当侧滑停止的时候来出来接下来的滑动
     */
    private class SmoothScrollTack extends AsyncTask<Integer, Integer, Integer> {

        @Override
        protected void onProgressUpdate(Integer... values) {
            int leftMargin = values[0];
            modifyLeftMargin(leftMargin);
        }

        /**
         * 计算下一个leftMargin值,第一个参数的目标值
         * 第二个参数是当前的边距
         * @param params
         * @return
         */
        @Override
        protected Integer doInBackground(Integer... params) {
            int targetLeftMargin = params[0];
            int currentLeftMargin = params[1];
            int leftMargin = currentLeftMargin;
            int step = targetLeftMargin == 0 ? 10 : -10;
            while(true) {
                leftMargin += step;
                //判断是否滑动完成
                if( leftMargin < -mLeftEdge ) {
                    leftMargin = -mLeftEdge;
                    break;
                }
                if( leftMargin > 0 ) {
                    leftMargin = 0;
                    break;
                }
                publishProgress(leftMargin);
                try {
                    Thread.sleep(5);
                } catch( InterruptedException e) {
                    e.printStackTrace();
                }
            }
            publishProgress(leftMargin);
            return leftMargin;
        }
    }

}

我在里面添加了三个函数并删除了onTouchEvent事件:

 /**
     * 切换菜单的显示和隐藏
     */
    public void switchMenu() {
        if( mLeftParams.leftMargin == 0) {
            showMenu();
        } else {
            hideMenu();
        }
    }

    /**
     * 显示菜单
     */
    public void showMenu() {
        new SmoothScrollTack().execute(-mLeftEdge, mLeftParams.leftMargin);
    }

    /**
     * 隐藏菜单
     */
    public void hideMenu() {
        new SmoothScrollTack().execute(0, mLeftParams.leftMargin);
    }

具体的代码逻辑我就不罗嗦了,我前面的博客有讲,下面就是主布局了:

<?xml version="1.0" encoding="utf-8"?>
<!--侧滑菜单-->
<cn.karent.nanhang.UI.SlideLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/slide"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <!--菜单布局-->
    <include android:id="@+id/slide_menu" layout="@layout/main_menu_layout"/>
    <!--内容布局-->
    <include android:id="@+id/slide_content" layout="@layout/content_layout"/>
</cn.karent.nanhang.UI.SlideLayout>

这里使用include标签包含了两个布局,@layout/main_menu_layout这个是前面刚讲的策划菜单布局,@layout/content_layout是上篇博客讲的主界面布局,然后修改MainActvity:

package cn.karent.nanhang;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.transition.Slide;
import android.view.View;
import android.widget.ImageView;

import cn.karent.nanhang.UI.NewsUI;
import cn.karent.nanhang.UI.SlideLayout;

public class MainActivity extends AppCompatActivity {
    /**
     * 封装跟新闻有关的UI
     */
    private NewsUI mNewsUI;

    private ImageView headUser;

    private SlideLayout slide;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
//        setContentView(R.layout.content_layout);
        setContentView(R.layout.main);
        headUser = (ImageView)findViewById(R.id.head_user);
        slide = (SlideLayout)findViewById(R.id.slide);
        //设置titile
        mNewsUI = new NewsUI(this);
        headUser.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                slide.switchMenu();
            }
        });
    }



}

这里将加载ActionBar的那一段代码删掉了,给右上角的ImageView添加点击事件,点击一下开始切换菜单

效果

这里写图片描述
再上一张原app的界面:
这里写图片描述
这就是今天的代码了!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值