Android DragImageView实现下拉拖动图片放大效果

DragImageView下拉拖动图片放大,先上图:

主要的类:继承了RelativeLayout,再在RelativeLayout里面添加ImageView,通过Touch事件来改变ImageView的缩放,缩放时计算scale,使其在手指移动到屏幕底部时,图片底部也刚好到达屏幕底部,手指松开时,图片逐步回弹。

package com.example.dragimagescale; 

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.graphics.PointF;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.MotionEvent;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;
import android.widget.RelativeLayout; 

public class DragScaleImageView extends RelativeLayout {
 private String TAG = "DragScaleImageView";
 private static final int BACK_SCALE = 1010; 

 private Context mContext;
 private AttributeSet attrs;
 private int displayWidth = 0;
 private int displayHeight = 0;
 private int mImageId;
 private Bitmap bmp;
 private ImageView imageView; 

 /** 是否处在回弹状态 */
 private boolean isBacking = false; 

 /** 用于记录拖拉图片移动的坐标位置 */
 private Matrix matrix = new Matrix();
 /** 用于记录图片要进行拖拉时候的坐标位置 */
 private Matrix currentMatrix = new Matrix();
 private Matrix defaultMatrix = new Matrix();
 /** 图片的宽高 */
 private float imgHeight, imgWidth;
 /** 初始状态 */
 private int mode = 0;
 /** 拖拉照片模式 */
 private final int MODE_DRAG = 1; 

 private float scaleY = 0; 

 /** 用于记录开始时候的坐标位置 */
 private PointF startPoint = new PointF(); 

 /** 用于记录开始时候的在整个屏幕中的Y坐标位置 */
 private float startRawY = 0;
 float scale = 1; 

 private TouchEventListener touchEventListener = null;
 private BackScaleListener backScaleListener = null; 

 public DragScaleImageView(Context context, AttributeSet attrs) {
  super(context, attrs);
  // TODO Auto-generated constructor stub
  this.mContext = context;
  this.attrs = attrs;
  initView();
 } 

 public DragScaleImageView(Context context) {
  super(context);
  // TODO Auto-generated constructor stub
  this.mContext = context;
  initView();
 } 

 public DragScaleImageView(Activity activity, Bitmap resBitmap, int width,
   int height) {
  super(activity);
 } 

 /**
  * 初始化图片
  */
 private void initView() {
  /* 取得屏幕分辨率大小 */
  DisplayMetrics dm = new DisplayMetrics();
  WindowManager mWm = (WindowManager) mContext
    .getSystemService(Context.WINDOW_SERVICE);
  mWm.getDefaultDisplay().getMetrics(dm);
  displayWidth = dm.widthPixels;
  displayHeight = dm.heightPixels; 

  TypedArray a = mContext.obtainStyledAttributes(attrs,
    R.styleable.DragScaleImageView);
  mImageId = a.getResourceId(R.styleable.DragScaleImageView_scale_image,
    0);
  a.recycle();
  if (null == bmp && mImageId != 0) {
   bmp = BitmapFactory.decodeResource(getResources(), mImageId);
   float scale = (float) displayWidth / (float) bmp.getWidth();// 1080/1800
   matrix.postScale(scale, scale, 0, 0);
   imgHeight = scale * bmp.getHeight();
   imgWidth = scale * bmp.getWidth();
  } else {
   imgHeight = displayWidth;
   imgWidth = displayWidth;
  }
  initImageView();
 } 

 private void initImageView() {
  imageView = new ImageView(mContext);
  imageView.setImageMatrix(matrix);
  defaultMatrix.set(matrix);
  Log.w(TAG, "imgWidth :" + imgWidth);
  Log.w(TAG, "imgHeight :" + imgHeight); 

  RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(
    (int) imgWidth, (int) imgHeight);
  imageView.setLayoutParams(layoutParams);
  imageView.setImageBitmap(bmp);
  imageView.setScaleType(ScaleType.CENTER_CROP);
  this.addView(imageView);
 } 

 /**
  * 设置ImageView的宽高
  *
  * @param width
  * @param height
  */
 public void setImageWidthAndHeight(int width, int height) {
  imgWidth = width;
  imgHeight = height;
  RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(
    (int) imgWidth, (int) imgHeight);
  imageView.setLayoutParams(layoutParams);
 } 

 public boolean onTouchEvent(MotionEvent event) {
  Log.w(TAG, "onTouchEvent :" + event.getAction());
  // 当该View放置在ScrollView里面时,会与父控件Touch事件冲突,所以touch该控件区域时,父控件不可用
  if (event.getAction() == MotionEvent.ACTION_UP) {
   getParent().requestDisallowInterceptTouchEvent(false);
  } else {
   getParent().requestDisallowInterceptTouchEvent(true);// true表示父类的不可用;
  }
  switch (event.getAction() & MotionEvent.ACTION_MASK) {
  // 手指压下屏幕
  case MotionEvent.ACTION_DOWN:
   if (isBacking) {
    return super.onTouchEvent(event);
   }
   int[] location = new int[2];
   imageView.getLocationInWindow(location);
   if (location[1] >= 0) {
    mode = MODE_DRAG;
    // 记录ImageView当前的移动位置
    currentMatrix.set(imageView.getImageMatrix());
    startPoint.set(event.getX(), event.getY());
    startRawY = event.getRawY();
    Log.w(TAG, "onTouchEvent startRawY:" + startRawY);
   }
   break;
  // 手指在屏幕上移动,改事件会被不断触发
  case MotionEvent.ACTION_MOVE:
   // 拖拉图片
   if (mode == MODE_DRAG) {
//    float dx = event.getX() - startPoint.x; // 得到x轴的移动距离
    float dy = event.getY() - startPoint.y; // 得到y轴的移动距离
    // 在没有移动之前的位置上进行移动
    if (dy > 0) {
     matrix.set(currentMatrix);
     Log.w(TAG, "onTouchEvent dy:" + dy);
     scale = ((dy / (displayHeight - startRawY) * (displayHeight - imgHeight)) + imgHeight)
       / imgHeight; // 得到缩放倍数,当手指移动到屏幕底部时,图片也达到屏幕底部
     Log.w(TAG, "onTouchEvent scale:" + scale); 

     scaleY = dy;
     RelativeLayout.LayoutParams relativeLayout = new RelativeLayout.LayoutParams(
       (int) (scale * imgWidth), (int) (scale * imgHeight));
     imageView.setLayoutParams(relativeLayout);
     matrix.postScale(scale, scale, imgWidth / 2, 0);
     imageView.setImageMatrix(matrix);
    }
   }
   break;
  // 手指离开屏幕
  case MotionEvent.ACTION_UP:
   // 当触点离开屏幕,图片还原
   mHandler.sendEmptyMessage(BACK_SCALE);
  case MotionEvent.ACTION_POINTER_UP:
   // 当两个手指移动时,取消移动图片
   mode = 0;
   break;
  }
  // 设置的Touch监听事件
  if (touchEventListener != null) {
   touchEventListener.onTouchEvent(event);
  }
  return true;
 } 

 /** 逐步回弹 */
 @SuppressLint("HandlerLeak")
 private Handler mHandler = new Handler() {
  @Override
  public void handleMessage(Message msg) {
   // TODO Auto-generated method stub
   switch (msg.what) {
   case BACK_SCALE:
    scale = (scaleY / 2 + imgHeight) / (imgHeight);// 得到缩放倍数
    if (scaleY > 0) {
     isBacking = true;
     matrix.set(currentMatrix);
     RelativeLayout.LayoutParams relativeLayout = new RelativeLayout.LayoutParams(
       (int) (scale * imgWidth), (int) (scale * imgHeight));
     imageView.setLayoutParams(relativeLayout);
     matrix.postScale(scale, scale, imgWidth / 2, 0);
     imageView.setImageMatrix(matrix);
     scaleY = (float) (scaleY / 2 - 1);
     mHandler.sendEmptyMessageDelayed(BACK_SCALE, 20);// 逐步回弹
    } else {
     scaleY = 0;
     RelativeLayout.LayoutParams relativeLayout = new RelativeLayout.LayoutParams(
       (int) imgWidth, (int) imgHeight);
     imageView.setLayoutParams(relativeLayout);
     matrix.set(defaultMatrix);
     imageView.setImageMatrix(matrix);
     isBacking = false;
    }
    if (backScaleListener != null) {
     backScaleListener.onBackScale();
    }
    break;
   default:
    break;
   }
   super.handleMessage(msg);
  }
 }; 

 public void setTouchEventListener(TouchEventListener touchEventListener) {
  this.touchEventListener = touchEventListener;
 } 

 public void setBackScaleListener(BackScaleListener backScaleListener) {
  this.backScaleListener = backScaleListener;
 } 

 /** Touch事件监听 */
 public interface TouchEventListener {
  public void onTouchEvent(MotionEvent event);
 }
 /** 回弹事件监听 */
 public interface BackScaleListener {
  public void onBackScale();
 }
} 

调用的Activity:

package com.example.dragimagescale; 

import com.example.dragimagescale.DragScaleImageView.BackScaleListener;
import com.example.dragimagescale.DragScaleImageView.TouchEventListener; 

import android.app.Activity;
import android.os.Bundle;
import android.view.MotionEvent; 

public class MainActivity extends Activity { 

 DragScaleImageView mDragScaleImageView; 

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main); 

  mDragScaleImageView = (DragScaleImageView) findViewById(R.id.dragScaleImageView);
  /** 自定义ImageView的宽高,若不设置则按图片宽高压缩至屏幕宽度 */
//  mDragScaleImageView.setImageWidthAndHeight(720, 300);
  // Touch事件监听
  mDragScaleImageView.setTouchEventListener(new TouchEventListener() { 

   @Override
   public void onTouchEvent(MotionEvent event) {
    // TODO Auto-generated method stub
    // do something here
   }
  });
  // 回弹事件监听
  mDragScaleImageView.setBackScaleListener(new BackScaleListener() { 

   @Override
   public void onBackScale() {
    // TODO Auto-generated method stub
    // do something here
   }
  });
 } 

} 

xml 布局文件:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:tools="http://schemas.android.com/tools"
 xmlns:dragscaleimageview="http://schemas.android.com/apk/res/com.example.dragimagescale"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:background="#ffffff" > 

 <com.example.dragimagescale.DragScaleImageView
  android:id="@+id/dragScaleImageView"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  dragscaleimageview:scale_image="@drawable/image"
  >
 </com.example.dragimagescale.DragScaleImageView> 

</RelativeLayout>

下载:源码

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

(0)

相关推荐

  • Android实现图片拖动效果

    要求: 1.通过手指移动来拖动图片 2.控制图片不能超出屏幕显示区域 技术点: 1.MotionEvent处理 2.对View进行动态定位(layout) activity_main.xml: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layou

  • Android编程实现支持拖动改变位置的图片中叠加文字功能示例

    本文实例讲述了Android编程实现支持拖动改变位置的图片中叠加文字功能.分享给大家供大家参考,具体如下: 之所以做了这么一个Demo,是因为最近项目中有一个奇葩的需求:用户拍摄照片后,分享到微信的同时添加备注,想获取用户在微信的弹出框输入的内容,保存在自己的服务器上.而事实上,这个内容程序是无法获取的,因此采取了一个折衷方案,将文字直接写在图片上. 首先上Demo效果图: 功能: 1.用户自由输入内容,可手动换行,并且行满也会自动换行. 2.可拖动改变图片中文本位置(文字不会超出图片区域).

  • android浮层图片拖动并且可点击效果

    最近产品出了个新需求,页面上出现浮层并且可点击,代码实现如下: Activity中实现浮层图片: @Override public void onResume() { super.onResume(); createView(); } @Override public void onPause() { super.onPause(); / 在程序退出(Activity销毁)时销毁悬浮窗口 if(floatView!=null && windowManager !=null) { windo

  • 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编程实现图片的浏览.缩放.拖动和自动居中效果的方法.分享给大家供大家参考,具体如下: Touch.java /** * 图片浏览.缩放.拖动.自动居中 */ public class Touch extends Activity implements OnTouchListener { Matrix matrix = new Matrix(); Matrix savedMatrix = new Matrix(); DisplayMetrics dm; ImageVie

  • Android实现ImageView图片缩放和拖动

    今天我们来编写一个缩放效果的ImageView ,网上有很多人都讲了这些.但有许多人都直接使用了库文件, 那么我们今天做的是直接上代码编写一个拖动和缩放的ImageView,具体看效果图 那么简单了分析一下.在手机上缩放图片和拖动要用到什么?手指对不对 那么控件上什么事件和手机有关.View.OnTouchListener 对不对. ok,那么先新建一个Class ··· public class BaseDragZoomImageView extends ImageView implement

  • android Matrix实现图片随意放大缩小或拖动

    本文实例为大家分享了android Matrix图片随意放大缩小和拖动的具体代码,供大家参考,具体内容如下 step1:新建一个项目DragAndZoom,并准备一张照片放在res/drawable-hdpi目录下,如下图所示: step2: 设置应用的UI界面,在main.xml中设置: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://

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

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

  • Android DragImageView实现下拉拖动图片放大效果

    DragImageView下拉拖动图片放大,先上图: 主要的类:继承了RelativeLayout,再在RelativeLayout里面添加ImageView,通过Touch事件来改变ImageView的缩放,缩放时计算scale,使其在手指移动到屏幕底部时,图片底部也刚好到达屏幕底部,手指松开时,图片逐步回弹. package com.example.dragimagescale; import android.annotation.SuppressLint; import android.a

  • Android仿QQ好友详情页下拉顶部图片缩放效果

    本文实例为大家分享了Android下拉顶部图片缩放效果展示的具体代码,供大家参考,具体内容如下 效果图 效果分析 1 向下滑动,头部的图片随着手指滑动不断变大 2 向上滑动,不断的向上移动图片,直到图片不可见 3 当顶部图片不可见时,向上滑动,滑动ListView 实现思路 1 由于这个View分上下两部分,垂直排列,可以通过继承LinearLayout实现::自定义一个DragImageView,该View继承LinearLayout public DragImageView(Context

  • Android ListView实现下拉顶部图片变大效果

    本文实例为大家分享了Android ListView下拉顶部图片变大的具体代码,供大家参考,具体内容如下 在git上查看牛人的代码,发现是反编译别人的代码,还没加注释,代码也没有完全编译完整,所以这里我做的简单的注释,仅供学习. 变量说明 这里变量包含了:自定义返回动画加速度.自定义动画线程.头部图片view,最后的y坐标,做好的比例,做大的比例等. private static final String TAG = "PullToZoomListView"; private stat

  • Android轮播图点击图片放大效果的实现方法

    前言 最近项目中需要实现轮播图显示商品图片,当用户点击商品图片的时候,需要图片放大显示,当然用户还能进行多张图片的滑动切换,放大,缩小图片等操作,实现起来相对还是比较简单的,话不多说,咱们是用代码说话的,直接上代码. 实现步骤: 1.效果图的展示 2.项目中添加相关的依赖 3.主界面实现轮播图的效果 4.点击轮播图进入图片放大展示页面 5.图片放大展示页面所需的适配器 6.获取fragment需要展示图片的url 7.图片缩放时遇到Bug解决 实现过程: 1.效果图的展示 2.项目中添加相关的依

  • android组件SwipeRefreshLayout下拉小球式刷新效果

    swiperefreshlayout实现下拉小球式的刷新,供大家参考,具体内容如下 布局文件: <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools&quo

  • Android ScrollView实现下拉弹回动画效果

    这里设计一个自定义View,继承了ScrollView,实现可以下拉里面的内容,松手后画面弹回,这个自定义的View可以当做ScrollView来使用. 一般设计时的应用效果: 一.自定义View的设计代码 package com.lwz.mathbox.weight; import android.content.Context; import android.graphics.Rect; import android.util.AttributeSet; import android.vie

  • Android仿今日头条APP实现下拉导航选择菜单效果

    本文实例为大家分享了在Android中如何实现下拉导航选择菜单效果的全过程,供大家参考,具体内容如下 关于下拉导航选择菜单效果在新闻客户端中用的比较多,当然也可以用在其他的项目中,这样可以很方便的选择更多的菜单.我们可以让我们的应用顶部有左右滑动或进行切换的导航菜单,也可以为了增强用户体验在应用中添加这样的下拉导航选择菜单效果. 关于它的实现原理,其实也是挺简单的,就是使用PopupWindow来进行展现,在显示时控制其高度并配置以相应的动画效果.在PopupWindow中我使用GridView

  • iOS tableView实现下拉图片放大效果

    本文实例为大家分享了iOS实现下拉图片放大效果展示的具体代码,供大家参考,具体内容如下 #import "ViewController.h" #define kScreenbounds [UIScreen mainScreen].bounds #define kScreenWidth [UIScreen mainScreen].bounds.size.width #define kScreenHeight [UIScreen mainScreen].bounds.size.height

  • Android背景图下拉回弹效果实例

    目录 Android实现背景图下拉回弹效果 效果 实现 总结 Android实现背景图下拉回弹效果 增加设置不横向拉伸时增加回弹效果 增加切换横屏时可滑动效果 效果 实现 public class HeadZoomScrollView extends NestedScrollView { public HeadZoomScrollView(Context context) { super(context); } public HeadZoomScrollView(Context context,

  • Android仿美团下拉菜单(商品选购)实例代码

    美团电商应用平台大家使用非常频繁,下面小编通过本文给大家介绍电商应用平台中常用的选择类别下拉列表的实现.先给大家展示下效果图: 一.下拉列表的实现 其实实现方法有很多,这时实现的也没有什么技术含量,只是总结下自己在项目中的做法,也提供一个思路. 首先是列表的数据,一般数据都是从后台读过来,这里因为没有后台,所以写死在客户端: private void initMenuData() { menuData = new ArrayList<map<string, string=""

随机推荐