【移動應(yīng)用開發(fā)技術(shù)】如何在Android項(xiàng)目中實(shí)現(xiàn)一個(gè)3D立體旋轉(zhuǎn)效果_第1頁
【移動應(yīng)用開發(fā)技術(shù)】如何在Android項(xiàng)目中實(shí)現(xiàn)一個(gè)3D立體旋轉(zhuǎn)效果_第2頁
【移動應(yīng)用開發(fā)技術(shù)】如何在Android項(xiàng)目中實(shí)現(xiàn)一個(gè)3D立體旋轉(zhuǎn)效果_第3頁
【移動應(yīng)用開發(fā)技術(shù)】如何在Android項(xiàng)目中實(shí)現(xiàn)一個(gè)3D立體旋轉(zhuǎn)效果_第4頁
【移動應(yīng)用開發(fā)技術(shù)】如何在Android項(xiàng)目中實(shí)現(xiàn)一個(gè)3D立體旋轉(zhuǎn)效果_第5頁
已閱讀5頁,還剩9頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

【移動應(yīng)用開發(fā)技術(shù)】如何在Android項(xiàng)目中實(shí)現(xiàn)一個(gè)3D立體旋轉(zhuǎn)效果

本文章向大家介紹如何在Android項(xiàng)目中實(shí)現(xiàn)一個(gè)3D立體旋轉(zhuǎn)效果,主要包括如何在Android項(xiàng)目中實(shí)現(xiàn)一個(gè)3D立體旋轉(zhuǎn)效果的使用實(shí)例、應(yīng)用技巧、基本知識點(diǎn)總結(jié)和需要注意事項(xiàng),具有一定的參考價(jià)值,需要的朋友可以參考一下。Android是一種基于Linux內(nèi)核的自由及開放源代碼的操作系統(tǒng),主要使用于移動設(shè)備,如智能手機(jī)和平板電腦,由美國Google公司和開放手機(jī)聯(lián)盟領(lǐng)導(dǎo)及開發(fā)。使用方式此空間繼承與FrameLayout子空間直接添加如同framelayout相同如要如圖效果唯一要求子空間必須位于父控件中心且寬高等大小為了方便擴(kuò)展而做如有其他需求可自行更改(注所有子控件最好添加上背景由于繪制機(jī)制和動畫原因沒有背景會有部分重貼)內(nèi)部子view可為任意ViewGroup。弱使用過程中遇見任何BUG歡迎提出。三實(shí)現(xiàn)原理

實(shí)現(xiàn)原理由Camera與Maxtrix組合修改View的繪制而得具體Camera與Maxtrix的變換過程請自行搜索。在此不班門弄斧。具體修改有@Override

protected

void

dispatchDraw(Canvas

canvas)

{

int

indexleft

=

getWidth()

/

2;//中間顯示視圖

左邊的位置

int

postTranslateX

=

rotationX

*

childWith

/

2

/

rotation;//設(shè)定邊移動

距離

//定點(diǎn)

又稱頂點(diǎn)

//

chilDrawforCamera(canvas,

postTranslateX,

indexleft,

3);//預(yù)繪制

縣繪制

防止遮擋

for

(int

i

=

0;

i

<

4;

i++)

chilDrawforCamera(canvas,

postTranslateX,

indexleft,

i);

if

(!isTouch)

handler.sendEmptyMessageDelayed(1,

100);

}重新編寫dispathDraw()從而達(dá)到不必要去修改子view的內(nèi)容而添加擴(kuò)展性具體變換包括private

void

chilDrawforCamera(Canvas

canvas,

int

postTranslateX,

int

indexleft,

int

i)

{

canvas.save();

mCamera.save();

mMaxtrix.reset();

mCamera.translate(postTranslateX,

0,

0);

mCamera.rotateY(rotationX);

mCamera.translate(postTranslateX,

0,

0);

if

(postTranslateX

==

0)

{

if

(isright)

setCameraChange(childWith,

rotation,

i);

else

setCameraChange(-childWith,

-rotation,

i);

}

else

if

(postTranslateX

>

0)

{

setCameraChange(childWith,

rotation,

i);

}

else

if

(postTranslateX

<

0)

{

setCameraChange(-childWith,

-rotation,

i);

}

mCamera.getMatrix(mMaxtrix);

mCamera.restore();

mMaxtrix.preTranslate(-indexleft,

-getHeight()

/

2);//指定在

屏幕上

運(yùn)行的棱

是哪一條

mMaxtrix.postTranslate(indexleft,

getHeight()

/

2);//運(yùn)行路徑

canvas.concat(mMaxtrix);

//繪制

View

childAt

=

getChildAt((swithView(i)

+

2

*

getChildCount())

%

getChildCount());

drawChild(canvas,

childAt,

0);

canvas.restore();

}指定需要繪制的子view先后順序以及哪些子viewprivate

int

swithView(int

i)

{

int

k

=

0;

switch

(i)

{

case

0:

if

(isright)

k

=

index

-

2;

else

k

=

index

+

2;

break;

case

1:

if

(isright)

k

=

index

+

1;

else

k

=

index

-

1;

break;

case

2:

if

(isright)

k

=

index

-

1;

else

k

=

index

+

1;

break;

case

3:

k

=

index;

break;

}

return

k;具體的網(wǎng)上其他類似效果到底有什么不同于優(yōu)勢在此不多做描述實(shí)現(xiàn)方式上有哪些不同嗯下次有空再細(xì)說(由于需要大量圖文描述3D的變換過程才講的清楚,有些間隔的時(shí)間也稍長只記得大概的思路過程)。private

void

setCameraChange(int

translate,

int

roat,

int

i)

{

switch

(i)

{

case

0:

//預(yù)繪制

的VIEW

mCamera.translate(-translate

/

2,

0,

0);

mCamera.rotateY(-roat);

mCamera.translate(-translate

/

2,

0,

0);

mCamera.translate(-translate

/

2,

0,

0);

mCamera.rotateY(-roat);

mCamera.translate(-translate

/

2,

0,

0);

break;

//當(dāng)前位置兩側(cè)的View

case

1:

mCamera.translate(translate

/

2,

0,

0);

mCamera.rotateY(roat);

mCamera.translate(translate

/

2,

0,

0);

break;

case

2:

mCamera.translate(-translate

/

2,

0,

0);

mCamera.rotateY(-roat);

mCamera.translate(-translate

/

2,

0,

0);

break;

//最后繪制

當(dāng)前顯示位置

防止

被遮擋

case

3:

mCamera.rotateY(0);

break;

}

}其他剩下的就是index選中切換以及滑動內(nèi)容和分發(fā)修改等。demo下載有分的相關(guān)小伙伴就下載提供一些沒有的就github下載吧。整個(gè)類復(fù)制也可以package

com.burning.foethedog;

import

android.content.Context;

import

android.graphics.Camera;

import

android.graphics.Canvas;

import

android.graphics.Matrix;

import

android.os.Handler;

import

android.os.Message;

import

android.util.AttributeSet;

import

android.view.MotionEvent;

import

android.view.View;

import

android.widget.FrameLayout;

/**

*

Created

by

burning

on

2017/5/2.

*

When

I

wrote

this,

only

God

and

I

understood

what

I

was

doing

*

Now,

God

only

knows

*

//┏┓┏┓

*

//┏┛┻━━━┛┻┓

*

//┃┃

*

//┃━┃

*

//┃┳┛┗┳┃

*

//┃┃

*

//┃┻┃

*

//┃┃

*

//┗━┓┏━┛

*

//┃┃

神獸保佑

*

//┃┃

代碼無BUG!

*

//┃┗━━━┓

*

//┃┣┓

*

//┃┏┛

*

//┗┓┓┏━┳┓┏┛

*

//

┃┫┫┃┫┫

*

//

┗┻┛┗┻┛

*/

public

class

Rota3DSwithView

extends

FrameLayout

{

Camera

mCamera;

Matrix

mMaxtrix;

public

Rota3DSwithView(Context

context)

{

super(context);

initRoat3D();

}

private

void

initRoat3D()

{

mCamera

=

new

Camera();

mMaxtrix

=

new

Matrix();

setWillNotDraw(false);

}

public

Rota3DSwithView(Context

context,

AttributeSet

attrs)

{

super(context,

attrs);

initRoat3D();

}

public

Rota3DSwithView(Context

context,

AttributeSet

attrs,

int

defStyleAttr)

{

super(context,

attrs,

defStyleAttr);

initRoat3D();

}

public

Rota3DSwithView(Context

context,

AttributeSet

attrs,

int

defStyleAttr,

int

defStyleRes)

{

super(context,

attrs,

defStyleAttr,

defStyleRes);

initRoat3D();

}

int

childWith;

@Override

protected

void

onLayout(boolean

changed,

int

left,

int

top,

int

right,

int

bottom)

{

childWith

=

getChildAt(0).getMeasuredWidth();

super.onLayout(changed,

left,

top,

right,

bottom);

}

//攝像機(jī)

為點(diǎn)光源

正真的直角

反而看起來

并不是直角

static

int

rotation

=

60;//

設(shè)定外角

int

rotationX

=

00;

int

index

=

0;

@Override

protected

void

dispatchDraw(Canvas

canvas)

{

int

indexleft

=

getWidth()

/

2;//中間顯示視圖

左邊的位置

int

postTranslateX

=

rotationX

*

childWith

/

2

/

rotation;//設(shè)定邊移動

距離

//定點(diǎn)

又稱頂點(diǎn)

//

chilDrawforCamera(canvas,

postTranslateX,

indexleft,

3);//預(yù)繪制

縣繪制

防止遮擋

for

(int

i

=

0;

i

<

4;

i++)

chilDrawforCamera(canvas,

postTranslateX,

indexleft,

i);

if

(!isTouch)

handler.sendEmptyMessageDelayed(1,

100);

}

private

void

setCameraChange(int

translate,

int

roat,

int

i)

{

switch

(i)

{

case

0:

//預(yù)繪制

的VIEW

mCamera.translate(-translate

/

2,

0,

0);

mCamera.rotateY(-roat);

mCamera.translate(-translate

/

2,

0,

0);

mCamera.translate(-translate

/

2,

0,

0);

mCamera.rotateY(-roat);

mCamera.translate(-translate

/

2,

0,

0);

break;

//當(dāng)前位置兩側(cè)的View

case

1:

mCamera.translate(translate

/

2,

0,

0);

mCamera.rotateY(roat);

mCamera.translate(translate

/

2,

0,

0);

break;

case

2:

mCamera.translate(-translate

/

2,

0,

0);

mCamera.rotateY(-roat);

mCamera.translate(-translate

/

2,

0,

0);

break;

//最后繪制

當(dāng)前顯示位置

防止

被遮擋

case

3:

mCamera.rotateY(0);

break;

}

}

boolean

isright

=

false;

Handler

handler

=

new

Handler()

{

@Override

public

void

handleMessage(Message

msg)

{

switch

(msg.what)

{

case

1:

if

(isTouch)

return;

if

(isright)

rotationX++;

else

rotationX--;

if

(Math.abs(rotationX)

==

rotation)

{

rotationX

=

0;

index

=

index

%

getChildCount();

if

(isright)

index--;

else

index++;

}

Rota3DSwithView.this.invalidate();

break;

}

}

};

private

void

chilDrawforCamera(Canvas

canvas,

int

postTranslateX,

int

indexleft,

int

i)

{

canvas.save();

mCamera.save();

mMaxtrix.reset();

mCamera.translate(postTranslateX,

0,

0);

mCamera.rotateY(rotationX);

mCamera.translate(postTranslateX,

0,

0);

if

(postTranslateX

==

0)

{

if

(isright)

setCameraChange(childWith,

rotation,

i);

else

setCameraChange(-childWith,

-rotation,

i);

}

else

if

(postTranslateX

>

0)

{

setCameraChange(childWith,

rotation,

i);

}

else

if

(postTranslateX

<

0)

{

setCameraChange(-childWith,

-rotation,

i);

}

mCamera.getMatrix(mMaxtrix);

mCamera.restore();

mMaxtrix.preTranslate(-indexleft,

-getHeight()

/

2);//指定在

屏幕上

運(yùn)行的棱

是哪一條

mMaxtrix.postTranslate(indexleft,

getHeight()

/

2);//運(yùn)行路徑

canvas.concat(mMaxtrix);

//繪制

View

childAt

=

getChildAt((swithView(i)

+

2

*

getChildCount())

%

getChildCount());

drawChild(canvas,

childAt,

0);

canvas.restore();

}

private

int

swithView(int

i)

{

int

k

=

0;

switch

(i)

{

case

0:

if

(isright)

k

=

index

-

2;

else

k

=

index

+

2;

break;

case

1:

if

(isright)

k

=

index

+

1;

else

k

=

index

-

1;

break;

case

2:

if

(isright)

k

=

index

-

1;

else

k

=

index

+

1;

break;

case

3:

k

=

index;

break;

}

return

k;

}

boolean

isTouch

=

false;

int

downX

=

0;

public

boolean

dispatchTouchEvent(MotionEvent

event)

{

//這里我們就

就只分發(fā)給當(dāng)前index子View

isTouch

=

event.getAction()

==

MotionEvent.ACTION_MOVE;

if

(!onInterceptTouchEvent(event))

{

index

=

index

%

getChildCount();

return

getChildAt((index

+

getChildCount())

%

getChildCount()).dispatchTouchEvent(event);

}

return

super.dispatchTouchEvent(event);

}

int

thisRx

=

0;

int

thisindex;

@Override

public

boolean

onInterceptTouchEvent(MotionEvent

event)

{

switch

(event.getAction())

{

case

MotionEvent.ACTION_DOWN:

downX

=

(int)

event.getX();

thisindex

=

index;

thisRx

=

rotationX;

break;

case

MotionEvent.ACTION_MOVE:

if

(Math.abs(event.getX()

-

downX)

>

50)

{

return

true

/*onTouchEvent(event)*/;

}

break;

}

return

false;

}

@Override

public

boolean

onT

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論