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

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

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


二、说明

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

缺点:也许大家发现了,按钮只是在效果显示上移动了,但是点击事件并没有跟随着移动(这是个大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





    

        

            

            

            
        

        

            

                

四、还有两个animation动画

slide_right_in.xml




    

slide_right_out.xml




    



五、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());
			}
		});
	}

}





你可能感兴趣的:(Android)