Android中动画实现单击按钮控制开屏关屏效果(系统animation实现、scrollTo实现、自定义scrollTo实现)

一、不多说,老惯例先上图



二、说明

优点:使用系统的动画,简单方便

缺点:也许大家发现了,按钮只是在效果显示上移动了,但是点击事件并没有跟随着移动(这是个大bug)


三、附上代码BaiHeTestActivity.java

package net.dxs.baihedemo;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;

public class BaiHeTestActivity extends Activity {

	private LinearLayout layout1;
	private LinearLayout layout2;
	private Button button1;

	private TextView textView1;
	private TextView textView2;
	private TextView textView3;
	private TextView textTest;
	/**
	 * 菜单面板打开时为true,关闭时为false
	 */
	private boolean flag = false;

	private Animation animIn;
	private Animation animOut;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		layout1 = (LinearLayout) findViewById(R.id.layout1);
		layout2 = (LinearLayout) findViewById(R.id.layout2);
		button1 = (Button) findViewById(R.id.button1);
		textView1 = (TextView) findViewById(R.id.textView1);
		textView2 = (TextView) findViewById(R.id.textView2);
		textView3 = (TextView) findViewById(R.id.textView3);
		textTest = (TextView) findViewById(R.id.textTest);

		init();
	}

	private void init() {
		animOut = AnimationUtils.loadAnimation(this, R.anim.slide_right_out);
		animOut.setFillAfter(true);

		animIn = AnimationUtils.loadAnimation(this, R.anim.slide_right_in);
		animIn.setFillAfter(true);

		button1.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				if (!flag) {
					layout2.startAnimation(animOut);
				} else {
					layout2.startAnimation(animIn);
				}
				flag = !flag;
			}
		});

		textView1.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				textTest.setText(textView1.getText());
			}
		});
		textView2.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				textTest.setText(textView2.getText());
			}
		});
		textView3.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				textTest.setText(textView3.getText());
			}
		});
	}

}

四、附上代码 布局activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >


    <FrameLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" >

        <LinearLayout
            android:id="@+id/layout1"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:background="@android:color/darker_gray"
            android:orientation="vertical" >

            <TextView
                android:id="@+id/textView1"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="10dp"
                android:text="Large Text1"
                android:textAppearance="?android:attr/textAppearanceLarge"
                android:textColor="@android:color/black" />

            <TextView
                android:id="@+id/textView2"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="10dp"
                android:text="Large Text2"
                android:textAppearance="?android:attr/textAppearanceLarge"
                android:textColor="@android:color/black" />

            <TextView
                android:id="@+id/textView3"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="10dp"
                android:text="Large Text3"
                android:textAppearance="?android:attr/textAppearanceLarge"
                android:textColor="@android:color/black" />
        </LinearLayout>

        <LinearLayout
            android:id="@+id/layout2"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:orientation="vertical" >

            <LinearLayout
                android:layout_width="fill_parent"
                android:layout_height="fill_parent"
                android:background="@android:color/black"
                android:orientation="vertical" >

                <Button
                    android:id="@+id/button1"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="Button" />

                <TextView
                    android:id="@+id/textTest"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="10dp"
                    android:text="textTest"
                    android:textAppearance="?android:attr/textAppearanceLarge" />
            </LinearLayout>
        </LinearLayout>
    </FrameLayout>

</LinearLayout>

四、还有两个animation动画

slide_right_in.xml

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

    <translate
        android:fillAfter="true"
        android:duration="800"
        android:fromXDelta="80%p"
        android:toXDelta="0" />
</set>

slide_right_out.xml

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

    <translate
        android:fillAfter="true"
        android:duration="800"
        android:fromXDelta="0"
        android:toXDelta="80%p" />

</set>


五、scrollTo实现

既然animation动画实现的有bug,那么肯定得换一种方式

方式一:使用scrollTo实现

将layout2.startAnimation(animOut);改为layout2.scrollTo(-200, 0);

layout2.startAnimation(animIn);改为layout2.scrollTo(0, 0);

就可以解决这个bug了,

但是貌似问题又出来了,缓慢移动的效果没有了,

那么我们这个时候就需要引入自定义scrollTo动画了


六、自定义scrollTo实现


①MyScroller.java工具类

package net.dxs.baihedemo;

import android.content.Context;
import android.os.SystemClock;

/**
 * 位移计算工具类
 * @author lijian
 *
 */
public class MyScroller {

	private Context ctx;
	public MyScroller(Context context){
		ctx = context;
	}
	
	private int startX;
	private int startY;
	private int distanceX;
	private int distanceY;
	
	private int currentX;
	private int currentY;
	
	private long startTime;
	private long duration = 1000L;
	
	/**
	 * 
	 * @param scrollX	x坐标
	 * @param scrollY	y坐标
	 * @param distanceX	X方向移动的距离
	 * @param distanceY	y方向移动的距离
	 */
	public void startScroll(int scrollX, int scrollY, int distanceX, int distanceY) {
		startX = scrollX;
		startY = scrollY;
		this.distanceX = distanceX;
		this.distanceY = distanceY;
		isFinish = false;
		startTime = SystemClock.uptimeMillis();
	}

	private boolean isFinish ;
	
	/**
	 * 计算偏移量,
	 * @return true 还在移动  false:移动已经停止
	 */
	public boolean computeScrollOffset() {

		if (isFinish) {
			return false;
		}

		long timePassed = SystemClock.uptimeMillis()- startTime;

		if (timePassed < duration) {

			currentX = (int) (startX + distanceX  * timePassed / duration);
			currentY = (int) (startY + distanceY * timePassed/ duration );

			System.out.println("currentX:::" + currentX);
		} else if (timePassed >= duration) {
			currentX = startX + distanceX;
			currentY = startY + distanceY;
			isFinish = true;
		}
		
		return true;
	}

	public int getCurrX() {
		return currentX;
	}

	public void setCurrentX(int currentX) {
		this.currentX = currentX;
	}

	public int getCurrentY() {
		return currentY;
	}

	public void setCurrentY(int currentY) {
		this.currentY = currentY;
	}

}


②调用

定义了一个handler并且回调

package net.dxs.baihedemo;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;

public class BaiHeTestActivity extends Activity {

	private LinearLayout layout1;
	private LinearLayout layout2;
	private Button button1;

	private TextView textView1;
	private TextView textView2;
	private TextView textView3;
	private TextView textTest;
	/**
	 * 菜单面板打开时为true,关闭时为false
	 */
	private boolean flag = false;
	
	private MyScroller scroller;
	
	private final int FLUSH = 1;
	private Handler handler = new Handler(){

		@Override
		public void handleMessage(Message msg) {
			if(msg.what == FLUSH){
				if(scroller.computeScrollOffset()){
					layout2.scrollTo(scroller.getCurrX(), 0);
					handler.sendEmptyMessage(FLUSH);
				}
			}
		}
	};


	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		layout1 = (LinearLayout) findViewById(R.id.layout1);
		layout2 = (LinearLayout) findViewById(R.id.layout2);
		button1 = (Button) findViewById(R.id.button1);
		textView1 = (TextView) findViewById(R.id.textView1);
		textView2 = (TextView) findViewById(R.id.textView2);
		textView3 = (TextView) findViewById(R.id.textView3);
		textTest = (TextView) findViewById(R.id.textTest);

		init();
	}

	private void init() {
		scroller = new MyScroller(this);

		button1.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				if (!flag) {
					scroller.startScroll(layout2.getScrollX(), layout2.getScrollY(), -200, 0);
					handler.sendEmptyMessage(FLUSH);
				} else {
					scroller.startScroll(layout2.getScrollX(), layout2.getScrollY(), 200, 0);
					handler.sendEmptyMessage(FLUSH);
				}
				flag = !flag;
			}
		});

		textView1.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				textTest.setText(textView1.getText());
			}
		});
		textView2.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				textTest.setText(textView2.getText());
			}
		});
		textView3.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				textTest.setText(textView3.getText());
			}
		});
	}

}


七、使用系统的Scroller类实现

也许大家会发现我自定义的MyScroller效果不好(匀速移动过去的)

说实话我的这个MyScroller是仿照系统的Scroller写的;

但是我只实现了位移的时间变化,没有去实现速度的时间变化。


那么我们改用系统的Scroller,你会发现移动的效果迅速提升几个等级(开始快,快到的时候放慢了)因为他做了一个速度的时间变化


好了不多说了,代码不用变,只需将MyScroller改为Scroller就ok了


package net.dxs.baihedemo;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.Scroller;
import android.widget.TextView;

public class BaiHeTestActivity extends Activity {

	private LinearLayout layout1;
	private LinearLayout layout2;
	private Button button1;

	private TextView textView1;
	private TextView textView2;
	private TextView textView3;
	private TextView textTest;
	/**
	 * 菜单面板打开时为true,关闭时为false
	 */
	private boolean flag = false;
	
	/**
	 * 自定义的scroller
	 */
	//private MyScroller scroller;
	/**
	 * 系统的scroller
	 */
	private Scroller scroller;
	
	private final int FLUSH = 1;
	private Handler handler = new Handler(){

		@Override
		public void handleMessage(Message msg) {
			if(msg.what == FLUSH){
				if(scroller.computeScrollOffset()){
					layout2.scrollTo(scroller.getCurrX(), 0);
					handler.sendEmptyMessage(FLUSH);
				}
			}
		}
	};


	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		layout1 = (LinearLayout) findViewById(R.id.layout1);
		layout2 = (LinearLayout) findViewById(R.id.layout2);
		button1 = (Button) findViewById(R.id.button1);
		textView1 = (TextView) findViewById(R.id.textView1);
		textView2 = (TextView) findViewById(R.id.textView2);
		textView3 = (TextView) findViewById(R.id.textView3);
		textTest = (TextView) findViewById(R.id.textTest);

		init();
	}

	private void init() {
		//scroller = new MyScroller(this);
		scroller = new Scroller(this);

		button1.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				if (!flag) {
					scroller.startScroll(layout2.getScrollX(), layout2.getScrollY(), -200, 0);
					handler.sendEmptyMessage(FLUSH);
				} else {
					scroller.startScroll(layout2.getScrollX(), layout2.getScrollY(), 200, 0);
					handler.sendEmptyMessage(FLUSH);
				}
				flag = !flag;
			}
		});

		textView1.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				textTest.setText(textView1.getText());
			}
		});
		textView2.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				textTest.setText(textView2.getText());
			}
		});
		textView3.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				textTest.setText(textView3.getText());
			}
		});
	}

}





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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值