前段时间打算写个锁屏的程序,想做个滑动图标来解锁的效果,想到了使用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>
由于水平有限,设计上还不够完美,希望和大家交流学习!
分享到:
相关推荐
可实现scroller的滑动效果。上推头部可根据上滑位置变化
android Scroller使用小例子
通过scroller学习,仿QQ ListView侧滑删除效果
webwidget_scroller_tab,tab选项卡代码
vue-scroller移动端下拉加载组件 vue-scroller移动端下拉加载组件 vue-scroller移动端下拉加载组件
Scroller简单例子,简单的使用下Scroller的API
详见http://blog.csdn.net/huaxun66/article/details/52884998
scroller类用法解析和scroller类实战案例类似ViewPager滑动功能
这个是Scroller应用上的demo 而且结合了自定义ViewGroup 很高的学习价值以及收藏价值
自定义ViewPager和Scroller,详细分析ViewPager的实现原理,有详细的注释,帮助你理解ViewPager和Scroller的运行原理
Android Scroller使用,利用Scroller实现平滑滑动,真实可用
Android 使用Scroller实现绚丽的ListView左右滑动删除Item效果,项目详情http://blog.csdn.net/xiaanming/article/details/17539199
可垂直滚动的viewpager,scroller的运用
jQuery插件——jquery.imageScroller.js 支持在正方形区域内查看比较长的图片效果 左下角有一个缩略图效果,拖拽缩略图的同时,大图对应比例的部分也会展示出来 效果相当不错 使用方法: ...
jquery 特效:imageScroller滚动图片效果 用于创建滚动图片效果的jquery案例指导!
自定义view教程之手势处理,玩转onTouchEvent()和Scroller,详解文章请移步博客:http://blog.csdn.net/yanzhenjie1003/article/details/53046027
我写的scroller相关博客里面的Demo,本来不想要分的但是为毛非得选择资源分,我也不知道为什么好久没有用CSDN这个玩意 了额,抱歉了
相应文章地址 Android 使用Scroller自动滚动第二种实现 http://blog.csdn.net/love_world_/article/details/8689077
一个通过继承ViewGroup,应用Scroller实现的手动拖拽滚屏及自动滚屏的自定义UI控件
NULL 博文链接:https://ice-cream.iteye.com/blog/337519