`
yuanlanjun
  • 浏览: 1185307 次
文章分类
社区版块
存档分类
最新评论

封装的scroller事件

 
阅读更多

前段时间打算写个锁屏的程序,想做个滑动图标来解锁的效果,想到了使用scroller,刚开始弄得时候感觉有点麻烦,所以封装了下

以后可以很方便的调用,经测试还可以正常使用 大笑,以后方便了。

设计思想:起一个子线程来更新scroller状态,然后通过handler来通知主线程更新UI。

上代码:

这个是主类

package com.popo.android.widget;


import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.view.animation.Interpolator;
import android.widget.Scroller;

/**
 * 封装的scroller滑动事件
 * 使用方法:
 * 		首先必须要实现一个ScrollerHandler用来通知线程更新Ui 
 *     
 *      MyScroller scroller = new  MyScroller(context,mainHandler);
 *      scroller.startScroll(0,0,10,10);
 *      
 *      在mainHandler handleMessage方法里面会获取到message 
 *      其中message.arg1 为scroller x位置 messag.arg2 为scroller y位置
 *      
 * @author popo
 *
 */

public class MyScroller extends Scroller {

	private MyThread myThread=null;
	private boolean isrunning =false;
	/**
	 * 
	 * @param context	运行环境
	 * @param mainHandler 用来通知scroller的状态更新
	 */
	public MyScroller(Context context,ScrollerHandler mainHandler) {
		// TODO Auto-generated constructor stub
		this(context,null,mainHandler);
		
	}
	
	/**
	 * 滑动
	 * @param context
	 * @param interpolator
	 * @param mainHandler
	 */
	public MyScroller(Context context, Interpolator interpolator,ScrollerHandler mainHandler) {
		// TODO Auto-generated constructor stub
		super(context, interpolator);
		myThread = new MyThread(mainHandler,context);
		
	}
	
	/**
	 * 取消滑动的方法
	 */
	@Override
	public void abortAnimation() {
		// TODO Auto-generated method stub
		stop();
		super.abortAnimation();
	}
	/**
	 * 开始滑动调用方法
	 * 这是公布给用户的一个方法
	 */
	
	@Override
	public void startScroll(int startX, int startY, int dx, int dy,
			int duration) {
		// TODO Auto-generated method stub
		
			super.startScroll(startX, startY, dx, dy, duration);
	
//		System.out.println("hello startScroll");
//		State state =myThread.getState();
			
		if(isrunning==false){
			myThread.start();
			isrunning=true;
		}else{
			myThread.running=true;
		}
	}
	
	/**
	 * 停止滑动
	 */
	private void stop() {
		// TODO Auto-generated method stub
		myThread.running = false;
	}
	
	/**
	 * 处理scroller的线程
	 * @author Administrator
	 *
	 */
	class MyThread extends Thread {
		boolean running = true;	//线程运行标志
		boolean newlooper = false;
		public ScrollerHandler mainHandler = null;	//主线程的处理handler
		public Handler hander = null;	//子线程处理handler 用于 mainHandler 回调
		public Context context = null;	//环境
		
		public MyThread(Context context){
			this(null,context);
		}
		
		public MyThread(final ScrollerHandler mainHandler, Context context) {
			super();
			this.mainHandler = mainHandler;
			
			//如果传给了mainHandler 就是用mainHandler的looper
			//否则创建自己的looper
			if (mainHandler == null) {
				hander = new Handler() {
					@Override
					public void handleMessage(Message msg) {
						// TODO Auto-generated method stub
						if (MyScroller.this.computeScrollOffset()) {
							sendMsg(MyScroller.this.getCurrX(),
									MyScroller.this.getCurrY());
						} else {
							running = false;
							sendMsg(MyScroller.this.getCurrX(),
									MyScroller.this.getCurrY(),mainHandler.getFinishedScrollTag());
						}
					}
				};
				//创建自己的looper
				newlooper = true;
			} else {
				
				hander = new Handler(mainHandler.getLooper()) {
					@Override
					public void handleMessage(Message msg) {
						// TODO Auto-generated method stub
						if (MyScroller.this.computeScrollOffset()) {
							sendMsg(MyScroller.this.getCurrX(),
									MyScroller.this.getCurrY());
						} else {
							running = false;
							sendMsg(MyScroller.this.getCurrX(),
									MyScroller.this.getCurrY(),mainHandler.getFinishedScrollTag());
						}
					}
				};
			}

		}

		public void run() {
			
			isrunning=true;
			//开始循环了啊
			
			sendMsg(0, 0);
			if (newlooper)
				Looper.prepare();
			while (running) {
			}

			if (newlooper)
				Looper.loop();
		}
		
		//封装的一个发送还未结束结束消息的方法
		private void sendMsg(int x, int y) {
			// TODO Auto-generated method stub
			sendMsg(x, y,mainHandler.getUnFinishedScrollTag());
		
		};
		
		private void sendMsg(int x,int y,int what){
			Message msg = new Message();
			msg.what = what;
			msg.arg1 = x;
			msg.arg2 = y;
			mainHandler.sendMessage(msg);
		}
		
	}
	
	
	/**
	 * 用来公布给ScrollerHandler 获取scroller状态的方法
	 * scroller状态会通过ScrollerHandler返回给调用线程
	 */
	public void sendgetScrollerRequest(){
//		if(computeScrollOffset())
			myThread.hander.sendEmptyMessage(0);
	}
	/**
	 * 结束时销毁线程资源
	 */
	
	@Override
	protected void finalize() {
		// TODO Auto-generated method stub
		try {
			myThread.running=false;
			myThread=null;
			super.finalize();
		} catch (Throwable e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
}


回调通知类:


package com.popo.android.widget;

import android.os.Handler;

/**
 * scroller滑动通知接口
 * scroller滑动的过程会通过这个类 的handleMessage方法来通知
 * Message 对象中 msg.arg0为滑动的x位置 msg.arg1为y位置
 *         msg.what 在滑动为结束时会是getUnFinishedScrollTag()的返回值
 *                  在滑动结束时会是getFinishedScrollTag()的返回值
 *              
 * 
 * @author popo
 *
 */
public abstract class ScrollerHandler extends Handler {

	public ScrollerHandler() {
		// TODO Auto-generated constructor stub
		super();
	}
	/**
	 * 用来填充msg.what 表明滑动未结束
	 * @return
	 */
	public abstract int getUnFinishedScrollTag();
	/**
	 * 用来填充msg.what表明滑动已结束
	 * @return
	 */
	public abstract int getFinishedScrollTag();
}


给一个Demo:

package com.popo.android;

import android.app.Activity;
import android.os.Bundle;
import android.os.Message;
import android.widget.AbsoluteLayout.LayoutParams;
import android.widget.ImageView;

import com.popo.android.widget.MyScroller;
import com.popo.android.widget.ScrollerHandler;

public class MyScrollerTest extends Activity {
	MyScroller scroller=null;
	ImageView img;
	
	// 主线程handler
	ScrollerHandler handler = new ScrollerHandler() {

		@Override
		public void handleMessage(Message msg) {
			// TODO Auto-generated method stub

			int x = msg.arg1;
			int y = msg.arg2;
			@SuppressWarnings("deprecation")
			LayoutParams layoutParams = new LayoutParams(
					LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, x, y);
			img.setLayoutParams(layoutParams);
			// 未结束
			if(msg.what==getUnFinishedScrollTag()){
				scroller.sendgetScrollerRequest();
			}
			super.handleMessage(msg);
		}

		@Override
		public int getFinishedScrollTag() {
			// TODO Auto-generated method stub
			return 3;
		}

		@Override
		public int getUnFinishedScrollTag() {
			// TODO Auto-generated method stub
			return 4;
		}
	
	};

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(R.layout.myscrollview);

		img = (ImageView) findViewById(R.id.imageView1);
		
		scroller = new MyScroller(this, handler);
		scroller.startScroll(0, 0, 200, 200, 6000);
	
	}
	
}

Demo中用到的布局:

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


        <ImageView
            android:id="@+id/imageView1"
            android:layout_width="40dp"
            android:layout_height="40dp"
            android:src="@drawable/simple_button_background_focused" />

</AbsoluteLayout>


由于水平有限,设计上还不够完美,希望和大家交流学习!

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics