前段时间打算写个锁屏的程序,想做个滑动图标来解锁的效果,想到了使用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>
由于水平有限,设计上还不够完美,希望和大家交流学习!