android 大图片拖拽并缩放实现原理
发布时间:2022-11-10 05:59:55
标签:图片,拖拽,缩放
由于最近项目忙,博客一直没有时间更新,今天有点时间就连续更新两篇吧,过过瘾。
这篇图片拖拽缩放也是我在项目中用到的,今天整理一下,将源码奉献给大家,希望对大家以后碰到相似的问题有帮助。
这篇就不做过多介绍了,直接上源码:
public class SpacePageActivity extends Activity {
private LinearLayout linnerLayout_spacepage;
private RelativeLayout relativeLayout_spacepage;
private Button btn_spacepage_back;
private Button btn_spacepage_save;
private static Boolean isTrue=false;
private static String IMAGE_MIME_TYPE ;
private ImageView image_spacePage;
private ProgressDialog dialog;
private Bitmap bitmap;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);//隐藏标题
setContentView(R.layout.spacepage);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
initHead();
if(isNetworkAvailable()){
image_spacePage=(ImageView) findViewById(R.id.image_spacepage);
btn_spacepage_save=(Button) findViewById(R.id.btn_spacepage_save);
image_spacePage.setOnTouchListener(new MulitPointTouchListener(image_spacePage));
image_spacePage.setScaleType(ScaleType.CENTER_INSIDE);
//加载成功
String urls="http://epaper.yzdsb.com.cn/201201/04/yz2104_7.jpg";
bitmap=returnBitMap(urls);
if(null!=bitmap){
image_spacePage.setImageBitmap(bitmap);
}
}
}
public Bitmap returnBitMap(String url) {
if(null==url || "".equals(url)){
return null;
}
URL myFileUrl = null;
Bitmap bitmap = null;
try {
myFileUrl = new URL(url);
} catch (MalformedURLException e) {
e.printStackTrace();
}
try {
HttpURLConnection conn = (HttpURLConnection) myFileUrl.openConnection();
conn.setConnectTimeout(2000);
conn.setDoInput(true);
conn.connect();
InputStream is = conn.getInputStream();
bitmap = BitmapFactory.decodeStream(is);
is.close();
} catch (IOException e) {
e.printStackTrace();
}
return bitmap;
}
public class MulitPointTouchListener implements OnTouchListener {
Matrix matrix = new Matrix();
Matrix savedMatrix = new Matrix();
public ImageView image;
static final int NONE = 0;
static final int DRAG = 1;
static final int ZOOM = 2;
int mode = NONE;
PointF start = new PointF();
PointF mid = new PointF();
float oldDist = 1f;
public MulitPointTouchListener(ImageView image) {
super();
this.image = image;
}
@Override
public boolean onTouch(View v, MotionEvent event) {
this.image.setScaleType(ScaleType.MATRIX);
ImageView view = (ImageView) v;
// dumpEvent(event);
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
Log.w("FLAG", "ACTION_DOWN");
matrix.set(view.getImageMatrix());
savedMatrix.set(matrix);
start.set(event.getX(), event.getY());
mode = DRAG;
break;
case MotionEvent.ACTION_POINTER_DOWN:
Log.w("FLAG", "ACTION_POINTER_DOWN");
oldDist = spacing(event);
if (oldDist > 10f) {
savedMatrix.set(matrix);
midPoint(mid, event);
mode = ZOOM;
}
break;
case MotionEvent.ACTION_UP:
Log.w("FLAG", "ACTION_UP");
case MotionEvent.ACTION_POINTER_UP:
Log.w("FLAG", "ACTION_POINTER_UP");
mode = NONE;
break;
case MotionEvent.ACTION_MOVE:
Log.w("FLAG", "ACTION_MOVE");
if (mode == DRAG) {
matrix.set(savedMatrix);
matrix.postTranslate(event.getX() - start.x, event.getY()
- start.y);
} else if (mode == ZOOM) {
float newDist = spacing(event);
if (newDist > 10f) {
matrix.set(savedMatrix);
float scale = newDist / oldDist;
matrix.postScale(scale, scale, mid.x, mid.y);
}
}
break;
}
view.setImageMatrix(matrix);
return true;
}
private float spacing(MotionEvent event) {
float x = event.getX(0) - event.getX(1);
float y = event.getY(0) - event.getY(1);
return FloatMath.sqrt(x * x + y * y);
}
private void midPoint(PointF point, MotionEvent event) {
float x = event.getX(0) + event.getX(1);
float y = event.getY(0) + event.getY(1);
point.set(x / 2, y / 2);
}
}
private void initHead() {
linnerLayout_spacepage = (LinearLayout) findViewById(R.id.linnerLayout_spacepage);
relativeLayout_spacepage=(RelativeLayout) findViewById(R.id.relativeLayout_spacepage);
btn_spacepage_back = (Button) findViewById(R.id.btn_spacepage_back);
btn_spacepage_back.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
finish();
}
});
btn_spacepage_save = (Button) findViewById(R.id.btn_spacepage_save);
}
protected boolean isNetworkAvailable() {
ConnectivityManager connectivity = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
if (connectivity == null) {
Log.i("NetWorkState", "Unavailabel");
return false;
} else {
NetworkInfo[] info = connectivity.getAllNetworkInfo();
if (info != null) {
for (int i = 0; i < info.length; i++) {
if (info[i].getState() == NetworkInfo.State.CONNECTED) {
Log.i("NetWorkState", "Availabel");
return true;
}
}
}
}
return false;
}
@Override
protected void onStop() {
// TODO Auto-generated method stub
if(bitmap!=null){
if(!bitmap.isRecycled()){
bitmap.recycle(); //回收图片所占的内存
bitmap=null;
System.gc(); //提醒系统及时回收
}
}
super.onStop();
}
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
if(bitmap!=null){
if(!bitmap.isRecycled()){
bitmap.recycle(); //回收图片所占的内存
bitmap=null;
System.gc(); //提醒系统及时回收
}
}
}
}
因为是大图片,在onDestroy的时候要recycle掉,这样系统才会定时回收掉,System.gc();是提醒系统回收,虽然java这种垃圾回收机制不用我们自己关心对象的回收,但是这也给android开发人员带来了不好的一面,如果系统回收不及时很可能就造成了内存溢出了。什么时候手机不担心内存使用了就好了。
运行一下看看效果:


猜你喜欢
- 有时候,我们需要将控件的背景颜色设定为透明,比如说label(标签)控件。那么,如何将控件的背景颜色设定为透明?是不是只要将控件的BackC
- 最近一直在使用邮件发送功能,老是遇到问题,后面才找到,原来并不是程序问题引起的,我吧问题整出来, javax.mail.SendFailed
- 1.Open IDEA,choose "New-->Project"2.Choose "Spring I
- synchronized锁的升级(偏向锁、轻量级锁及重量级锁)java同步锁前置知识点1.编码中如果使用锁可以使用synchronized关
- Spring的最基本的能力就是DI,即依赖注入,或控制反转,它可以为Bean注入其依赖的其他Bean。一个Bean依赖其他Bean一般是通过
- 实现多表联合查询还是在david.mybatis.model包下面新建一个Website类,用来持久化数据之用,重写下相应toString(
- 本文接上文“java反射之获取类的信息方法(推荐)”,利用反射(invoke)来获取一个类中的方法来执行。1、定义一个类,包含三个名称相同,
- 一、添加联系人Intent addIntent = new Intent(Intent.ACTION_INSERT,Uri.withAppe
- 目录 * 仓库的配置1、 下载sonatype Nexus来搭建 * 2 安装nexus服务3、创建 * 仓库4、配置 * 信息中央仓库的配置三个仓
- 前段时间在看属性动画,恰巧这个按钮的效果可以用属性动画实现,所以就来实践实践。效果基本出来了,大家可以自己去完善。首先看一下效果图:我们看到
- 本文实例讲述了Android自动朗读TTS用法。分享给大家供大家参考,具体如下:TextToSpeech简称 TTS,是自Android 1
- 验证码逻辑以前在项目中也做过验证码,生成验证码的代码网上有很多,也有一些第三方的jar包也可以生成漂亮的验证码。验证码逻辑很简单,就是在登录
- foreach遍历是C#常见的功能,而本文通过实例形式展现了C#使用yield关键字让自定义集合实现foreach遍历的方法。具体步骤如下:
- 开发设计搞了一个带圆形进度的进度条,在GitHub上逛了一圈,发现没有,自己撸吧。先看界面效果:主要思路是写一个继承ProgressBar的
- 一.延续任务private async static void CallerWithAsync() {  
- 前言面向切面编程,利用 AOP 可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发
- @Value获取yml和properties配置参数Yml:#定时任务配置 application:
- 在上一讲中,我们对Spring的基本使用进行了一个简单的回顾,接下来,我们就来看一下Spring核心功能结构。Spring核心功能结构Spr
- 一、@Value读取application.properties配置文件中的值application.properties配置文件fileN
- 这个功能没什么可介绍的,大家都懂,直接上代码了。。实现功能选择多个文件压缩成ZIP文件和解压ZIP文件开发环境开发工具: Visual St