版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
【移动应用开发技术】Android中实现Bitmap在自定义View中的放大与拖动
Android中实现Bitmap在自定义View中的放大与拖动
一:基本实现思路基于View类实现自定义View–MyImageView类。在使用View的Activity类中完成OnTouchListener接口,实现对自定义View的触摸事件监听
放大与拖动基于单点触控实现Bitmap对象在View上的拖动、并且检测View的边缘,防止拖动过界。基于两个点触控实现Bitmap对象在View上的放大、并且检测放大倍数。基于Matrix对象实现对Bitmap在View上放大与平移变换
Bitmap对象在View中的更新与显示通过重载onDraw方法,使用canvas实现绘制Bitmap对象、通过view.invalidate()方法实现View的刷新。
MyImageView类的重要方法说明:initParameters()初始化所有需要用到的参数setStartPoint()设置图像平移的开始点坐标setMovePoint()设置图像平移的移动点坐标,然后集合开始点位置,计算它们之间的距离,从而得到Bitmap对象需要平移的两个参数值sx、sy。其中还包括保证图像不会越过View边界的检查代码。savePreviousResult()保存当前的平移数据,下次可以继续在次基础上平移Bitmap对象。zoomIn()根据两个点之间的欧几里德距离,通过初始距离比较,得到放大比例,实现Bitmap在View对象上的放大Matrix.postScale方法与Matrix.postTranslate方法可以不改变Bitmap对象本身实现平移与放大。OnTouchListener支持以下的触摸事件处理:ACTION_DOWN事件,记录平移开始点ACTION_UP事件,结束平移事件处理ACTION_MOVE事件,记录平移点,计算与开始点距离,实现Bitmap平移,在多点触控时候,计算两点之间的距离,实现图像放大ACTION_POINTER_DOWN事件,计算两点之间的距离,作为初始距离,实现图像手势放大时候使用。ACTION_POINTER_UP事件,结束两点触控放大图像处理二:代码实现自定义View的在layout中的使用xml如下:<RelativeLayout
xmlns:android="/apk/res/android"
xmlns:tools="/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity"
>
<com.example.matrixdemo.MyImageView
android:id="@+id/myView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:text="@string/hello_world"
/>
</RelativeLayout>自定义View类的实现代码如下:package
com.example.matrixdemo;
import
android.content.Context;
import
android.graphics.Bitmap;
import
android.graphics.Canvas;
import
android.graphics.Color;
import
android.graphics.Matrix;
import
android.graphics.Paint;
import
android.graphics.Paint.Style;
import
android.graphics.Point;
import
android.graphics.Rect;
import
android.util.AttributeSet;
import
android.view.View;
public
class
MyImageView
extends
View
{
private
Paint
mPaint;
private
Bitmap
bitmap;
private
Matrix
matrix;
//
平移开始点与移动点
private
Point
startPoint;
private
Point
movePoint;
private
float
initDistance;
//
记录当前平移距离
private
int
sx;
private
int
sy;
//
保存平移状态
private
int
oldsx;
private
int
oldsy;
//
scale
rate
private
float
widthRate;
private
float
heightRate;
public
MyImageView(Context
context)
{
super(context);
}
public
MyImageView(Context
context,
AttributeSet
attrs)
{
super(context,
attrs);
}
public
void
setBitmap(Bitmap
bitmap)
{
this.bitmap
=
bitmap;
}
private
void
initParameters()
{
//
初始化画笔
mPaint
=
new
Paint();
mPaint.setColor(Color.BLACK);
matrix
=
new
Matrix();
if(bitmap
!=
null)
{
float
iw
=
bitmap.getWidth();
float
ih
=
bitmap.getHeight();
float
width
=
this.getWidth();
float
height
=
this.getHeight();
//
初始放缩比率
widthRate
=
width
/
iw;
heightRate
=
height
/
ih;
}
sx
=
0;
sy
=
0;
oldsx
=
0;
oldsy
=
0;
}
public
void
setStartPoint(Point
startPoint)
{
this.startPoint
=
startPoint;
}
public
void
setInitDistance(float
initDistance)
{
this.initDistance
=
initDistance;
}
public
void
zoomIn(float
distance)
{
float
rate
=
distance
/
this.initDistance;
float
iw
=
bitmap.getWidth();
float
ih
=
bitmap.getHeight();
float
width
=
this.getWidth();
float
height
=
this.getHeight();
//
get
scale
rate
widthRate
=
(width
/
iw
)
*
rate;
heightRate
=
(height
/
ih)
*
rate;
//
make
it
same
as
view
size
float
iwr
=
(width
/
iw
);
float
ihr
=
(height
/
ih);
if(iwr
>=
widthRate)
{
widthRate
=
(width
/
iw
);
}
if(ihr
>=
heightRate)
{
heightRate
=
(height
/
ih);
}
//
go
to
center
oldsx
=
(int)((width
-
widthRate
*
iw)
/
2);
oldsy
=
(int)((height
-
heightRate
*
ih)
/
2);
}
public
void
setMovePoint(Point
movePoint)
{
this.movePoint
=
movePoint;
sx
=
this.movePoint.x
-
this.startPoint.x;
sy
=
this.movePoint.y
-
this.startPoint.y;
float
iw
=
bitmap.getWidth();
float
ih
=
bitmap.getHeight();
//
检测边缘
int
deltax
=
(int)((widthRate
*
iw)
-
this.getWidth());
int
deltay
=
(int)((heightRate
*
ih)
-
this.getHeight());
if((sx
+
this.oldsx)
>=
0)
{
this.oldsx
=
0;
sx
=
0;
}
else
if((sx
+
this.oldsx)
<=
-deltax)
{
this.oldsx
=
-deltax;
sx
=
0;
}
if((sy
+
this.oldsy)
>=
0)
{
this.oldsy
=
0;
this.sy
=
0;
}
else
if((sy
+
this.oldsy)
<=
-deltay)
{
this.oldsy
=
-deltay;
this.sy
=
0;
}
float
width
=
this.getWidth();
//
初始放缩比率
float
iwr
=
width
/
iw;
if(iwr
==
widthRate)
{
sx
=
0;
sy
=
0;
oldsx
=
0;
oldsy
=
0;
}
}
public
void
savePreviousResult()
{
this.oldsx
=
this.sx
+
this.oldsx;
this.oldsy
=
this.sy
+
this.oldsy;
//
zero
sx
=
0;
sy
=
0;
}
@Override
protected
void
onDraw(Canvas
canvas)
{
if(matrix
==
null)
{
initParameters();
}
if(bitmap
!=
null)
{
matrix.reset();
matrix.postScale(widthRate,
heightRate);
matrix.postTranslate(oldsx+sx,
oldsy
+
sy);
canvas.drawBitmap(bitmap,
matrix,
mPaint);
}
else
{
//
fill
rect
Rect
rect
=
new
Rect(0,
0,
getWidth(),
getHeight());
mPaint.setAntiAlias(true);
mPaint.setColor(Color.BLACK);
mPaint.setStyle(Style.FILL_AND_STROKE);
canvas.drawRect(rect,
mPaint);
}
}
}MainActivity的代码如下:package
com.example.matrixdemo;
import
android.app.Activity;
import
android.graphics.Bitmap;
import
android.graphics.BitmapFactory;
import
android.graphics.Point;
import
android.os.Bundle;
import
android.util.Log;
import
android.view.Menu;
import
android.view.MotionEvent;
import
android.view.View;
import
android.view.View.OnTouchListener;
public
class
MainActivity
extends
Activity
implements
OnTouchListener
{
public
static
final
int
SCALE_MODE
=
4;
public
static
final
int
TRANSLATION_MODE
=
2;
public
static
final
int
NULL_MODE
=
1;
private
MyImageView
myView;
private
int
mode;
@Override
protected
void
onCreate(Bundle
savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startMyImageView();
}
private
void
startMyImageView()
{
myView
=
(MyImageView)
this.findViewById(R.id.myView);
Bitmap
bitmap
=
BitmapFactory.decodeResource(this.getResources(),
R.drawable.flower_001);
myView.setBitmap(bitmap);
myView.setOnTouchListener(this);
myView.invalidate();
}
@Override
public
boolean
onCreateOptionsMenu(Menu
menu)
{
getMenuInflater().inflate(R.menu.main,
menu);
return
true;
}
@Override
public
boolean
onTouch(View
view,
MotionEvent
event)
{
Log.i("touch
event","touch
x
=
"
+
event.getX());
switch
(MotionEvent.ACTION_MASK
&
event.getAction())
{
case
MotionEvent.ACTION_DOWN:
mode
=
TRANSLATION_MODE;
myView.setStartPoint(new
Point((int)event.getX(),
(int)event.getY()));
break;
case
MotionEvent.ACTION_POINTER_UP:
case
MotionEvent.ACTION_OUTSIDE:
case
MotionEvent.ACTION_UP:
mode
=
NULL_MODE;
myV
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 皮革漂白制剂市场发展前景分析及供需格局研究预测报告
- 手动螺旋切菜器产品供应链分析
- 多媒体图书馆服务行业营销策略方案
- 发行预付费电话卡行业相关项目经营管理报告
- 修脚时穿的泡沫拖鞋产业链招商引资的调研报告
- 扩音器用变送器产业链招商引资的调研报告
- 3.2遵守规则 同步课件 -2024-2025学年统编版道德与法治八年级上册
- 自动驾驶送货机器人项目营销计划书
- 广告咨询行业相关项目经营管理报告
- 创建设计和维护网站行业经营分析报告
- 专项施工方案审查意见汇总
- 小学硬笔书法教学设计-020初级第二十次课:竖弯钩 课后服务
- DB51∕T 2447-2018 高海拔地区光伏发电站设计规范
- 云南文山铝业有限公司歪山头铝土矿采矿工程 环评报告
- Unit3FascinatingParks单元分析讲义高中英语人教版选择性
- 网络营销四大系统
- 患者突发昏迷应急预案演练脚本-
- 2023新时代解决台湾问题的总体方略PPT
- 妊娠合并心脏病的护理
- 二年级语文上册《坐井观天》优秀说课课件
- 食品工艺-食品加工-第八章-果品制酒与制醋课件
评论
0/150
提交评论