日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > Android >内容正文

Android

android computescroll_Android Scroller与computeScroll方法的调用关系

發(fā)布時(shí)間:2025/3/21 Android 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 android computescroll_Android Scroller与computeScroll方法的调用关系 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

Android ViewGroup中的Scroller與computeScroll的有什么關(guān)系?

答:沒有直接的關(guān)系

知道了答案,是不是意味著下文就沒必要看了,如果說對ViewGroup自定義控件不感興趣,可以不用看了。

1.Scroller到底是什么?

答:Scroller只是個(gè)計(jì)算器,提供插值計(jì)算,讓滾動(dòng)過程具有動(dòng)畫屬性,但它并不是UI,也不是輔助UI滑動(dòng),反而是單純地為滑動(dòng)提供計(jì)算。

無論從構(gòu)造方法還是其他方法,以及Scroller的屬性可知,其并不會(huì)持有View,輔助ViewGroup滑動(dòng)

2.Scroller只是提供計(jì)算,那誰來調(diào)用computeScroll使得ViewGroup滑動(dòng)

答:computeScroll也不是來讓ViewGroup滑動(dòng)的,真正讓ViewGroup滑動(dòng)的是scrollTo,scrollBy。computeScroll的作用是計(jì)算ViewGroup如何滑動(dòng)。而computeScroll是通過draw來調(diào)用的。

3.computeScroll和Scroller都是計(jì)算,兩者有啥關(guān)系?

答:文章開始已作答,沒有直接的關(guān)系。computeScroll和Scroller要是飛得拉關(guān)系的話,那就是computeScroll可以參考Scroller計(jì)算結(jié)果來影響scrollTo,scrollBy,從而使得滑動(dòng)發(fā)生改變。也就是Scroller不會(huì)調(diào)用computeScroll,反而是computeScroll調(diào)用Scroller。

4.滑動(dòng)時(shí)連續(xù)的,如何讓Scroller的計(jì)算也是連續(xù)的?

這個(gè)就問到了什么時(shí)候調(diào)用computeScroll了,如上所說computeScroll調(diào)用Scroller,只要computeScroll調(diào)用連續(xù),Scroller也會(huì)連續(xù),實(shí)質(zhì)上computeScroll的連續(xù)性又invalidate方法控制,scrollTo,scrollBy都會(huì)調(diào)用invalidate,而invalidate回去觸發(fā)draw,從而computeScroll被連續(xù)調(diào)用,綜上,Scroller也會(huì)被連續(xù)調(diào)用,除非invalidate停止調(diào)用。

5.computeScroll如何和Scroller的調(diào)用過程保持一致。

computeScroll參考Scroller影響scrollTo,scrollBy,實(shí)質(zhì)上,為了不重復(fù)影響scrollTo,scrollBy,那么Scroller必須終止計(jì)算currX,currY。要知道計(jì)算有沒有終止,需要通過mScroller.computeScrollOffset()

6.如上問題應(yīng)該說的很清楚了吧,如果不明白,請留言。

7.通過一個(gè)SlidePanel的例子,我們來深刻的了解一下

注意:在移動(dòng)平臺(tái)中,要明確知道“滑動(dòng)”與“滾動(dòng)”的不同,具體來說,滑動(dòng)和滾動(dòng)的方向總是相反的。

public?class?SlidingPanel?extends?RelativeLayout?{

private?Context?context;

private?FrameLayout?leftMenu;

private?FrameLayout?middleMenu;

private?FrameLayout?rightMenu;

private?FrameLayout?middleMask;

private?Scroller?mScroller;

public??final?int?LEFT_ID?=?0xaabbcc;

public??final?int?MIDEELE_ID?=?0xaaccbb;

public??final?int?RIGHT_ID?=?0xccbbaa;

private?boolean?isSlideCompete;

private?boolean?isHorizontalScroll;

private?Point?point?=?new?Point();

private?static?final?int?SLIDE_SLOP?=?20;

public?SlidingPanel(Context?context)?{

super(context);

initView(context);

}

public?SlidingPanel(Context?context,?AttributeSet?attrs)?{

super(context,?attrs);

initView(context);

}

private?void?initView(Context?context)?{

this.context?=?context;

mScroller?=?new?Scroller(context,?new?DecelerateInterpolator());

leftMenu?=?new?FrameLayout(context);

middleMenu?=?new?FrameLayout(context);

rightMenu?=?new?FrameLayout(context);

middleMask?=?new?FrameLayout(context);

leftMenu.setBackgroundColor(Color.RED);

middleMenu.setBackgroundColor(Color.GREEN);

rightMenu.setBackgroundColor(Color.RED);

middleMask.setBackgroundColor(0x88000000);

addView(leftMenu);

addView(middleMenu);

addView(rightMenu);

addView(middleMask);

middleMask.setAlpha(0);

}

public?float?onMiddleMask(){

return?middleMask.getAlpha();

}

@Override

public?void?scrollTo(int?x,?int?y)?{

super.scrollTo(x,?y);

onMiddleMask();

//?Log.e("getScrollX","getScrollX="+getScrollX());//可以是負(fù)值

int?curX?=?Math.abs(getScrollX());

float?scale?=?curX/(float)leftMenu.getMeasuredWidth();

middleMask.setAlpha(scale);

}

@Override

protected?void?onMeasure(int?widthMeasureSpec,?int?heightMeasureSpec)?{

super.onMeasure(widthMeasureSpec,?heightMeasureSpec);

middleMenu.measure(widthMeasureSpec,?heightMeasureSpec);

middleMask.measure(widthMeasureSpec,?heightMeasureSpec);

int?realWidth?=?MeasureSpec.getSize(widthMeasureSpec);

int?tempWidthMeasure?=?MeasureSpec.makeMeasureSpec(

(int)?(realWidth?*?0.8f),?MeasureSpec.EXACTLY);

leftMenu.measure(tempWidthMeasure,?heightMeasureSpec);

rightMenu.measure(tempWidthMeasure,?heightMeasureSpec);

}

@Override

protected?void?onLayout(boolean?changed,?int?l,?int?t,?int?r,?int?b)?{

super.onLayout(changed,?l,?t,?r,?b);

middleMenu.layout(l,?t,?r,?b);

middleMask.layout(l,?t,?r,?b);

leftMenu.layout(l?-?leftMenu.getMeasuredWidth(),?t,?r,?b);

rightMenu.layout(

l?+?middleMenu.getMeasuredWidth(),

t,

l?+?middleMenu.getMeasuredWidth()

+?rightMenu.getMeasuredWidth(),?b);

}

@Override

public?boolean?dispatchTouchEvent(MotionEvent?ev)?{

if?(!isSlideCompete)?{

handleSlideEvent(ev);

return?true;

}

if?(isHorizontalScroll)?{

switch?(ev.getActionMasked())?{

case?MotionEvent.ACTION_MOVE:

int?curScrollX?=?getScrollX();

int?dis_x?=?(int)?(ev.getX()?-?point.x);

//滑動(dòng)方向和滾動(dòng)滾動(dòng)條方向相反,因此dis_x必須取負(fù)值

int?expectX?=?-dis_x?+?curScrollX;

if(dis_x>0)

{

Log.d("I","Right-Slide,Left-Scroll");//向右滑動(dòng),向左滾動(dòng)

}else{

Log.d("I","Left-Slide,Right-Scroll");

}

Log.e("I","ScrollX="+curScrollX+"?,?X="+ev.getX()+"?,?dis_x="+dis_x);

//規(guī)定expectX的變化范圍

int????finalX?=?Math.max(-leftMenu.getMeasuredWidth(),Math.min(expectX,?rightMenu.getMeasuredWidth()));

scrollTo(finalX,?0);

point.x?=?(int)?ev.getX();//更新,保證滑動(dòng)平滑

break;

case?MotionEvent.ACTION_UP:

case?MotionEvent.ACTION_CANCEL:

curScrollX?=?getScrollX();

if?(Math.abs(curScrollX)?>?leftMenu.getMeasuredWidth()?>>?1)?{

if?(curScrollX?

mScroller.startScroll(curScrollX,?0,

-leftMenu.getMeasuredWidth()?-?curScrollX,?0,

200);

}?else?{

mScroller.startScroll(curScrollX,?0,

leftMenu.getMeasuredWidth()?-?curScrollX,?0,

200);

}

}?else?{

mScroller.startScroll(curScrollX,?0,?-curScrollX,?0,?200);

}

invalidate();

isHorizontalScroll?=?false;

isSlideCompete?=?false;

break;

}

}?else?{

switch?(ev.getActionMasked())?{

case?MotionEvent.ACTION_UP:

isHorizontalScroll?=?false;

isSlideCompete?=?false;

break;

default:

break;

}

}

return?super.dispatchTouchEvent(ev);

}

/**

*?通過invalidate操縱,此方法通過draw方法調(diào)用

*/

@Override

public?void?computeScroll()?{

super.computeScroll();

if?(!mScroller.computeScrollOffset())?{

//計(jì)算currX,currY,并檢測是否已完成“滾動(dòng)”

return;

}

int?tempX?=?mScroller.getCurrX();

scrollTo(tempX,?0);?//會(huì)重復(fù)調(diào)用invalidate

}

private?void?handleSlideEvent(MotionEvent?ev)?{

switch?(ev.getAction()&MotionEvent.ACTION_MASK)?{

case?MotionEvent.ACTION_DOWN:

point.x?=?(int)?ev.getX();

point.y?=?(int)?ev.getY();

super.dispatchTouchEvent(ev);

break;

case?MotionEvent.ACTION_MOVE:

int?dX?=?Math.abs((int)?ev.getX()?-?point.x);

int?dY?=?Math.abs((int)?ev.getY()?-?point.y);

if?(dX?>=?SLIDE_SLOP?&&?dX?>?dY)?{?//?左右滑動(dòng)

isHorizontalScroll?=?true;

isSlideCompete?=?true;

point.x?=?(int)?ev.getX();

point.y?=?(int)?ev.getY();

}?else?if?(dY?>=?SLIDE_SLOP?&&?dY?>?dX)?{?//?上下滑動(dòng)

isHorizontalScroll?=?false;

isSlideCompete?=?true;

point.x?=?(int)?ev.getX();

point.y?=?(int)?ev.getY();

}

break;

case?MotionEvent.ACTION_UP:

case?MotionEvent.ACTION_OUTSIDE:

case?MotionEvent.ACTION_CANCEL:

super.dispatchTouchEvent(ev);

isHorizontalScroll?=?false;

isSlideCompete?=?false;

break;

}

}

}

《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀

總結(jié)

以上是生活随笔為你收集整理的android computescroll_Android Scroller与computeScroll方法的调用关系的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。