首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android如何创建可拖动的图片控件

Android如何创建可拖动的图片控件

作者头像
砸漏
发布2020-11-04 13:28:38
2.1K0
发布2020-11-04 13:28:38
举报
文章被收录于专栏:恩蓝脚本恩蓝脚本

本文实例为大家分享了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函数是根据图片尺寸计算适合屏幕居中的方法。

运行程序

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

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-09-11 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档