Android實(shí)現(xiàn)簡(jiǎn)單的下拉阻尼效應(yīng)示例代碼
OS的下拉上拉都會(huì)出現(xiàn)一個(gè)很玄的動(dòng)態(tài)效果。在Android中,雖然可以實(shí)現(xiàn)類(lèi)似的效果,但有點(diǎn)不同的是,如果調(diào)用overScrollBy來(lái)實(shí)現(xiàn)類(lèi)似的阻尼效應(yīng)的話,最頂部會(huì)出現(xiàn)一片亮的區(qū)域,讓人感覺(jué)不是很爽。所以決定不采用該方法來(lái)實(shí)現(xiàn)而是改用自定義的方式來(lái)實(shí)現(xiàn)。
下面是自定義控件的代碼部分:

public class MyView extends ScrollView {
//記錄下最開(kāi)始點(diǎn)擊的位置
int initY;
//移動(dòng)的位置
int deltaY;
int touchY;
//記錄第一個(gè)item的位置的矩形
Rect topRect;
//用來(lái)存放第一個(gè)可見(jiàn)的item
View inner;
//記錄下ImageView最原始的頂部位置和底部位置
int initTop,initButtom;
int left = 0,top = 0,right = 0,bottom = 0;
ImageView imageView;
State state;
boolean recordFlag;
enum State
{
UP,NORMAL,DOWN
}
boolean isMoving;
boolean shutScroll;
private int current_Bottom;
private int current_Top;
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
state = State.NORMAL;
topRect=new Rect();
recordFlag=false;
}
public void setImageView(ImageView imageView)
{
this.imageView=imageView;
}
//當(dāng)布局加載完成之后調(diào)用該方法
@Override
protected void onFinishInflate() {
super.onFinishInflate();
//返回加載完成后所看到的第一個(gè)item,這里就是看到的第一個(gè)item,通過(guò)對(duì)該對(duì)象的移動(dòng)來(lái)實(shí)現(xiàn)整體的移動(dòng)
inner=getChildAt(0);
Log.i("inner", inner.toString());
}
//onTouchEvent的返回值 返回true的話表示該事件已經(jīng)被處理了,返回false表示改時(shí)間還未被處理
@Override
public boolean onTouchEvent(MotionEvent ev) {
if(inner!=null)
{
commOnTouchEvent(ev);
}
if(shutScroll)
{
return true;
}else
{
return super.onTouchEvent(ev);
}
}
private void commOnTouchEvent(MotionEvent ev) {
switch(ev.getAction())
{
case MotionEvent.ACTION_DOWN:
{
if(recordFlag==false)
{
left=inner.getLeft();
top=inner.getTop();
right=inner.getRight();
bottom=inner.getBottom();
recordFlag=true;
}
//開(kāi)始的時(shí)候接觸點(diǎn)的坐標(biāo)值
initY=(int) ev.getY();
//記錄下ImageView的原始高度
initTop=imageView.getTop();
//記錄下ImageView的原始的底部的像素坐標(biāo)
initButtom=imageView.getBottom();
break;
}
case MotionEvent.ACTION_MOVE:
{
//滑動(dòng)的距離
deltaY=(int) (ev.getY()-initY);
if(deltaY<0)
{
//向上滑動(dòng)
state=State.UP;
isMoving=false;
shutScroll=false;
}
else if(deltaY>=0)
{
//在這里做一下判斷,當(dāng)getScrollY為0時(shí),繼續(xù)下拉就會(huì)進(jìn)入down狀態(tài)。
if(getScrollY()==0)
{
//向下滑動(dòng)
state=State.DOWN;
isMoving=true;
shutScroll=true;
}
}
if(isMoving)
{
if (topRect.isEmpty()) {
// 保存正常的布局位置
topRect.set(left, top,right,bottom);
}
float inner_move_H = deltaY / 5;
inner.layout(topRect.left, (int) (topRect.top + inner_move_H),
topRect.right, (int) (topRect.bottom + inner_move_H));
float image_move_H = deltaY / 10;
current_Top = (int) (initTop + image_move_H);
current_Bottom = (int) (initButtom + image_move_H);
imageView.layout(imageView.getLeft(), current_Top,
imageView.getRight(), current_Bottom);
}
break;
}
case MotionEvent.ACTION_UP:
{
if(needToScroll())
{
animation();
}
if(getScrollY()==0)
{
/*這里為什么要這么寫(xiě)呢?這里有很重要的一個(gè)知識(shí)點(diǎn):
* getScrollY()返回的是手機(jī)屏幕左上角和調(diào)用該方法的view的左上角之間的Y坐標(biāo)只差。
* 在這里,自定義空間的布局方式看看布局文件就會(huì)發(fā)現(xiàn),當(dāng)View滑動(dòng)的時(shí)候,View的狀態(tài)在up,normal;
* down之間切換。在View下來(lái)的過(guò)程中,normal和down有一個(gè)臨界值,這個(gè)臨界值就是該view的
* 左上角是不是和屏幕的左上角相等。相等的話就說(shuō)明再向下拉的話就down狀態(tài)了。*/
state=State.NORMAL;
}
break;
}
}
}
private void animation() {
//背景圖片平移的動(dòng)畫(huà)
TranslateAnimation image_Anim = new TranslateAnimation(0, 0,
Math.abs(initTop - current_Top), 0);
image_Anim.setDuration(200);
imageView.startAnimation(image_Anim);
imageView.layout(imageView.getLeft(), (int) initTop,
imageView.getRight(), (int) initButtom);
// 開(kāi)啟移動(dòng)動(dòng)畫(huà)
TranslateAnimation inner_Anim = new TranslateAnimation(0, 0,
inner.getTop(), topRect.top);
inner_Anim.setDuration(200);
inner.startAnimation(inner_Anim);
inner.layout(topRect.left, topRect.top, topRect.right, topRect.bottom);
//state=State.NORMAL;
topRect.setEmpty();
}
private boolean needToScroll() {
if(state==State.DOWN)
{
return true;
}
return false;
}
}
以上這篇Android實(shí)現(xiàn)簡(jiǎn)單的下拉阻尼效應(yīng)示例代碼就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
- Android下拉刷新完全解析,教你如何一分鐘實(shí)現(xiàn)下拉刷新功能(附源碼)
- Android實(shí)現(xiàn)聯(lián)動(dòng)下拉框 下拉列表spinner的實(shí)例代碼
- Android中Spinner(下拉框)控件的使用詳解
- Android下拉刷新ListView——RTPullListView(demo)
- Android PullToRefreshLayout下拉刷新控件的終結(jié)者
- Android中使用RecyclerView實(shí)現(xiàn)下拉刷新和上拉加載
- Android下拉刷新上拉加載控件(適用于所有View)
- Android官方下拉刷新控件SwipeRefreshLayout使用詳解
- Android屬性動(dòng)畫(huà)實(shí)現(xiàn)布局的下拉展開(kāi)效果
- Android下拉阻尼效果實(shí)現(xiàn)原理及簡(jiǎn)單實(shí)例
相關(guān)文章
Android使用OKHttp庫(kù)實(shí)現(xiàn)視頻文件的上傳到服務(wù)器功能
這篇文章主要介紹了Android使用OKHttp庫(kù)實(shí)現(xiàn)視頻文件的上傳到服務(wù)器功能,需要的朋友可以參考下2018-03-03
android?微信搶紅包工具AccessibilityService實(shí)現(xiàn)詳解
這篇文章主要為大家介紹了android?微信搶紅包工具AccessibilityService實(shí)現(xiàn)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-02-02
Android編程之微信SDK分享功能過(guò)程步驟詳細(xì)分析
這篇文章主要介紹了Android編程之微信SDK分享功能過(guò)程步驟詳細(xì)分析,較為詳細(xì)的分析了Android微信SDK分享功能的原理、步驟與相關(guān)注意事項(xiàng),需要的朋友可以參考下2015-10-10
Android?線程死鎖場(chǎng)景與優(yōu)化解決
線程死鎖是老生常談的問(wèn)題,線程池死鎖本質(zhì)上屬于線程死鎖的一部分,線程池造成的死鎖問(wèn)題往往和業(yè)務(wù)場(chǎng)景相關(guān),本文主要介紹了Android?線程死鎖場(chǎng)景與優(yōu)化,感興趣的可以了解一下2023-12-12
Android程序靜默安裝安裝后重新啟動(dòng)APP的方法
這篇文章主要介紹了Android 靜默安裝,安裝后重新啟動(dòng)APP的方法,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2018-01-01
Android自定義ViewGroup實(shí)現(xiàn)側(cè)滑菜單
這篇文章主要為大家詳細(xì)介紹了Android如何通過(guò)自定義ViewGroup實(shí)現(xiàn)側(cè)滑菜單,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下2023-01-01
android 類(lèi)似微信的搖一搖功能實(shí)現(xiàn)思路及代碼
微信的搖一搖功能的出現(xiàn),讓彼此之間的距離有近了一步,本文也想實(shí)現(xiàn)以下微信的搖一搖功能,感興趣的朋友可以了解下啊,希望本人對(duì)你有所幫助2013-01-01

