当前位置:编程学习 > wap >>

自定义了一个button,用keydown和keyup来控制图片的移动,报错了,麻烦帮看下吧,谢谢

--------------------编程问答-------------------- 自己顶上来吧 --------------------编程问答-------------------- 用handler试下 --------------------编程问答--------------------
引用 2 楼 fighter0593 的回复:
用handler试下


我刚接触android几周,还不太熟悉,能用代码给表示一下吗? 什么handler --------------------编程问答-------------------- 安卓的话要改 UI的界面的话必须通过 发送消息--->handler--->改 UI,你稍微看下handler吧. 你现在就应该 当按下setOnTouchListener发送对应的消息给handler,然后handler进行处理才行. 我理解这个和在后台更新主界面进度条是一个意思. --------------------编程问答-------------------- 这个应该不是handler的问题
界面的监听本身就是UI线程里面的。
楼主查看LogCat
看里面说报什么异常,只有有异常才好判断是什么原因
下面是我的一个解锁app的一部,里面有拖动图片以及归为的代码。楼主参考下

public class LockPart extends RelativeLayout {

private Context context;
private Activity activity;
// private TextView select = null; // 初始控件,用来判断是否为拖动?
// private ImageView imgview=null;
private TextView showpower = null;
private AnimationDrawable animationDrawable;
private Bitmap dragimg = null; // 拖拽图片
private ImageView leftimg = null;
private ImageView rightimg = null;
private Drawable leftup;
private Drawable leftdown;
private Drawable rightup;
private Drawable rightdown;
private boolean downflag=false;
private int screenWidth;
private int screenCenter;
private int lockWidth;//可拖拽的范围的宽度,为屏幕宽度-2*两边边距
private int mLastMoveX = 0;
private int startMoveX;
private int leftWidth;
private int leftHeight;
private int dragWidth;// 拖拽图片宽度
private int dragCenter;// 拖拽图片中间长度
private int dragHeight;// 拖拽图片高度
private int powerWidth;//显示电量的背景的宽度
private int powerHeight;//显示电量的背景的高度
private int heightdifferenet;//拖拽的图片和电量的图片的高度差
private int margin ;// 左右侧的外边距
private int range;//解锁范围

// 回退动画时间间隔值
private static int BACK_DURATION = 20; // 20ms
// 水平方向前进速率
private static float VE_HORIZONTAL = 0.7f; // 0.1dip/ms

private static Intent intent = new Intent();

public LockPart(Context context) {
super(context);
this.context = context;
this.activity = (Activity) context;
init();
// setBackgroundColor(Color.WHITE);
setLp();
addLockView();
addLeftAndRightView();
//设置允许重写onDraw方法
setWillNotDraw(false);
}

/**
 * 计算初始坐标
 */
private void init() {
screenWidth = PhoneUtil.getResolution()[0];
// 初始化图片拖拽时的Bitmap对象
Resources resources = context.getResources();
if (dragimg == null)
dragimg = BitmapFactory.decodeResource(resources,
R.drawable.lock);
range=PhoneUtil.getFitWidth(Constant.RANGE);
margin=PhoneUtil.getFitWidth(Constant.MARGIN);
screenCenter=screenWidth/2;
dragWidth = dragimg.getWidth();
dragHeight = dragimg.getHeight();
//-(dragWidth*2)
lockWidth=screenWidth - (margin * 2)-dragWidth;
dragCenter=dragWidth/2;
startMoveX = screenWidth / 2;
mLastMoveX = startMoveX;
powerWidth = screenWidth / 4;
powerHeight = screenWidth / 4;
leftWidth = screenWidth / 8;
leftHeight = screenWidth / 8;
heightdifferenet=(powerHeight-dragHeight)/2;

leftup=resources.getDrawable(R.drawable.zuo1);
leftdown=resources.getDrawable(R.drawable.zuo2);
rightup=resources.getDrawable(R.drawable.you1);
rightdown=resources.getDrawable(R.drawable.you2);
}

private void setLp() {

LayoutParams lockp = new LayoutParams(lockWidth+dragWidth, -2);
lockp.setMargins(margin, 0, 0, PhoneUtil.getFitHeight(100));
lockp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
this.setLayoutParams(lockp);
}

private void addLockView() {



showpower = new TextView(context);
LayoutParams selectp = new LayoutParams(powerWidth, powerHeight);
selectp.addRule(RelativeLayout.CENTER_HORIZONTAL);
selectp.addRule(RelativeLayout.CENTER_VERTICAL);
// Animation out =
// AnimationUtils.loadAnimation(context,R.anim.lockanim);
showpower.setLayoutParams(selectp);
// lockimg.setBackgroundResource(R.anim.lock_anim);

animationDrawable = (AnimationDrawable) this.getResources()
.getDrawable(R.anim.lock_anim);
showpower.setBackgroundDrawable(animationDrawable);
animationDrawable.start();
showpower.setGravity(Gravity.CENTER);
showpower.setText("21%");
showpower.setTextColor(Color.WHITE);
addView(showpower);
}

private void addLeftAndRightView() {


leftimg = new ImageView(context);
LayoutParams leftp = new LayoutParams(leftWidth, leftHeight);
leftp.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
leftp.addRule(RelativeLayout.CENTER_VERTICAL);
leftimg.setBackgroundDrawable(leftup);
// 修改外边距
leftimg.setLayoutParams(leftp);

rightimg = new ImageView(context);
LayoutParams rightp = new LayoutParams(leftWidth, leftHeight);
rightp.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
rightp.addRule(RelativeLayout.CENTER_VERTICAL);
rightimg.setBackgroundDrawable(rightup);
rightimg.setLayoutParams(rightp);

addView(leftimg);
addView(rightimg);
}

// @Override
// protected void onFinishInflate() {
// // TODO Auto-generated method stub
// super.onFinishInflate();
// // 该控件主要判断是否处于滑动点击区域。滑动时 处于INVISIBLE(不可见)状态,滑动时处于VISIBLE(可见)状态
// }

@Override
public boolean onTouchEvent(MotionEvent event) {

int x = (int) event.getX() + margin;
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
downflag=true;
mLastMoveX = x;
leftimg.setBackgroundDrawable(leftdown);
rightimg.setBackgroundDrawable(rightdown);
// 处理Action_Down事件: 判断是否点击了滑动区域
return handleActionDownEvenet(event);
case MotionEvent.ACTION_MOVE:
mLastMoveX = x; // 保存了X轴方向
invalidate(); // 重新绘制
return true;
case MotionEvent.ACTION_UP:
leftimg.setBackgroundDrawable(leftup);
rightimg.setBackgroundDrawable(rightup);
// 处理Action_Up事件: 判断是否解锁成功,成功则结束我们的Activity ;否则 ,缓慢回退该图片。
handleActionUpEvent(event);
}
return super.onTouchEvent(event);
}

// 手势落下是,是否点中了图片,即是否需要开始移动
private boolean handleActionDownEvenet(MotionEvent event) {
Rect rect = new Rect();
showpower.getHitRect(rect);
boolean isHit = rect.contains((int) event.getX(), (int) event.getY());

if (isHit) // 开始拖拽 ,隐藏该图片
showpower.setVisibility(View.INVISIBLE);
Log_I("action is down and set showpower for false");
return isHit;
}

// 图片更随手势移动
private void invalidateDragImg(Canvas canvas) {
// 以合适的坐标值绘制该图片
int drawXCor = mLastMoveX - dragCenter -margin;

int drawYCor = showpower.getTop()+heightdifferenet;
drawXCor=drawXCor < 0 ? 0 : drawXCor;
drawXCor=drawXCor > lockWidth ? lockWidth : drawXCor;
if(downflag)
canvas.drawBitmap(dragimg, drawXCor, drawYCor, null);
}

// 判断松开手指时,是否达到末尾即可以开锁了 , 是,则开锁,否则,通过一定的算法使其回退。
private void handleActionUpEvent(MotionEvent event) {
int x = (int) event.getX() + margin;
Log_I("x:" + x);
// 距离在RANGE以内代表解锁成功。
int right = getRight();
boolean isSuccessRight = (x>right-dragCenter-range) ? true
: false;
int left = getLeft();
boolean isSuccessLeft = (x<left+dragCenter+range) ? true
: false;

if (isSuccessRight) {
doActionRight();
} else if (isSuccessLeft) {
doActionLeft();
} else {// 没有成功解锁,以一定的算法使其回退
// 每隔20ms , 速率为0.6dip/ms , 使当前的图片往后回退一段距离,直到到达最左端
mLastMoveX = x; // 记录手势松开时,当前的坐标位置。
Log_I("lockimg.getRight():" + showpower.getRight());
int distanceRight = x - screenCenter;
int distanceLeft = screenCenter - x;
// 只有移动了足够距离才回退
if (distanceRight >= 0) {
mHandler.postDelayed(BackDragImgTaskRight, BACK_DURATION);
} else if (distanceLeft >= 0) {
mHandler.postDelayed(BackDragImgTaskLeft, BACK_DURATION);
} else { // 复原初始场景
resetViewState();
}
}
}

// // 重置初始的状态,显示tv_slider_icon图像,使bitmap不可见
private void resetViewState() {
mLastMoveX = startMoveX;
downflag=false;
showpower.setVisibility(View.VISIBLE);
invalidate(); // 重绘最后一次
}

// 通过延时控制当前绘制bitmap的位置坐标
private Runnable BackDragImgTaskRight = new Runnable() {

public void run() {
// 一下次Bitmap应该到达的坐标值
mLastMoveX = mLastMoveX - (int) (BACK_DURATION * VE_HORIZONTAL);

invalidate();// 重绘
// 是否需要下一次动画 ? 到达了初始位置,不在需要绘制
boolean shouldEnd = Math.abs(mLastMoveX - screenCenter) <= 18;
if (!shouldEnd)
mHandler.postDelayed(BackDragImgTaskRight, BACK_DURATION);
else { // 复原初始场景
resetViewState();
}
}
};

private Runnable BackDragImgTaskLeft = new Runnable() {

public void run() {
// 一下次Bitmap应该到达的坐标值
mLastMoveX = mLastMoveX + (int) (BACK_DURATION * VE_HORIZONTAL);

invalidate();// 重绘
// 是否需要下一次动画 ? 到达了初始位置,不在需要绘制
boolean shouldEnd = Math.abs(screenCenter - mLastMoveX) <= 18;
if (!shouldEnd)
mHandler.postDelayed(BackDragImgTaskLeft, BACK_DURATION);
else { // 复原初始场景
resetViewState();
}
}
};

private Handler mHandler = new Handler() {

public void handleMessage(Message msg) {

Log_I("handleMessage :  #### ");
}
};

//
private void doActionLeft() {
Toast.makeText(context, "左边解锁成功", Toast.LENGTH_SHORT).show();
Log_I("左边解锁");
intent.setClass(context, ShowActivity.class);
context.startActivity(intent);
activity.finish();

}

private void doActionRight() {
Toast.makeText(context, "右边解锁成功", Toast.LENGTH_SHORT).show();
virbate(); // 震动一下
// 结束我们的主Activity界面
Log_I("右边解锁");
activity.finish();
}

// 绘制拖动时的图片
@Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
// 图片更随手势移动
invalidateDragImg(canvas);
}

// 震动一下
private void virbate() {
Vibrator vibrator = (Vibrator) context
.getSystemService(Context.VIBRATOR_SERVICE);
vibrator.vibrate(300);
}

public TextView getShowpowerText() {
return this.showpower;
}

void Log_I(String log) {
// LogHelper.Log_I(this.getClass().getSimpleName(), log);
}
}
--------------------编程问答--------------------
引用 5 楼 AA5279AA 的回复:
这个应该不是handler的问题
界面的监听本身就是UI线程里面的。
楼主查看LogCat
看里面说报什么异常,只有有异常才好判断是什么原因
下面是我的一个解锁app的一部,里面有拖动图片以及归为的代码。楼主参考下

public class LockPart extends RelativeLayout {

private Context context;
private Activity activity;
// private TextView select = null; // 初始控件,用来判断是否为拖动?
// private ImageView imgview=null;
private TextView showpower = null;
private AnimationDrawable animationDrawable;
private Bitmap dragimg = null; // 拖拽图片
private ImageView leftimg = null;
private ImageView rightimg = null;
private Drawable leftup;
private Drawable leftdown;
private Drawable rightup;
private Drawable rightdown;
private boolean downflag=false;
private int screenWidth;
private int screenCenter;
private int lockWidth;//可拖拽的范围的宽度,为屏幕宽度-2*两边边距
private int mLastMoveX = 0;
private int startMoveX;
private int leftWidth;
private int leftHeight;
private int dragWidth;// 拖拽图片宽度
private int dragCenter;// 拖拽图片中间长度
private int dragHeight;// 拖拽图片高度
private int powerWidth;//显示电量的背景的宽度
private int powerHeight;//显示电量的背景的高度
private int heightdifferenet;//拖拽的图片和电量的图片的高度差
private int margin ;// 左右侧的外边距
private int range;//解锁范围

// 回退动画时间间隔值
private static int BACK_DURATION = 20; // 20ms
// 水平方向前进速率
private static float VE_HORIZONTAL = 0.7f; // 0.1dip/ms

private static Intent intent = new Intent();

public LockPart(Context context) {
super(context);
this.context = context;
this.activity = (Activity) context;
init();
// setBackgroundColor(Color.WHITE);
setLp();
addLockView();
addLeftAndRightView();
//设置允许重写onDraw方法
setWillNotDraw(false);
}

/**
 * 计算初始坐标
 */
private void init() {
screenWidth = PhoneUtil.getResolution()[0];
// 初始化图片拖拽时的Bitmap对象
Resources resources = context.getResources();
if (dragimg == null)
dragimg = BitmapFactory.decodeResource(resources,
R.drawable.lock);
range=PhoneUtil.getFitWidth(Constant.RANGE);
margin=PhoneUtil.getFitWidth(Constant.MARGIN);
screenCenter=screenWidth/2;
dragWidth = dragimg.getWidth();
dragHeight = dragimg.getHeight();
//-(dragWidth*2)
lockWidth=screenWidth - (margin * 2)-dragWidth;
dragCenter=dragWidth/2;
startMoveX = screenWidth / 2;
mLastMoveX = startMoveX;
powerWidth = screenWidth / 4;
powerHeight = screenWidth / 4;
leftWidth = screenWidth / 8;
leftHeight = screenWidth / 8;
heightdifferenet=(powerHeight-dragHeight)/2;

leftup=resources.getDrawable(R.drawable.zuo1);
leftdown=resources.getDrawable(R.drawable.zuo2);
rightup=resources.getDrawable(R.drawable.you1);
rightdown=resources.getDrawable(R.drawable.you2);
}

private void setLp() {

LayoutParams lockp = new LayoutParams(lockWidth+dragWidth, -2);
lockp.setMargins(margin, 0, 0, PhoneUtil.getFitHeight(100));
lockp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
this.setLayoutParams(lockp);
}

private void addLockView() {



showpower = new TextView(context);
LayoutParams selectp = new LayoutParams(powerWidth, powerHeight);
selectp.addRule(RelativeLayout.CENTER_HORIZONTAL);
selectp.addRule(RelativeLayout.CENTER_VERTICAL);
// Animation out =
// AnimationUtils.loadAnimation(context,R.anim.lockanim);
showpower.setLayoutParams(selectp);
// lockimg.setBackgroundResource(R.anim.lock_anim);

animationDrawable = (AnimationDrawable) this.getResources()
.getDrawable(R.anim.lock_anim);
showpower.setBackgroundDrawable(animationDrawable);
animationDrawable.start();
showpower.setGravity(Gravity.CENTER);
showpower.setText("21%");
showpower.setTextColor(Color.WHITE);
addView(showpower);
}

private void addLeftAndRightView() {


leftimg = new ImageView(context);
LayoutParams leftp = new LayoutParams(leftWidth, leftHeight);
leftp.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
leftp.addRule(RelativeLayout.CENTER_VERTICAL);
leftimg.setBackgroundDrawable(leftup);
// 修改外边距
leftimg.setLayoutParams(leftp);

rightimg = new ImageView(context);
LayoutParams rightp = new LayoutParams(leftWidth, leftHeight);
rightp.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
rightp.addRule(RelativeLayout.CENTER_VERTICAL);
rightimg.setBackgroundDrawable(rightup);
rightimg.setLayoutParams(rightp);

addView(leftimg);
addView(rightimg);
}

// @Override
// protected void onFinishInflate() {
// // TODO Auto-generated method stub
// super.onFinishInflate();
// // 该控件主要判断是否处于滑动点击区域。滑动时 处于INVISIBLE(不可见)状态,滑动时处于VISIBLE(可见)状态
// }

@Override
public boolean onTouchEvent(MotionEvent event) {

int x = (int) event.getX() + margin;
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
downflag=true;
mLastMoveX = x;
leftimg.setBackgroundDrawable(leftdown);
rightimg.setBackgroundDrawable(rightdown);
// 处理Action_Down事件: 判断是否点击了滑动区域
return handleActionDownEvenet(event);
case MotionEvent.ACTION_MOVE:
mLastMoveX = x; // 保存了X轴方向
invalidate(); // 重新绘制
return true;
case MotionEvent.ACTION_UP:
leftimg.setBackgroundDrawable(leftup);
rightimg.setBackgroundDrawable(rightup);
// 处理Action_Up事件: 判断是否解锁成功,成功则结束我们的Activity ;否则 ,缓慢回退该图片。
handleActionUpEvent(event);
}
return super.onTouchEvent(event);
}

// 手势落下是,是否点中了图片,即是否需要开始移动
private boolean handleActionDownEvenet(MotionEvent event) {
Rect rect = new Rect();
showpower.getHitRect(rect);
boolean isHit = rect.contains((int) event.getX(), (int) event.getY());

if (isHit) // 开始拖拽 ,隐藏该图片
showpower.setVisibility(View.INVISIBLE);
Log_I("action is down and set showpower for false");
return isHit;
}

// 图片更随手势移动
private void invalidateDragImg(Canvas canvas) {
// 以合适的坐标值绘制该图片
int drawXCor = mLastMoveX - dragCenter -margin;

int drawYCor = showpower.getTop()+heightdifferenet;
drawXCor=drawXCor < 0 ? 0 : drawXCor;
drawXCor=drawXCor > lockWidth ? lockWidth : drawXCor;
if(downflag)
canvas.drawBitmap(dragimg, drawXCor, drawYCor, null);
}

// 判断松开手指时,是否达到末尾即可以开锁了 , 是,则开锁,否则,通过一定的算法使其回退。
private void handleActionUpEvent(MotionEvent event) {
int x = (int) event.getX() + margin;
Log_I("x:" + x);
// 距离在RANGE以内代表解锁成功。
int right = getRight();
boolean isSuccessRight = (x>right-dragCenter-range) ? true
: false;
int left = getLeft();
boolean isSuccessLeft = (x<left+dragCenter+range) ? true
: false;

if (isSuccessRight) {
doActionRight();
} else if (isSuccessLeft) {
doActionLeft();
} else {// 没有成功解锁,以一定的算法使其回退
// 每隔20ms , 速率为0.6dip/ms , 使当前的图片往后回退一段距离,直到到达最左端
mLastMoveX = x; // 记录手势松开时,当前的坐标位置。
Log_I("lockimg.getRight():" + showpower.getRight());
int distanceRight = x - screenCenter;
int distanceLeft = screenCenter - x;
// 只有移动了足够距离才回退
if (distanceRight >= 0) {
mHandler.postDelayed(BackDragImgTaskRight, BACK_DURATION);
} else if (distanceLeft >= 0) {
mHandler.postDelayed(BackDragImgTaskLeft, BACK_DURATION);
} else { // 复原初始场景
resetViewState();
}
}
}

// // 重置初始的状态,显示tv_slider_icon图像,使bitmap不可见
private void resetViewState() {
mLastMoveX = startMoveX;
downflag=false;
showpower.setVisibility(View.VISIBLE);
invalidate(); // 重绘最后一次
}

// 通过延时控制当前绘制bitmap的位置坐标
private Runnable BackDragImgTaskRight = new Runnable() {

public void run() {
// 一下次Bitmap应该到达的坐标值
mLastMoveX = mLastMoveX - (int) (BACK_DURATION * VE_HORIZONTAL);

invalidate();// 重绘
// 是否需要下一次动画 ? 到达了初始位置,不在需要绘制
boolean shouldEnd = Math.abs(mLastMoveX - screenCenter) <= 18;
if (!shouldEnd)
mHandler.postDelayed(BackDragImgTaskRight, BACK_DURATION);
else { // 复原初始场景
resetViewState();
}
}
};

private Runnable BackDragImgTaskLeft = new Runnable() {

public void run() {
// 一下次Bitmap应该到达的坐标值
mLastMoveX = mLastMoveX + (int) (BACK_DURATION * VE_HORIZONTAL);

invalidate();// 重绘
// 是否需要下一次动画 ? 到达了初始位置,不在需要绘制
boolean shouldEnd = Math.abs(screenCenter - mLastMoveX) <= 18;
if (!shouldEnd)
mHandler.postDelayed(BackDragImgTaskLeft, BACK_DURATION);
else { // 复原初始场景
resetViewState();
}
}
};

private Handler mHandler = new Handler() {

public void handleMessage(Message msg) {

Log_I("handleMessage :  #### ");
}
};

//
private void doActionLeft() {
Toast.makeText(context, "左边解锁成功", Toast.LENGTH_SHORT).show();
Log_I("左边解锁");
intent.setClass(context, ShowActivity.class);
context.startActivity(intent);
activity.finish();

}

private void doActionRight() {
Toast.makeText(context, "右边解锁成功", Toast.LENGTH_SHORT).show();
virbate(); // 震动一下
// 结束我们的主Activity界面
Log_I("右边解锁");
activity.finish();
}

// 绘制拖动时的图片
@Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
// 图片更随手势移动
invalidateDragImg(canvas);
}

// 震动一下
private void virbate() {
Vibrator vibrator = (Vibrator) context
.getSystemService(Context.VIBRATOR_SERVICE);
vibrator.vibrate(300);
}

public TextView getShowpowerText() {
return this.showpower;
}

void Log_I(String log) {
// LogHelper.Log_I(this.getClass().getSimpleName(), log);
}
}


谢谢你,不过貌似也搞得也太复杂了,我的问题应该不会需要类似那么多代码的。
补充:移动开发 ,  Android
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,