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 UI控件之Gallery实现拖动式图片浏览效果
  • Android中SeekBar拖动条控件使用方法详解
  • Android控件拖动实例详解
  • Android通过自定义ImageView控件实现图片的缩放和拖动的实现代码
  • Android基于widget组件实现物体移动/控件拖动功能示例
  • Android 仿淘宝、京东商品详情页向上拖动查看图文详情控件DEMO详解
  • Android使用WindowManager制作一个可拖动的控件
  • Android编程之控件可拖动的实现方法
(0)

相关推荐

  • Android UI控件之Gallery实现拖动式图片浏览效果

    我们知道现在智能手机上都有这样一种功能,就是你在浏览图片的时候.不是硬性的点击按钮而是可以实现手指的拖动,划开效果.使用户具有更好的交互体验,不过这种效果是如何实现的呢? 在Android中是通过Gallery来实现拖动效果的. 通过Gallery可以实现各种各样的效果,此篇文章只是简要谈谈他的用法,至于后续的一些效果 有机会的时候做一个整理. 首先看看其简单实现吧!本次实例是通过选取图片实现类似设置背景的功能! 不过需要说明的是:图片不宜过大,否则容易内存溢出,android对大图片的支持不好

  • Android通过自定义ImageView控件实现图片的缩放和拖动的实现代码

    概述:通过自定义ImageView控件,在xml布局里面调用自定的组件实现图片的缩放. /** * 自定义的ImageView控制,可对图片进行多点触控缩放和拖动 * * @author qiuwanyong */ public class MyImageView extends ImageView { /** * 初始化状态常量 */ public static final int STATUS_INIT = 1; /** * 图片放大状态常量 */ public static final i

  • Android控件拖动实例详解

    Android控件拖动 Android控件的拖动,主要是通过设置控件的setOnTouchListener()方法,重写它的onTouch()方法.然后通过MotionEvent的不同事件,进行判断,主要是在MotionEvent.ACTION_MOVE中不断重绘控件在画布中的位置,而实现拖动的效果. public class DragViewActivity extends AppCompatActivity { private Button btn_drag; @Override prote

  • Android基于widget组件实现物体移动/控件拖动功能示例

    本文实例讲述了Android基于widget组件实现物体移动/控件拖动功能.分享给大家供大家参考,具体如下: package com.sky; import android.app.Activity; import android.os.Bundle; import android.view.KeyEvent; import android.view.MotionEvent; import android.view.View; import android.view.View.OnClickLi

  • Android中SeekBar拖动条控件使用方法详解

    SeekBar拖动条控件使用方法,具体内容如下 一.简介 1.  二.SeekBar拖动条控件使用方法 1.创建SeekBar控件 <SeekBar android:id="@+id/SeekBar1" android:layout_width="match_parent" android:layout_height="wrap_content" android:progress="30" /> 2.添加setOn

  • Android使用WindowManager制作一个可拖动的控件

    效果图如下 第一步:新建DragView继承RelativeLayout package com.rong.activity; import com.rong.test.R; import android.content.Context; import android.graphics.Color; import android.graphics.PixelFormat; import android.util.AttributeSet; import android.view.Gravity;

  • Android 仿淘宝、京东商品详情页向上拖动查看图文详情控件DEMO详解

    一.淘宝商品详情页效果 我们的效果 二.实现思路 使用两个scrollView,两个scrollView 竖直排列,通过自定义viewGroup来控制两个scrollView的竖直排列,以及滑动事件的处理.如下图 三.具体实现 1.继承viewGroup自定义布局View 重写onMeasure()和onLayout方法,在onLayout方法中完成对两个子ScrollView的竖直排列布局,代码如下: 布局文件: <RelativeLayout xmlns:android="http:/

  • Android编程之控件可拖动的实现方法

    本文实例讲述了Android编程之控件可拖动的实现方法.分享给大家供大家参考,具体如下: 点击和触摸的区别是什么? 点击: 一组动作的集合 手指按下着按钮 手指要在按钮停留一段时间 手指离开按钮 private static final String TAG = "DragViewActivity"; private ImageView iv_dv_view; private TextView tv_drag_view; private int startx; private int

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

    本文实例为大家分享了Android创建可拖动图片控件的具体代码,供大家参考,具体内容如下 重载.自绘 1.从View派生一个控件类 ,构造函数中调用父类构造器. 2.重载其onDraw函数,在里面绘制图片.(和windows的MFC有种似曾相识的感觉,可能安卓借鉴了windows的模式吧) 消息处理 拖动图片的消息,主要是处理按下和移动两个消息,重载onTouchEvent.数学知识(平移):在ACTION_DOWN时记录下坐标点,在ACTION_MOVE时根据当前位置与按下时的位置算出平移量.

  • Android自定义View之自定义评价打分控件RatingBar实现自定义星星大小和间距

    在Android开发中,我们经常会用到对商家或者商品的评价,运用星星进行打分.然而在Android系统中自带的打分控件,RatingBar特别不好用,间距和大小无法改变.所以,我就自定义了一个特别好用的打分控件.在项目中可以直接使用,特别简单.下面直接上图: 效果图 实现原理 其实就是自定义View继承LinearLayout ,然后里面动态加了五个ImageView. 实现代码,有详细的注释 在attrs中声明的可以在xml中设置的变量 <declare-styleable name="

  • Android开发实现AlertDialog中View的控件设置监听功能分析

    本文实例讲述了Android开发实现AlertDialog中View的控件设置监听功能.分享给大家供大家参考,具体如下: 之前给弹出的AlertDialog中的控件设置监听时,老是报空指针异常,之所以报空指针异常,是因为我findViewById写的有问题,因为我们需要给弹出框中的控件设置监听,直接用findViewById是找不到弹出框中的控件的,需要利用Dialog.findViewById或者利用你找到的弹出框中的View,然后view.findViewById;具体看下面代码 packa

  • Android自定义View之简约风歌词控件实战指南

    目录 前言 一. 歌词解析 1.歌词实体类LrcBean 2. 解析歌词工具类LrcUtil 二.歌词绘制 1.设置自定View属性,在代码中设置默认值 2. 初始化两支画笔 3. 重复执行onDraw方法 1.获得控件的测量后的宽高 2. 得到当前歌词的位置 4. 歌词同步滑动 5.不断重绘 三 .使用 总结 前言 最近重构了之前的音乐播放器,添加了许多功能,比如歌词,下载功能等.这篇文章就让我们聊聊歌词控件的实现,先上效果图,如果感觉海星,就继续瞧下去! 看到这里,估计你对这个控件还有点感兴

  • Android自定义ViewGroup实现朋友圈九宫格控件

    目录 一.简介 1.1.效果图如下 1.2.主要功能如下 二.使用 2.1.自定义属性如下 2.2.布局中使用自定义NineImageLayout 2.3.Adapter方式绑定数据和UI 2.4.列表里面使用 三.源码地址 四.总结 一.简介 最近项目里有个类似微信朋友圈的九图控件的需求,Github找了一下,发现都不太满足需求,我需要单张图片的时候可以按照图片宽高比列在一定范围内自适应,而大多开源项目单张图片也是一个小正方形,所以,干脆自己动手写一个 1.1.效果图如下 1.2.主要功能如下

  • 如何创建一个AJAXControlToolKit的扩展控件

    微软的AJAXControlToolKit提供了很容易的扩展方式,小弟我也是初学ajaxcontroltoolkit的扩展,所以这里举个例子,一起来学习,如果有什么好的建议和例子请提出来一起分享. 其实Microsoft的ajax官网给出的扩展说明已经很详细了,而且有个例子,严格来说确实有点简单,但是总结一下每个扩展控件大致需要注意如下几点: 1. 必须添加的dll: System.Web.dll , System.Web.Extensions.dll, System.Design.dll, S

  • Android开发中DatePicker日期与时间控件实例代码

    一.简介 二.方法 最日常的使用方法了 日期控件DatePicker 时间控件TimePicker 月份从0开始 三.代码实例 效果图: 代码: fry.Activity01 package fry; import com.example.DatePicherDemo1.R; import android.app.Activity; import android.os.Bundle; import android.widget.DatePicker; import android.widget.

  • Android拆轮子系列之写验证码控件的方法

    前言 先看看效果 怎么样不错吧?别急下面我就一步一步的教你实现. 用到的知识点总结: 1.Canvas和pint的使用,我们用它画点,线,字 2.View的基本用法 其实做这个东西还是很简单的,总体思路步骤如下: 1.准备一个Canvas. 2.向Canvas里面画几条斜杠. 3.向canvas里面画100个小点. 4.随机生成4个数字,然后画在canvas里面. 其实就是这么简单,没什么深奥的. 开始写编码 1.首先我们要重写View 既然我们要画验证码,那么我们就需要准备画笔(paint)和

  • 解决Android Studio Design界面不显示layout控件的问题

    Android Studio更新到3.1.3后,发现拖到Design中的控件在预览界面中不显示: 解决办法: 在Styles.xml中的parent="..."中的Theme前添加Base <resources> <!-- Base application theme. --> <style name="AppTheme" parent="Base.Theme.AppCompat.Light.DarkActionBar&quo

随机推荐