安卓开发实例一:创建可拖动的图片控件

重载、自绘

1、从View派生一个控件类 ,构造函数中调用父类构造器。

2、重载其onDraw函数,在里面绘制图片。(和windows的MFC有种似曾相识的感觉,可能安卓借鉴了windows的模式吧)

消息处理

拖动图片的消息,主要是处理按下和移动两个消息,重载onTouchEvent。数学知识(平移):在ACTION_DOWN时记录下坐标点,在ACTION_MOVE时根据当前位置与按下时的位置算出平移量。刷新控件,导致控件重绘,重绘时移动绘制的左上角坐标即可。

刚开始时,只是收到了ACTION_DOWN消息,ACTION_MOVE消息就是捕捉不到,上网搜了下,原来是我在onTouchEvent最后调用了父类函数return super.onTouchEvent(event);父类里面返回false表示对这些消息不予关注,后续的ACTION_MOVE和ACTION_UP就不会进来了。

代码和配置

activity的XML配置

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >
	<com.example.timertest.DragImageView 
	    android:id="@+id/div"
	    android:layout_width="fill_parent"
	    android:layout_height="fill_parent"
	/>
</LinearLayout>

控件的自绘代码

package com.example.timertest;


import java.util.ArrayList;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;

@SuppressLint("ClickableViewAccessibility")
public class DragImageView extends View{
	
	private Bitmap bmp = null;
	private PointF orgPos = new PointF(0, 0);
	private PointF downPos = new PointF(0, 0);
	private PointF movePos = new PointF(0, 0);
	private boolean bMove = false;
	private int nDstWidth = 0;
	private int nDstHeight = 0;
	private Rect rcSrc = new Rect(0, 0 , 0, 0);
	private RectF rcDst = new RectF(0, 0, 0, 0);
	private Paint paint = null;
	public DragImageView(Context context) {
		super(context);
		// TODO Auto-generated constructor stub
		paint = new Paint(Paint.ANTI_ALIAS_FLAG);
		//setOnClickListener(new DivOnClickListener());
		//setOnTouchListener(l);
	}
	
	public DragImageView(Context context, AttributeSet attrs) {
		super(context, attrs);
		//bmp = img;
		paint = new Paint(Paint.ANTI_ALIAS_FLAG);
	}
	public DragImageView(Context context, AttributeSet attrs, int defStyleAttr){
		super(context, attrs, defStyleAttr);
		paint = new Paint(Paint.ANTI_ALIAS_FLAG);
	}
	
	public void SetImage(Bitmap img){
		if ( bmp != null ){
			bmp = null;
		}
		bmp = img;
	}

	@Override
	public void addTouchables(ArrayList<View> views) {
		// TODO Auto-generated method stub
		super.addTouchables(views);
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		// TODO Auto-generated method stub
		float fPosX = event.getX();
		float fPosY = event.getY();
		int nAct = event.getAction();
		switch ( nAct ){
		case MotionEvent.ACTION_MOVE:{
			if ( !bMove )
				bMove = true;
			movePos.x = fPosX - downPos.x;
			movePos.y = fPosY - downPos.y;
			downPos.x = fPosX;
			downPos.y = fPosY;
			invalidate();
		}
			break;
		case MotionEvent.ACTION_DOWN:{
			downPos.x = fPosX;
			downPos.y = fPosY;
		}
			break;
		case MotionEvent.ACTION_UP:
			break;
		}
		//一定要返回ture,如果返回父类方法即false,则后续的move up 消息都不会触发。
		return true;
		//return super.onTouchEvent(event);
	}

	@Override
	protected void onDraw(Canvas canvas) {
		// TODO Auto-generated method stub
		super.onDraw(canvas);
		if ( bmp == null )
			return ;
		int nWidth = bmp.getWidth();
		int nHeight = bmp.getHeight();
		if ( !bMove ){
			orgPos = GetCenterPos();
		}
		else{
			orgPos.x += movePos.x;
			orgPos.y += movePos.y;
		}
		rcSrc.right = nWidth;
		rcSrc.bottom = nHeight;
		rcDst.left = orgPos.x;
		rcDst.top = orgPos.y;
		rcDst.right = orgPos.x+nDstWidth;
		rcDst.bottom = orgPos.y+nDstHeight;
		canvas.drawBitmap(bmp, rcSrc, rcDst, paint);
	}
	
	protected PointF GetCenterPos(){
		PointF pt = new PointF(0, 0);
		if ( bmp == null )
			return pt;
		WindowManager wm = (WindowManager)getContext().getSystemService(Context.WINDOW_SERVICE);
		//wm.getDefaultDisplay().getSize(pt);
		int nScrWidth = wm.getDefaultDisplay().getWidth();
		@SuppressWarnings("deprecation")
		int nScrHeight = wm.getDefaultDisplay().getHeight();
		int nWidth = bmp.getWidth();
		int nHeight = bmp.getHeight();
		float fImgRate = nWidth/(float)nHeight;
		float fScrRate = nScrWidth/(float)nScrHeight;
		if ( nWidth>nScrWidth && nHeight>nScrHeight ){
			if ( fImgRate > fScrRate ){
				
				nDstWidth = nScrWidth;
				nDstHeight = (int)(nScrWidth/fImgRate);

			}
			else{
				
				nDstHeight = nScrHeight;
				nDstWidth= (int)(nScrHeight*fImgRate);
	
			}
		}
		else if ( nWidth>nScrWidth ){
			nDstWidth = nScrWidth;
			nDstHeight = nHeight;
		}
		else if ( nHeight>nScrHeight ){
			nDstWidth = nWidth;
			nDstHeight = nScrHeight;
		}
		else{
			nDstWidth = nWidth;
			nDstHeight = nHeight;
		}
		pt.y = (nScrHeight-nDstHeight)/2.0f;
		pt.x = (nScrWidth-nDstWidth)/2.0f;
		return pt;
	}
	

}

其中GetCenterPos函数是根据图片尺寸计算适合屏幕居中的方法。

运行程序


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值