软件编程
位置:首页>> 软件编程>> Android编程>> Android如何创建可拖动的图片控件

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

作者:疯狂-的-蜗牛  发布时间:2022-11-25 04:02:00 

标签:Android,拖动,控件

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

运行程序

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

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

来源:https://blog.csdn.net/mfcing/article/details/48790235

0
投稿

猜你喜欢

  • Java枚举类使用Lombok枚举类是一个特殊的常量类,由于其特殊的设计,具有简洁性、安全性以及便捷性,在开发中被普遍使用。本文简单介绍一下
  • 规则1(无继承情况下):对于静态变量、静态初始化块、变量、初始化块、构造器,它们的初始化顺序依次是(静态变量、静态初始化块)>(变量、
  • 本文研究的主要是java网络爬虫连接超时的问题,具体如下。在网络爬虫中,经常会遇到如下报错。即连接超时。针对此问题,一般解决思路为:将连接时
  • 一、使用策略枚举来优化if-else看到网上蛮多人推荐使用策略模式来优化if-else,但我总觉得,搞一堆策略类来优化大批量if-else,
  • 今天就是国赛的第一天直接开摆打国赛不如玩羊了个羊玩羊了个羊不如玩MATLAB版写作不易留个赞叭(比赛之余放松一下也行,反正MATLAB版我设
  • 一、实验目的(1)掌握应用黑盒测试技术进行测试用例设计。(2)掌握对测试用例进行优化设计方法。二、实验内容日期问题测试以下程序:该程序有三个
  • 相信大家都有这样的一个需求,选择相应开始时间和结束时间,对数据进行筛选,下面就将使用TimePickerView实现这么一个功能。一、先导入
  • 其实SynchronousQueue 是一个特别有意思的阻塞队列,就我个人理解来说,它很重要的特点就是没有容量。直接看一个例子:packag
  • 标识符Java 对各种变量、方法和类等要素命名时使用的字符序列称为标识符技巧:凡是自己可以起名字的地方都叫标识符定义合法标识符规则:由26个
  • 前言在Java中,Range方法在IntStream和LongStream类中都可用。在IntStream类中,它有助于返回函数参数范围内I
  • 对象创建的几种方法:使用new关键字使用clone方法反射机制反序列化以上四种都可以产生java对象1,3都会明确的显式的调用构造函数2是在
  • maven3 安装:安装 Maven 之前要求先确定你的 JDK 已经安装配置完成。Maven是 Apache 下的一个项目,目前最新版本是
  • 使用场景在 Java 应用中,对于访问频率高,更新少的数据,通常的方案是将这类数据加入缓存中。相对从数据库中读取来说,读缓存效率会有很大提升
  • java.sql.Timestamp(时间戳)继承父类:java.util.Date所有已实现的接口:Serializable, Clone
  • 本文实例讲述了如何计算(或者说,估算)一个Java对象占用的内存数量的方法。分享给大家供大家参考。具体分析如下:通常,我们谈论的堆内存使用的
  • 前言众所周知,Struts2是个非常优秀的开源框架,我们能用Struts2框架进行开发,同时能快速搭建好一个Struts2框架,但我们是否能
  • 单例模式一个类只有一个实例,并且可以全局访问使用应用场景如账户管理类,数据库操作类等(某个对象频繁被访问使用)常用方式饿汉式懒汉式同步加锁D
  • 在jdk1.4中提出的技术,非阻塞IO,采用的是基于事件处理方式。传统的io技术为阻塞的,比如读一个文件,惹read方法是阻塞的,直到有数据
  • 这篇文章主要介绍了Spring配置文件如何使用${username},文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习
  • 本文介绍了Android是如何设置组件半透明和透明的效果,分享出来供大家参考,下面来看看详细的介绍:1、Button或者ImageButto
手机版 软件编程 asp之家 www.aspxhome.com