![【移動(dòng)應(yīng)用開發(fā)技術(shù)】Android怎么實(shí)現(xiàn)圖片在屏幕內(nèi)縮放和移動(dòng)效果_第1頁](http://file4.renrendoc.com/view/67527aeb3259f2ed0febdb4d4c395e1e/67527aeb3259f2ed0febdb4d4c395e1e1.gif)
![【移動(dòng)應(yīng)用開發(fā)技術(shù)】Android怎么實(shí)現(xiàn)圖片在屏幕內(nèi)縮放和移動(dòng)效果_第2頁](http://file4.renrendoc.com/view/67527aeb3259f2ed0febdb4d4c395e1e/67527aeb3259f2ed0febdb4d4c395e1e2.gif)
![【移動(dòng)應(yīng)用開發(fā)技術(shù)】Android怎么實(shí)現(xiàn)圖片在屏幕內(nèi)縮放和移動(dòng)效果_第3頁](http://file4.renrendoc.com/view/67527aeb3259f2ed0febdb4d4c395e1e/67527aeb3259f2ed0febdb4d4c395e1e3.gif)
![【移動(dòng)應(yīng)用開發(fā)技術(shù)】Android怎么實(shí)現(xiàn)圖片在屏幕內(nèi)縮放和移動(dòng)效果_第4頁](http://file4.renrendoc.com/view/67527aeb3259f2ed0febdb4d4c395e1e/67527aeb3259f2ed0febdb4d4c395e1e4.gif)
![【移動(dòng)應(yīng)用開發(fā)技術(shù)】Android怎么實(shí)現(xiàn)圖片在屏幕內(nèi)縮放和移動(dòng)效果_第5頁](http://file4.renrendoc.com/view/67527aeb3259f2ed0febdb4d4c395e1e/67527aeb3259f2ed0febdb4d4c395e1e5.gif)
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
【移動(dòng)應(yīng)用開發(fā)技術(shù)】Android怎么實(shí)現(xiàn)圖片在屏幕內(nèi)縮放和移動(dòng)效果
在下給大家分享一下Android怎么實(shí)現(xiàn)圖片在屏幕內(nèi)縮放和移動(dòng)效果,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!通常我們遇到的圖片縮放需求,都是圖片基于屏幕自適應(yīng)后,進(jìn)行縮放和移動(dòng),且圖片最小只能是自適應(yīng)的大小。最近遇到一個(gè)需求,要求圖片只能在屏幕內(nèi)縮放和移動(dòng),不能超出屏幕。一、需求在屏幕中加載一張圖片,圖片可以手勢(shì)縮放移動(dòng)。但是圖片最大只能縮放到屏幕大小,也只允許在屏幕內(nèi)移動(dòng)。可以從系統(tǒng)中讀取圖片(通過絕對(duì)路徑),也可以從資源文件中讀取圖片。二、自定義ZoomImageView屏幕內(nèi)手勢(shì)縮放圖片與普通的圖片縮放相比,比較麻煩的是,需要計(jì)算圖片的精確位置。不同于普通縮放的圖片充滿屏幕,屏內(nèi)縮放的圖片只占據(jù)屏幕的一部分,我們需要判斷手指是否點(diǎn)在圖片內(nèi),才能進(jìn)行各種操作。/**
*
判斷手指是否點(diǎn)在圖片內(nèi)(單指)
*/
private
void
isClickInImage(){
if
(translationX
<=
mFirstX
&&
mFirstX
<=
(translationX
+
currentW)
&&
translationY
<=
mFirstY
&&
mFirstY
<=
(translationY
+
currentH)){
isClickInImage
=
true;
}else
{
isClickInImage
=
false;
}
}
/**
*
判斷手指是否點(diǎn)在圖片內(nèi)(雙指)
*
只要有一只手指在圖片內(nèi)就為true
*
@param
event
*/
private
void
isClickInImage(MotionEvent
event){
if
(translationX
<=
event.getX(0)
&&
event.getX(0)
<=
(translationX
+
currentW)
&&
translationY
<=
event.getY(0)
&&
event.getY(0)
<=
(translationY
+
currentH)){
isClickInImage
=
true;
}else
if
(translationX
<=
event.getX(1)
&&
event.getX(1)
<=
(translationX
+
currentW)
&&
translationY
<=
event.getY(1)
&&
event.getY(1)
<=
(translationY
+
currentH)){
isClickInImage
=
true;
}else
{
isClickInImage
=
false;
}
}其他的各種操作,之于縮放,移動(dòng),邊界檢查等,和普通的圖片縮放沒有太多區(qū)別。完整代碼如下:package
com.uni.myapplication;
import
android.content.Context;
import
android.graphics.Bitmap;
import
android.graphics.BitmapFactory;
import
android.graphics.Canvas;
import
android.graphics.Matrix;
import
android.graphics.Paint;
import
android.support.annotation.Nullable;
import
android.util.AttributeSet;
import
android.view.MotionEvent;
import
android.view.View;
import
java.io.File;
/**
*
Created
by
newcboy
on
2018/3/9.
*/
public
class
ZoomImageView
extends
View
{
public
static
final
int
IMAGE_MAX_SIZE
=
1000;//加載圖片允許的最大size,單位kb
private
float
minimal
=
100.0f;
private
float
screenW;//屏幕寬度
private
float
screenH;//屏幕高度
//單指按下的坐標(biāo)
private
float
mFirstX
=
0.0f;
private
float
mFirstY
=
0.0f;
//單指離開的坐標(biāo)
private
float
lastMoveX
=-1f;
private
float
lastMoveY
=-1f;
//兩指的中點(diǎn)坐標(biāo)
private
float
centPointX;
private
float
centPointY;
//圖片的繪制坐標(biāo)
private
float
translationX
=
0.0f;
private
float
translationY
=
0.0f;
//圖片的原始寬高
private
float
primaryW;
private
float
primaryH;
//圖片當(dāng)前寬高
private
float
currentW;
private
float
currentH;
private
float
scale
=
1.0f;
private
float
maxScale,
minScale;
private
Bitmap
bitmap;
private
Matrix
matrix;
private
int
mLocker
=
0;
private
float
fingerDistance
=
0.0f;
private
boolean
isLoaded
=
false;
private
boolean
isClickInImage
=
false;
public
ZoomImageView(Context
context,
@Nullable
AttributeSet
attrs)
{
super(context,
attrs);
}
/**
*
從資源文件中讀取圖片
*
@param
context
*
@param
imageId
*/
public
void
setResourceBitmap(Context
context,
int
imageId){
bitmap
=
BitmapFactory.decodeResource(context.getResources(),
imageId);
isLoaded
=
true;
primaryW
=
bitmap.getWidth();
primaryH
=
bitmap.getHeight();
matrix
=
new
Matrix();
}
/**
*
根據(jù)路徑添加圖片
*
@param
path
*
@param
scale
*/
public
void
setImagePathBitmap(String
path,
float
scale){
this.scale
=
scale;
setImageBitmap(path);
}
private
void
setImageBitmap(String
path){
File
file
=
new
File(path);
if
(file.exists()){
isLoaded
=
true;
bitmap
=
ImageLoadUtils.getImageLoadBitmap(path,
IMAGE_MAX_SIZE);
primaryW
=
bitmap.getWidth();
primaryH
=
bitmap.getHeight();
matrix
=
new
Matrix();
}else
{
isLoaded
=
false;
}
}
@Override
protected
void
onLayout(boolean
changed,
int
left,
int
top,
int
right,
int
bottom)
{
super.onLayout(changed,
left,
top,
right,
bottom);
if
(changed){
screenW
=
getWidth();
screenH
=
getHeight();
translationX
=
(screenW
-
bitmap.getWidth()
*
scale)/
2;
translationY
=
(screenH
-
bitmap.getHeight()
*
scale)
/
2;
setMaxMinScale();
}
}
/**
*
*/
private
void
setMaxMinScale(){
float
xScale,
yScale;
xScale
=
minimal
/
primaryW;
yScale
=
minimal
/
primaryH;
minScale
=
xScale
>
yScale
?
xScale
:
yScale;
xScale
=
primaryW
/
screenW;
yScale
=
primaryH
/
screenH;
if
(xScale
>
1
||
yScale
>
1
)
{
if
(xScale
>
yScale)
{
maxScale
=
1/xScale;
}else
{
maxScale
=
1/yScale;
}
}else
{
if
(xScale
>
yScale)
{
maxScale
=
1/xScale;
}else
{
maxScale
=
1/yScale;
}
}
if
(isScaleError()){
restoreAction();
}
}
@Override
public
boolean
onTouchEvent(MotionEvent
event)
{
if
(!isLoaded){
return
true;
}
switch
(event.getActionMasked()){
case
MotionEvent.ACTION_DOWN:
mFirstX
=
event.getX();
mFirstY
=
event.getY();
isClickInImage();
break;
case
MotionEvent.ACTION_POINTER_DOWN:
fingerDistance
=
getFingerDistance(event);
isClickInImage(event);
break;
case
MotionEvent.ACTION_MOVE:
float
fingerNum
=
event.getPointerCount();
if
(fingerNum
==
1
&&
mLocker
==
0
&&
isClickInImage){
movingAction(event);
}else
if
(fingerNum
==
2
&&
isClickInImage){
zoomAction(event);
}
break;
case
MotionEvent.ACTION_POINTER_UP:
mLocker
=
1;
if
(isScaleError()){
translationX
=
(event.getX(1)
+
event.getX(0))
/
2;
translationY
=
(event.getY(1)
+
event.getY(0))
/
2;
}
break;
case
MotionEvent.ACTION_UP:
lastMoveX
=
-1;
lastMoveY
=
-1;
mLocker
=
0;
if
(isScaleError()){
restoreAction();
}
break;
}
return
true;
}
/**
*
移動(dòng)操作
*
@param
event
*/
private
void
movingAction(MotionEvent
event){
float
moveX
=
event.getX();
float
moveY
=
event.getY();
if
(lastMoveX
==
-1
||
lastMoveY
==
-1)
{
lastMoveX
=
moveX;
lastMoveY
=
moveY;
}
float
moveDistanceX
=
moveX
-
lastMoveX;
float
moveDistanceY
=
moveY
-
lastMoveY;
translationX
=
translationX
+
moveDistanceX;
translationY
=
translationY
+
moveDistanceY;
lastMoveX
=
moveX;
lastMoveY
=
moveY;
invalidate();
}
/**
*
縮放操作
*
@param
event
*/
private
void
zoomAction(MotionEvent
event){
midPoint(event);
float
currentDistance
=
getFingerDistance(event);
if
(Math.abs(currentDistance
-
fingerDistance)
>
1f)
{
float
moveScale
=
currentDistance
/
fingerDistance;
scale
=
scale
*
moveScale;
translationX
=
translationX
*
moveScale
+
centPointX
*
(1-moveScale);
translationY
=
translationY
*
moveScale
+
centPointY
*
(1-moveScale);
fingerDistance
=
currentDistance;
invalidate();
}
}
/**
*
圖片恢復(fù)到指定大小
*/
private
void
restoreAction(){
if
(scale
<
minScale){
scale
=
minScale;
}else
if
(scale
>
maxScale){
scale
=
maxScale;
}
translationX
=
translationX
-
bitmap.getWidth()*scale
/
2;
translationY
=
translationY
-
bitmap.getHeight()*scale
/
2;
invalidate();
}
/**
*
判斷手指是否點(diǎn)在圖片內(nèi)(單指)
*/
private
void
isClickInImage(){
if
(translationX
<=
mFirstX
&&
mFirstX
<=
(translationX
+
currentW)
&&
translationY
<=
mFirstY
&&
mFirstY
<=
(translationY
+
currentH)){
isClickInImage
=
true;
}else
{
isClickInImage
=
false;
}
}
/**
*
判斷手指是否點(diǎn)在圖片內(nèi)(雙指)
*
只要有一只手指在圖片內(nèi)就為true
*
@param
event
*/
private
void
isClickInImage(MotionEvent
event){
if
(translationX
<=
event.getX(0)
&&
event.getX(0)
<=
(translationX
+
currentW)
&&
translationY
<=
event.getY(0)
&&
event.getY(0)
<=
(translationY
+
currentH)){
isClickInImage
=
true;
}else
if
(translationX
<=
event.getX(1)
&&
event.getX(1)
<=
(translationX
+
currentW)
&&
translationY
<=
event.getY(1)
&&
event.getY(1)
<=
(translationY
+
currentH)){
isClickInImage
=
true;
}else
{
isClickInImage
=
false;
}
}
/**
*
獲取兩指間的距離
*
@param
event
*
@return
*/
private
float
getFingerDistance(MotionEvent
event){
float
x
=
event.getX(1)
-
event.getX(0);
float
y
=
event.getY(1)
-
event.getY(0);
return
(float)
Math.sqrt(x
*
x
+
y
*
y);
}
/**
*
判斷圖片大小是否符合要求
*
@return
*/
private
boolean
isScaleError(){
if
(scale
>
maxScale
||
scale
<
minScale){
return
true;
}
return
false;
}
/**
*
獲取兩指間的中點(diǎn)坐標(biāo)
*
@param
event
*/
private
void
midPoint(MotionEvent
event){
centPointX
=
(event.getX(1)
+
event.getX(0))/2;
centPointY
=
(event.getY(1)
+
event.getY(0))/2;
}
@Override
protected
void
onDraw(Canvas
canvas)
{
super.onDraw(canvas);
if
(isLoaded){
imageZoomView(canvas);
}
}
private
void
imageZoomView(Canvas
canvas){
currentW
=
primaryW
*
scale;
currentH
=
primaryH
*
scale;
matrix.reset();
matrix.postScale(scale,
scale);//x軸y軸縮放
peripheryJudge();
matrix.postTranslate(translationX,
translationY);//中點(diǎn)坐標(biāo)移動(dòng)
canvas.drawBitmap(bitmap,
matrix,
null);
}
/**
*
圖片邊界檢查
*
(只在屏幕內(nèi))
*/
private
void
peripheryJudge(){
if
(translationX
<
0){
translationX
=
0;
}
if
(translationY
<
0){
translationY
=
0;
}
if
((translationX
+
currentW)
>
screenW){
translationX
=
screenW
-
currentW;
}
if
((translationY
+
currentH)
>
screenH){
translationY
=
screenH
-
currentH;
}
}
}實(shí)際上,用Bitmap繪制圖片時(shí),可以通過Paint設(shè)置圖片透明度。Paint
paint
=
new
Paint();
paint.setStyle(
Paint.Style.STROKE);
paint.setAlpha(150);在setAlpha()中傳入一個(gè)0~255的整數(shù)。數(shù)字越大,透明度越低。然后在繪制圖片時(shí)canvas.drawBitmap(bitmap,
matrix,
paint);三、ImageLoadUtils圖片加載類這個(gè)類是對(duì)傳入的圖片進(jìn)行壓縮處理的類,在應(yīng)用從系統(tǒng)中讀取圖片時(shí)用到。在寫這個(gè)類時(shí),發(fā)現(xiàn)一些和網(wǎng)上說法不一樣的地方。options.inSampleSize這個(gè)屬性,網(wǎng)上的說法是必須是2的冪次方,但實(shí)際上,我的驗(yàn)證結(jié)果是所有的整數(shù)都可以。這里采用的壓縮方法是,獲取系統(tǒng)剩余內(nèi)存和圖片大小,然后將圖片壓縮到合適的大小。package
com.uni.myapplication;
import
android.app.ActivityManager;
import
android.content.Context;
import
android.graphics.Bitmap;
import
android.graphics.BitmapFactory;
import
android.graphics.BitmapFactory.Options;
import
.Uri;
import
java.io.File;
import
java.io.FileInputStream;
/**
*
圖片加載工具類
*
*
Created
by
newcboy
on
2018/1/25.
*/
public
class
ImageLoadUtils
{
/**
*
原圖加載,根據(jù)傳入的指定圖片大小。
*
@param
imagePath
*
@param
maxSize
*
@return
*/
public
static
Bitmap
getImageLoadBitmap(String
imagePath,
int
maxSize){
int
fileSize
=
1;
Bitmap
bitmap
=
null;
int
simpleSize
=
1;
File
file
=
new
File(imagePath);
if
(file.exists())
{
Uri
imageUri
=
Uri.parse(imagePath);
try
{
fileSize
=
(int)
(getFileSize(file)
/
1024);
}
catch
(Exception
e)
{
e.printStackTrace();
}
Options
options
=
new
Options();
if
(fileSize
>
maxSize){
for
(simpleSize
=
2;
fileSize>=
maxSize;
simpleSize++){
fileSize
=
fileSize
/
simpleSize;
}
}
options.inSampleSize
=
simpleSize;
bitmap
=
BitmapFactory.decodeFile(imageUri.getPath(),
options);
}
return
bitmap;
}
/**
*
獲取指定文件的大小
*
@param
file
*
@return
*
@throws
Exception
*/
public
static
long
getFileSize(File
file)
throws
Exception{
if(file
==
null)
{
return
0;
}
long
size
=
0;
if(file.exists())
{
FileInputStream
mI
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年公路架橋機(jī)項(xiàng)目可行性研究報(bào)告
- 電動(dòng)特種車項(xiàng)目風(fēng)險(xiǎn)評(píng)估報(bào)告
- 二人合伙開店合同協(xié)議書模板
- 原合同管理辦法與相抵觸的地方
- 動(dòng)物無害化處理場(chǎng)建設(shè)項(xiàng)目可行性研究報(bào)告建議書
- 2025年中國植物干浸膏行業(yè)市場(chǎng)發(fā)展前景及發(fā)展趨勢(shì)與投資戰(zhàn)略研究報(bào)告
- KTV裝修施工合同模板
- 企事業(yè)單位裝修施工合同
- 倉儲(chǔ)租賃與運(yùn)輸服務(wù)合同
- 港口用地出讓居間合同
- 電動(dòng)汽車用驅(qū)動(dòng)電機(jī)系統(tǒng)-編制說明
- 江蘇卷2024年高三3月份模擬考試化學(xué)試題含解析
- (正式版)JTT 1497-2024 公路橋梁塔柱施工平臺(tái)及通道安全技術(shù)要求
- 2024年四川省成都市新都區(qū)中考英語一診試卷(含解析)
- 醫(yī)療器械物價(jià)收費(fèi)申請(qǐng)流程
- 招聘專員轉(zhuǎn)正述職報(bào)告
- “一帶一路”背景下的西安市文化旅游外宣翻譯研究-基于生態(tài)翻譯學(xué)理論
- 2024年江蘇省昆山市六校中考聯(lián)考(一模)化學(xué)試題
- 大學(xué)生文學(xué)常識(shí)知識(shí)競(jìng)賽考試題庫500題(含答案)
- 國家電網(wǎng)智能化規(guī)劃總報(bào)告
- 邢臺(tái)市橋西區(qū)2024年事業(yè)單位考試《公共基礎(chǔ)知識(shí)》全真模擬試題含解析
評(píng)論
0/150
提交評(píng)論