【移動(dòng)應(yīng)用開發(fā)技術(shù)】Android怎么實(shí)現(xiàn)圖片在屏幕內(nèi)縮放和移動(dòng)效果_第1頁
【移動(dòng)應(yīng)用開發(fā)技術(shù)】Android怎么實(shí)現(xiàn)圖片在屏幕內(nèi)縮放和移動(dòng)效果_第2頁
【移動(dòng)應(yīng)用開發(fā)技術(shù)】Android怎么實(shí)現(xiàn)圖片在屏幕內(nèi)縮放和移動(dòng)效果_第3頁
【移動(dòng)應(yīng)用開發(fā)技術(shù)】Android怎么實(shí)現(xiàn)圖片在屏幕內(nèi)縮放和移動(dòng)效果_第4頁
【移動(dòng)應(yīng)用開發(fā)技術(shù)】Android怎么實(shí)現(xiàn)圖片在屏幕內(nèi)縮放和移動(dòng)效果_第5頁
已閱讀5頁,還剩15頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(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ì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論