本文实例为大家分享了Android创建可拖动图片控件的具体代码,供大家参考,具体内容如下

重载、自绘

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函数是根据图片尺寸计算适合屏幕居中的方法。

运行程序

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

02-06 03:12
查看更多