




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
【移動(dòng)應(yīng)用開(kāi)發(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)用技巧、基本知識(shí)點(diǎn)總結(jié)和需要注意事項(xiàng),具有一定的參考價(jià)值,需要的朋友可以參考一下。Android是一種基于Linux內(nèi)核的自由及開(kāi)放源代碼的操作系統(tǒng),主要使用于移動(dòng)設(shè)備,如智能手機(jī)和平板電腦,由美國(guó)Google公司和開(kāi)放手機(jī)聯(lián)盟領(lǐng)導(dǎo)及開(kāi)發(fā)。使用方式此空間繼承與FrameLayout子空間直接添加如同framelayout相同如要如圖效果唯一要求子空間必須位于父控件中心且寬高等大小為了方便擴(kuò)展而做如有其他需求可自行更改(注所有子控件最好添加上背景由于繪制機(jī)制和動(dòng)畫(huà)原因沒(méi)有背景會(huì)有部分重貼)內(nèi)部子view可為任意ViewGroup。弱使用過(guò)程中遇見(jiàn)任何BUG歡迎提出。三實(shí)現(xiàn)原理
實(shí)現(xiàn)原理由Camera與Maxtrix組合修改View的繪制而得具體Camera與Maxtrix的變換過(guò)程請(qǐng)自行搜索。在此不班門弄斧。具體修改有@Override
protected
void
dispatchDraw(Canvas
canvas)
{
int
indexleft
=
getWidth()
/
2;//中間顯示視圖
左邊的位置
int
postTranslateX
=
rotationX
*
childWith
/
2
/
rotation;//設(shè)定邊移動(dòng)
距離
//定點(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ì)在此不多做描述實(shí)現(xiàn)方式上有哪些不同嗯下次有空再細(xì)說(shuō)(由于需要大量圖文描述3D的變換過(guò)程才講的清楚,有些間隔的時(shí)間也稍長(zhǎng)只記得大概的思路過(guò)程)。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選中切換以及滑動(dòng)內(nèi)容和分發(fā)修改等。demo下載有分的相關(guān)小伙伴就下載提供一些沒(méi)有的就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
*
//┏┓┏┓
*
//┏┛┻━━━┛┻┓
*
//┃┃
*
//┃━┃
*
//┃┳┛┗┳┃
*
//┃┃
*
//┃┻┃
*
//┃┃
*
//┗━┓┏━┛
*
//┃┃
神獸保佑
*
//┃┃
代碼無(wú)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)光源
正真的直角
反而看起來(lái)
并不是直角
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è)定邊移動(dòng)
距離
//定點(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. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 財(cái)務(wù)風(fēng)險(xiǎn)識(shí)別與評(píng)估的方法論
- 質(zhì)量文化的建設(shè)與傳播策略
- 跨國(guó)企業(yè)知識(shí)產(chǎn)權(quán)培訓(xùn)與教育體系構(gòu)建
- 金融科技公司財(cái)報(bào)特點(diǎn)與趨勢(shì)分析
- 超聲波在材料科學(xué)的研究應(yīng)用
- 江蘇專用2024高考物理二輪復(fù)習(xí)實(shí)驗(yàn)題增分練一
- 部編版四年級(jí)下冊(cè)道德與法治教案(全冊(cè))
- 超聲科技術(shù)革新與患者溝通技巧培訓(xùn)
- 跨國(guó)公司在海外的專利權(quán)維護(hù)策略
- 人事的試用期工作總結(jié)報(bào)告范文(8篇)
- 【正版授權(quán)】 IEC 63310:2025 EN Functional performance criteria for AAL robots used in connected home environment
- 最終版附件1:“跨學(xué)科主題學(xué)習(xí)”教學(xué)設(shè)計(jì)(2025年版)
- (2024)云南省公務(wù)員考試《行測(cè)》真題及答案解析
- 2022年“正確認(rèn)識(shí)新疆四史”《民族團(tuán)結(jié)鑄牢中華民族共同體意識(shí)》全文解讀
- 靜脈治療護(hù)理技術(shù)操作標(biāo)準(zhǔn)解讀
- (精心整理)事故后果模擬分析
- 國(guó)家開(kāi)放大學(xué)電大《健康教育與健康促進(jìn)(本)》期末題庫(kù)及答案
- MBR系統(tǒng)運(yùn)行技術(shù)手冊(cè)
- 中國(guó)河流湖泊
- 學(xué)校中層干部民主測(cè)評(píng)表(一)
- 中國(guó)農(nóng)業(yè)銀行資金證明模板
評(píng)論
0/150
提交評(píng)論