




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
【移動(dòng)應(yīng)用開發(fā)技術(shù)】Android怎么實(shí)現(xiàn)微信側(cè)滑關(guān)閉頁面效果
這篇文章主要介紹了Android怎么實(shí)現(xiàn)微信側(cè)滑關(guān)閉頁面效果,具有一定借鑒價(jià)值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓在下帶著大家一起了解一下。原理在每個(gè)Activity里面都有一個(gè)底層的View,也就是所謂的rootView,當(dāng)我們加載一個(gè)xml布局時(shí),系統(tǒng)就會自動(dòng)給你生成這個(gè)rootView,由于它是一個(gè)View,那么也就意味著你可以通過一定的代碼隨意移動(dòng)這個(gè)根布局。如下代碼所示,只要簡單的幾行代碼便能實(shí)現(xiàn)布局的移動(dòng)。public
class
SlideActivity
extends
AppCompatActivity
{
View
mRootView;
private
GestureDetector
mDetector;
private
int
mWindowWidth;
@Override
protected
void
onCreate(Bundle
savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_demo);
mRootView
=
getWindow().getDecorView();
mRootView.setBackgroundColor(Color.BLUE);
mDetector
=
new
GestureDetector(this,
new
GestureListener());
mWindowWidth
=
getWindow().getWindowManager().getDefaultDisplay().getWidth();
}
@Override
public
boolean
onTouchEvent(MotionEvent
event)
{
return
mDetector.onTouchEvent(event);
}
/**
*
手勢監(jiān)聽
*/
private
class
GestureListener
extends
GestureDetector.SimpleOnGestureListener
{
@Override
public
boolean
onScroll(MotionEvent
e1,
MotionEvent
e2,
float
distanceX,
float
distanceY)
{
if
(e1
!=
null)
{
handlerCurrentActivityScroll(e2);
}
return
super.onScroll(e1,
e2,
distanceX,
distanceY);
}
/**
*
處理當(dāng)前頁面滑動(dòng)
*/
private
void
handlerCurrentActivityScroll(MotionEvent
e2)
{
mRootView.setTranslationX(e2.getX());
if
(e2.getX()
>
mWindowWidth
-
20)
{
finish();
}
}
}
}這是我們的效果Activity聯(lián)動(dòng)這差距還是很大的,最明顯的地方是,我們移動(dòng)的時(shí)候,上一層Activity竟然沒有跟著聯(lián)動(dòng)。解決這個(gè)問題的方法也簡單,如圖所示,每當(dāng)啟動(dòng)一個(gè)Activity時(shí),系統(tǒng)都會把Activity放到一個(gè)棧里面,由于棧的工作原理可知,APP里面的Activity是一層覆蓋一層的,就如上圖所示。為此,每當(dāng)啟動(dòng)一個(gè)Activity時(shí),就可以把當(dāng)前的Actiivty存儲到一個(gè)List里面,這樣,我們就可以在當(dāng)前的Activity里面取出上一個(gè)Activity進(jìn)行操作。因此,在進(jìn)入一個(gè)新的Activity的時(shí)候,在其onCreate方法里面把當(dāng)前的Activity加載到列表里,當(dāng)退出時(shí),在finish的重載方法里面,將當(dāng)前Activity從列表里面移除。注意?。?!在滑動(dòng)的時(shí)候必須需要考慮到Activity里面有可能會有類似于ListView一類的滑動(dòng)控件,因此,我們必須對事件進(jìn)行分發(fā)控制。代碼如下/**
*
Created
by
yuyu
on
2015/10/29.
*/
public
class
TestActivity
extends
AppCompatActivity
{
View
mRootView;
private
GestureDetector
mGestureDetector;
private
static
List<TestActivity>
mActivitys
=
new
ArrayList<>();
/**
*
移動(dòng)距離
*/
private
float
mWindowWidth;
private
TestActivity
mBeforeActivity;
/**
*
上一個(gè)Activity偏移量
*/
private
float
mOffsetX;
/**
*
上一個(gè)頁面移出的位置
*/
private
float
mOutsideWidth;
@Override
protected
void
onCreate(Bundle
savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_demo);
/**
*
把當(dāng)前Activity加到列表里面
*/
mActivitys.add(this);
initScrollBack();
}
/**
*
初始化左滑退出功能
*/
private
void
initScrollBack()
{
mWindowWidth
=
getWindowManager().getDefaultDisplay().getWidth();
mOutsideWidth
=
-mWindowWidth
/
4;
mOffsetX
=
mOutsideWidth;
mGestureDetector
=
new
GestureDetector(this,
new
GestureListener());
mRootView
=
getWindow().getDecorView();
mRootView.setBackgroundColor(Color.BLUE);
}
/**
*
控制分發(fā)事件,在這里控制能能觸發(fā)拖動(dòng)的范圍
*/
@Override
public
boolean
dispatchTouchEvent(@NonNull
MotionEvent
ev)
{
if
(ev.getX()
<
mWindowWidth
/
10)
{
if
(mActivitys.size()
>
1)
{
mBeforeActivity
=
mActivitys.get(mActivitys.size()
-
2);
beforeActivityTranslationX(mOutsideWidth);
}
return
onTouchEvent(ev);
}
return
super.dispatchTouchEvent(ev);
}
@Override
public
void
finish()
{
mActivitys.remove(this);
if
(mOffsetX
<
0.0001
||
mOffsetX
>
0.0001)
{
beforeActivityTranslationX(0);
}
super.finish();
}
public
void
onClick(View
view)
{
Intent
intent
=
new
Intent(this,
Activity5.class);
startActivity(intent);
}
public
View
getRootView()
{
return
mRootView;
}
/**
*
控制上一個(gè)Activity移動(dòng)
*/
private
void
beforeActivityTranslationX(float
translationX)
{
if
(mBeforeActivity
!=
null)
{
mBeforeActivity.getRootView().setTranslationX(translationX);
}
}
@Override
public
boolean
onTouchEvent(MotionEvent
event)
{
return
mGestureDetector.onTouchEvent(event);
}
/**
*
手勢監(jiān)聽
*/
private
class
GestureListener
extends
GestureDetector.SimpleOnGestureListener
{
@Override
public
boolean
onScroll(MotionEvent
e1,
MotionEvent
e2,
float
distanceX,
float
distanceY)
{
if
(e1
!=
null)
{
handlerCurrentActivityScroll(e2);
handleBeforeActivityScroll(e2,
distanceX);
}
return
super.onScroll(e1,
e2,
distanceX,
distanceY);
}
/**
*
處理當(dāng)前頁面滑動(dòng)
*/
private
void
handlerCurrentActivityScroll(MotionEvent
e2)
{
mRootView.setTranslationX(e2.getX());
if
(e2.getX()
>
mWindowWidth
-
20)
{
finish();
}
}
/**
*
處理上一個(gè)頁面滑動(dòng)
*/
private
void
handleBeforeActivityScroll(MotionEvent
e2,
float
distanceX)
{
if
(mBeforeActivity
!=
null)
{
mOffsetX
=
distanceX
<
0
?
mOffsetX
+
Math.abs(distanceX)
/
4
:
mOffsetX
-
Math.abs(distanceX)
/
4;
if
(mOffsetX
>
0.0001)
{
mOffsetX
=
0f;
}
mBeforeActivity.getRootView().setTranslationX(mOffsetX);
}
}
}
}這是聯(lián)動(dòng)后的效果圖現(xiàn)在算是有點(diǎn)效果了,但是和微信的差距還是很大,接下來我們便需要開始處理自動(dòng)滑動(dòng)了自動(dòng)滑動(dòng)這個(gè)就不需要多說了,這個(gè)主要就是利用屬性動(dòng)畫進(jìn)行移動(dòng)以下是完整的代碼public
class
SlideActivity
extends
AppCompatActivity
{
private
static
final
String
TAG
=
"SlideActivity";
private
static
List<SlideActivity>
mActivitys
=
new
ArrayList<>();
/**
*
手勢監(jiān)聽
*/
private
GestureDetector
mGestureDetector;
private
View
mRootView;
private
boolean
isScroll
=
false;
/**
*
移動(dòng)距離
*/
private
float
mWindowWidth;
private
SlideActivity
mBeforeActivity;
/**
*
上一個(gè)Activity偏移量
*/
private
float
mOffsetX;
/**
*
上一個(gè)頁面移出的位置
*/
private
float
mOutsideWidth;
private
boolean
canScrollBack
=
true;
private
boolean
canScroll
=
false;
@Override
protected
void
onCreate(Bundle
savedInstanceState)
{
getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
getWindow().setEnterTransition(new
Slide(Gravity.RIGHT));
super.onCreate(savedInstanceState);
/**
*
把當(dāng)前Activity加到列表里面
*/
mActivitys.add(this);
initScrollBack();
}
@Override
public
void
startActivity(Intent
intent)
{
startActivity(intent,
ActivityOptions.makeSceneTransitionAnimation(this).toBundle());
}
/**
*
初始化左滑退出功能
*/
private
void
initScrollBack()
{
mWindowWidth
=
getWindowManager().getDefaultDisplay().getWidth();
mOutsideWidth
=
-mWindowWidth
/
4;
mOffsetX
=
mOutsideWidth;
mGestureDetector
=
new
GestureDetector(this,
new
GestureListener());
mRootView
=
getWindow().getDecorView();
}
/**
*
控制上一個(gè)Activity移動(dòng)
*/
private
void
beforeActivityTranslationX(float
translationX)
{
if
(mBeforeActivity
!=
null)
{
mBeforeActivity.getRootView().setTranslationX(translationX);
}
}
/**
*
設(shè)置是否能滑動(dòng)
*
*
@param
canScrollBack
true
可以滑動(dòng)
*/
protected
void
setCanScrollBack(boolean
canScrollBack)
{
this.canScrollBack
=
canScrollBack;
}
public
View
getRootView()
{
return
mRootView;
}
@Override
public
void
finish()
{
mActivitys.remove(this);
if
(mOffsetX
<
0.0001
||
mOffsetX
>
0.0001)
{
beforeActivityTranslationX(0);
}
super.finish();
}
/**
*
控制分發(fā)事件
*/
@Override
public
boolean
dispatchTouchEvent(@NonNull
MotionEvent
ev)
{
if
(canScrollBack
&&
ev.getX()
<
mWindowWidth
/
10)
{
if
(mActivitys.size()
>
1)
{
mBeforeActivity
=
mActivitys.get(mActivitys.size()
-
2);
beforeActivityTranslationX(mOutsideWidth);
}
canScroll
=
true;
return
onTouchEvent(ev);
}
return
super.dispatchTouchEvent(ev);
}
@Override
public
boolean
onTouchEvent(MotionEvent
event)
{
if
(canScrollBack
&&
canScroll)
{
if
(event.getAction()
==
MotionEvent.ACTION_UP
&&
isScroll)
{
isScroll
=
false;
canScroll
=
false;
//退出當(dāng)前Activity
if
(event.getX()
>
mWindowWidth
/
2)
{
if
(mBeforeActivity
!=
null)
{
ObjectAnimator.ofFloat(mBeforeActivity.getRootView(),
"translationX",
mOffsetX,
0).setDuration(500).start();
}
ObjectAnimator
moveIn
=
ObjectAnimator.ofFloat(mRootView,
"translationX",
event.getX(),
mWindowWidth);
moveIn.addListener(new
AnimatorListenerAdapter()
{
@Override
public
void
onAnimationEnd(Animator
animation)
{
super.onAnimationEnd(animation);
finish();
}
});
moveIn.setDuration(500).start();
//反彈回來
}
else
if
(event.getX()
<
mWindowWidth
/
2)
{
ObjectAnimator.ofFloat(mRootView,
"translationX",
event.getX(),
0).setDuration(500).start();
if
(mBeforeActivity
!=
null)
{
ObjectAnimator.ofFloat(mBeforeActivity.getRootView(),
"translationX",
mOffsetX,
mOutsideWidth).setDuration(500).start();
}
mOffsetX
=
mOutsideWidth;
}
}
else
{
mGestureDetector.onTouchEvent(event);
}
}
return
true;
}
/**
*
手勢監(jiān)聽
*/
private
class
GestureListener
extends
溫馨提示
- 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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 鋁合金材料施工方案
- (三模)榆林市2025屆高三第三次模擬檢測生物試卷(含答案詳解)
- 數(shù)控加工工藝與編程技術(shù)基礎(chǔ) 教案 模塊一 任務(wù)4 數(shù)控加工機(jī)床夾具基礎(chǔ)
- 結(jié)合農(nóng)業(yè)植保技術(shù)的現(xiàn)代農(nóng)業(yè)病蟲害防治思路與具體辦法探討
- 醫(yī)療機(jī)構(gòu)水污染物排放的管理制度與組織架構(gòu)
- 石油化工靜電接地系統(tǒng)的組成與功能
- 綠色發(fā)展與可持續(xù)城鎮(zhèn)化策略
- 積極穩(wěn)妥推進(jìn)碳達(dá)峰碳中和的策略及實(shí)施路徑
- 采購鐵皮保溫施工方案
- 2018年數(shù)學(xué)(北師大版選修2-2)練習(xí)第3章22最大值最小值問題活頁作業(yè)14
- 2024年第二學(xué)期春學(xué)期人教版初中道德與法治八年級下冊教學(xué)計(jì)劃附教學(xué)進(jìn)度表版
- 湖北省(面試)公務(wù)員考試試題及解答參考(2024年)
- 《營銷素養(yǎng)訓(xùn)練-團(tuán)隊(duì)與個(gè)人管理實(shí)務(wù)》
- 2024年人教版小學(xué)六年級數(shù)學(xué)下冊試卷及答案精校新版
- 院內(nèi)突發(fā)心跳呼吸驟停、昏迷、跌倒事件應(yīng)急預(yù)案及程序
- 日記本產(chǎn)品市場需求分析報(bào)告
- 護(hù)理美學(xué)-第七章 護(hù)士的語言美
- 2024年永州市冷水灘區(qū)數(shù)學(xué)五年級第二學(xué)期期末達(dá)標(biāo)檢測試題含解析
- 《小型水庫雨水情測報(bào)和大壩安全監(jiān)測設(shè)施建設(shè)與運(yùn)行管護(hù)技術(shù)指南》
- 2024湖南株洲市天元區(qū)面向社會招聘社區(qū)專職工作者人員筆試歷年典型考題及考點(diǎn)剖析附答案帶詳解
- 八年級英語上冊第一學(xué)期期末綜合測試卷(人教陜西版)
評論
0/150
提交評論