Android 养成记-1 --1.4 动画系列 (菜单侧滑+图标旋转+dialog弹出+点击效果)

  • 菜单侧滑动画

思想是布局文件里,将菜单栏跟内容栏放在同一个layout中,但是菜单栏初始是隐藏状态.

总布局是线性水平布局:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="horizontal"
    tools:context=".MainActivity" >

然后分为menu跟content两个部分:

 <RelativeLayout
        android:id="@+id/menu"
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:background="@drawable/bg" >
RelativeLayout
        android:id="@+id/content"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

在mainActivity中:

重新设置menuParams的laiyout,并监听content的滑动onTouch

content = findViewById(R.id.content);
        menu = findViewById(R.id.menu);
        menuParams = (LinearLayout.LayoutParams) menu.getLayoutParams();
        // 将menu的宽度设置为屏幕宽度减去menuPadding
        menuParams.width = screenWidth - menuPadding;
        // 左边缘的值赋值为menu宽度的负数
        leftEdge = -menuParams.width;
        // menu的leftMargin设置为左边缘的值,这样初始化时menu就变为不可见
        menuParams.leftMargin = leftEdge;
        // 将content的宽度设置为屏幕宽度
        content.getLayoutParams().width = screenWidth;
        lastDistanceX=0;
        content.setOnTouchListener(this);
 @Override
    public boolean onTouch(View v, MotionEvent event) {
        createVelocityTracker(event);

        switch (event.getAction()) {

            case MotionEvent.ACTION_DOWN:
                // 手指按下时,记录按下时的横坐标
                xDown = event.getRawX();
                break;
            case MotionEvent.ACTION_MOVE:
                // 手指移动时,对比按下时的横坐标,计算出移动的距离,来调整menu的leftMargin值,从而显示和隐藏menu

                xMove = event.getRawX();
                int distanceX = (int) (xMove - xDown);
                if (isMenuVisible) {
                    menuParams.leftMargin = distanceX;
                } else {
                    menuParams.leftMargin = leftEdge + distanceX;
                }
                if (menuParams.leftMargin < leftEdge) {
                    menuParams.leftMargin = leftEdge;
                } else if (menuParams.leftMargin > rightEdge) {
                    menuParams.leftMargin = rightEdge;
 menu.setLayoutParams(menuParams);

                break;
            case MotionEvent.ACTION_UP:
                // 手指抬起时,进行判断当前手势的意图,从而决定是滚动到menu界面,还是滚动到content界面
                xUp = event.getRawX();
                if (wantToShowMenu()) {
                    if (shouldScrollToMenu()) {
                        scrollToMenu();
                    } else {
                        scrollToContent();
                    }
                } else if (wantToShowContent()) {
                    if (shouldScrollToContent()) {
                        scrollToContent();
                    } else {
                        scrollToMenu();
                    }
                }
                recycleVelocityTracker();
                break;
        }
        return true;
    }
  • 图标旋转

两种办法,一种是调用系统现有接口:

**
     * 将屏幕滚动到menu界面,滚动速度设定为30.
     */
    private void scrollToMenu() {
        final Animation rotateAnimation = new RotateAnimation(90f, 180f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
        rotateAnimation.setDuration(300);
        showmenulist.startAnimation(rotateAnimation);
        new ScrollTask().execute(30);
    }

    /**
     * 将屏幕滚动到content界面,滚动速度设定为-30.
     */
    private void scrollToContent() {
        final Animation rotateAnimation = new RotateAnimation(0f, 90f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
        rotateAnimation.setDuration(300);
        showmenulist.startAnimation(rotateAnimation);
        new ScrollTask().execute(-30);
    }

还有就是当滑动时,获取位置,并重新传参数:

 case MotionEvent.ACTION_MOVE:
                // 手指移动时,对比按下时的横坐标,计算出移动的距离,来调整menu的leftMargin值,从而显示和隐藏menu

                xMove = event.getRawX();
                int distanceX = (int) (xMove - xDown);
                if (isMenuVisible) {
                    menuParams.leftMargin = distanceX;
                } else {
                    menuParams.leftMargin = leftEdge + distanceX;
                }
                if (menuParams.leftMargin < leftEdge) {
                    menuParams.leftMargin = leftEdge;
                } else if (menuParams.leftMargin > rightEdge) {
                    menuParams.leftMargin = rightEdge;
                } else{
                    //随着手指滑动距离实时改变menu图标的旋转角度
                    distanceX = distanceX > menuParams.width ? menuParams.width : distanceX;
                    //方法3,在代码中设置参数,实现menu图标动画旋转角度的控制
                    float pivotX = showmenulist.getWidth() / 2f;
                    float pivotY = showmenulist.getHeight() / 2f;
                    float fromDegrees = ((float) lastDistanceX / menuParams.width) * 360f;

                    float toDegrees = ((float) distanceX / menuParams.width) * 360f;
                    //旋转动画效果   参数值 旋转的开始角度  旋转的结束角度  pivotX x轴伸缩值
                    RotateAnimation animation = new RotateAnimation(fromDegrees, toDegrees,
                            pivotX, pivotY);
                    //该方法用于设置动画的持续时间,以毫秒为单位
                    animation.setDuration(100);
                    //设置重复次数
                    //animation.setRepeatCount(int repeatCount);
                    //动画终止时停留在最后一帧
                    animation.setFillAfter(true);
                    //启动动画
                    showmenulist.startAnimation(animation);
                    lastDistanceX = distanceX;
                }

效果图如下:

  • dialog弹出动画

直接看code:

   //简单列表对话框,用于选择操作
    public void showExitDialog(){
            AlertDialog dialog = new AlertDialog.Builder(this)
                    .setTitle("退出").create();
        Button positiveBtn=new Button(this);

            dialog.setButton(dialog.BUTTON_POSITIVE, "确定", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    finish();
                }
            });
        dialog.setButton(dialog.BUTTON_NEGATIVE, "取消", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {

            }
        });
        TextView textView=new TextView(this);
        textView.setText("确定退出吗?\n");
        textView.setTextSize(20);
        //组合文本加图片,可以设置线性布局
        LinearLayout layout=new LinearLayout(this);
        layout.setOrientation(LinearLayout.VERTICAL);//设置LinearLayout垂直
        layout.setGravity(Gravity.CENTER);//设置LinearLayout里面内容中心分布
        //layout.addView(imageView);//先添加image
        layout.addView(textView);//再添加text
        dialog.setView(layout);//只需要把layout设置进入Toast

        Window dialogWindow = dialog.getWindow();
        dialogWindow.setGravity(Gravity.BOTTOM);  //此处可以设置dialog显示的位置,从底部弹出
        dialogWindow.setWindowAnimations(R.style.popupDialog);  //添加动画
        dialog.show();
        /* 将对话框的大小按屏幕大小的百分比设置
         */
            WindowManager m = getWindowManager();
            Display d = m.getDefaultDisplay(); // 获取屏幕宽、高用
            WindowManager.LayoutParams lp = dialogWindow.getAttributes();
            lp.height = (int) (d.getHeight() * 0.3); //设置dialog的高度
            dialogWindow.setAttributes(lp);

        }

上面还可以将layout 潜入到dialog中,layout可以添加自己想要的控件。然后通过style 设置dialog进入和退出的效果:

 <style name="popupDialog" parent="android:Animation">
        <item name="@android:windowEnterAnimation">@anim/dialog_enter</item>
        <item name="@android:windowExitAnimation">@anim/dialog_exit</item>
    </style>
  • 按钮点击效果

通过布局文件控制:

 <Button
                    android:id="@+id/txt_setting"
                    android:layout_width="wrap_content"
                    android:layout_height="match_parent"
                    android:background="@drawable/tab_menu_bg"
                    android:drawablePadding="3dp"
                    android:drawableTop="@drawable/tab_menu_setting"
                    android:gravity="center"
                    android:textColor="@drawable/tab_menu_msg_text"
                    android:text="设置"
                    android:textSize = "12dp"/>

tab_menu_setting.xml里来设置按钮图标颜色press on和off:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item 
        android:state_focused="true"
        android:drawable="@drawable/ic_setup_off"
        ></item>
	<item 
	    android:state_pressed="true"
	    android:drawable="@drawable/ic_setup_on"
	    ></item>
	<item 
	    android:drawable="@drawable/ic_setup_off"
	    ></item>
</selector>

tab_menu_msg_text里来设置按钮字体颜色press on和off 效果:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:color="@color/orange" android:state_selected="true"/>
    <item android:color="@color/gray" />

</selector>

效果图如下:

这样,就是这篇文章全部内容了。

所有实现及资源文件均在下面的demo 里,Androidstudio可以正常运行。https://download.csdn.net/download/linzihahaha/10771576

猜你喜欢

转载自blog.csdn.net/linzihahaha/article/details/83834865