国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android Scroll實現彈性滑動_列表下拉彈性滑動的示例代碼

2019-10-22 18:16:44
字體:
來源:轉載
供稿:網友

我這一次講使用scroll實現彈性滑動,我不會只有一個例子就說完,因為寫文章的時候我也在學習,我分幾次講完吧。

首先上一段代碼,

private void smoothScrollByScroller(int dy){ mScroller.startScroll(0,dy,0,dy*-1,1000); invalidate();}@Overridepublic void computeScroll() { if (mScroller.computeScrollOffset()) {  scrollTo(mScroller.getCurrX(), mScroller.getCurrY());  postInvalidate(); }}

這段代碼是實現彈性滑動的核心,第一個函數指的是緩慢滑動的意思,但是卻沒有這個滑動的實際功能。

startScroll這函數的五個參數指的是起點x坐標,起點y坐標,x位移量,y位移量,這段滑動的時間。這個函數的內部是不斷計算在滑動時間里x和y坐標應該是什么值,然后因為invalidate會調用computeScroll,這個computeScrollOffset函數是判斷當前滑動是否結束,如果沒有結束通過getCurrX和getCurry獲得startScroll函數計算的值,在使用scrollTo滑動相應的位置,因為startScroll會運算很多次,也就是將滑動時間分成很多段,相應的坐標也都算出來,跟著給scrollTo去實現滑動。

這很像是ValueAmition,將時間分成很多段,然后計算相應的值,同時分很多次去實現。

我貼一個類似QQ消息列表的常見的彈性滑動,這里下拉是沒有刷新的,

public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  setContentView(R.layout.activity_main); }}public final class PullView extends ViewGroup { private int mLastY; private Context mContext; private Scroller mScroller; //子View的個數 private int mChildCount; public PullView(Context context){  this(context,null); } public PullView(Context context, AttributeSet attributeSet){  super(context,attributeSet);  mContext=context;  initView(); } private void initView(){  mScroller=new Scroller(mContext); } @Override public boolean onTouchEvent(MotionEvent event) {  int y=(int)event.getY();  switch (event.getAction()){   //手指按下時,初始化按下位置的X,Y位置值   case MotionEvent.ACTION_DOWN:    mLastY=y;    break;   //計算滑動的偏移量,產生滑動效果   case MotionEvent.ACTION_MOVE:    //手指向下滑動delayY>0,向上滑動delayY<0    int delayY=y-mLastY;    delayY=delayY*-1;    scrollBy(0,delayY);    break;   case MotionEvent.ACTION_UP:    /**     * scrollY是指:View的上邊緣和View內容的上邊緣(其實就是第一個ChildView的上邊緣)的距離     * scrollY=上邊緣-View內容上邊緣,scrollTo/By方法滑動的知識View的內容     * 往下滑動scrollY是負值     */    int scrollY=getScrollY();    smoothScrollByScroller(scrollY);    break;  }  mLastY=y;  return true; } /**  * 執行滑動效果  * 使用scroller實現  * @param dy  */ private void smoothScrollByScroller(int dy){  mScroller.startScroll(0,dy,0,dy*-1,1000);  invalidate(); } @Override public void computeScroll() {  if (mScroller.computeScrollOffset()) {   scrollTo(mScroller.getCurrX(), mScroller.getCurrY());   postInvalidate();  } } /**  * 重新計算子View的高度和寬度  * @param widthMeasureSpec  * @param heightMeasureSpec  */ @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {  super.onMeasure(widthMeasureSpec, heightMeasureSpec);  int measuredWidth;  int measureHeight;  mChildCount = getChildCount();  //測量子View  measureChildren(widthMeasureSpec, heightMeasureSpec);  int widthSpaceSize = MeasureSpec.getSize(widthMeasureSpec);  int widthSpaceMode = MeasureSpec.getMode(widthMeasureSpec);  int heightSpaceSize = MeasureSpec.getSize(heightMeasureSpec);  int heightSpaceMode = MeasureSpec.getMode(heightMeasureSpec);  //獲取橫向的padding值  int paddingLeft=getPaddingLeft();  int paddingRight=getPaddingRight();  final View childView = getChildAt(0);  /**   * 如果子View的數量是0,就讀取LayoutParams中數據   * 否則就對子View進行測量   * 此處主要是針對wrap_content這種模式進行處理,因為默認情況下   * wrap_content等于match_parent   */  if (mChildCount == 0) {   ViewGroup.LayoutParams layoutParams=getLayoutParams();   if(layoutParams!=null){    setMeasuredDimension(layoutParams.width,layoutParams.height);   }else {    setMeasuredDimension(0, 0);   }  } else if (heightSpaceMode == MeasureSpec.AT_MOST && widthSpaceMode == MeasureSpec.AT_MOST) {   measuredWidth = childView.getMeasuredWidth() * mChildCount;   measureHeight = getChildMaxHeight();   //將兩側的padding值加上去   measuredWidth=paddingLeft+measuredWidth+paddingRight;   setMeasuredDimension(measuredWidth, measureHeight);  } else if (heightSpaceMode == MeasureSpec.AT_MOST) {   measureHeight = getChildMaxHeight();   setMeasuredDimension(widthSpaceSize, measureHeight);  } else if (widthSpaceMode == MeasureSpec.AT_MOST) {   measuredWidth = childView.getMeasuredWidth() * mChildCount;   measuredWidth=paddingLeft+measuredWidth+paddingRight;   setMeasuredDimension(measuredWidth, heightSpaceSize);  } } /**  * 獲取子View中最大高度  * @return  */ private int getChildMaxHeight(){  int maxHeight=0;  for (int i = 0; i < mChildCount; i++) {   View childView = getChildAt(i);   if (childView.getVisibility() != View.GONE) {    int height = childView.getMeasuredHeight();    if(height>maxHeight){     maxHeight=height;    }   }  }  return maxHeight; } /**  * 設置子View的布局  * @param changed  * @param l  * @param t  * @param r  * @param b  */ @Override protected void onLayout(boolean changed, int l, int t, int r, int b) {  int childLeft = 0;  for (int i = 0; i < mChildCount; i++) {   View childView = getChildAt(i);   if (childView.getVisibility() != View.GONE) {    int childWidth = childView.getMeasuredWidth();    childView.layout(childLeft, 0, childLeft + childWidth, childView.getMeasuredHeight());    childLeft += childWidth;   }  } }}<android.com.listfragment.PullView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <LinearLayout  android:layout_width="match_parent"  android:layout_height="1500dp"  android:background="#806363"></LinearLayout></android.com.listfragment.PullView>

這里的ViewGroup的繪畫和測量我就不多說,我就說一下它獲取函數,計算坐標的一些事。

它在手指按下時記錄y坐標,在手指移動時,跟著移動子View,在手指抬起時,使用彈性滑動的函數smoothScrollByScroller。

大家會發現為什么一些計算出的坐標要加負號,因為在我們人眼里,我們下拉y坐標的位移量是正的,但是在系統認為這個值是負的,原因我太菜不知道,知道的求大神評論留言告訴。

下一次寫一個隨手指彈性滑動的例子。

以上這篇Android Scroll實現彈性滑動_列表下拉彈性滑動的示例代碼就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持VEVB武林網。


注:相關教程知識閱讀請移步到Android開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 旬邑县| 芮城县| 高平市| 克东县| 枞阳县| 大理市| 大连市| 扎兰屯市| 左云县| 云南省| 西吉县| 磴口县| 永嘉县| 鹤岗市| 榆中县| 灵台县| 张家界市| 冀州市| 隆德县| 来安县| 黄平县| 宁河县| 三门峡市| 饶平县| 万年县| 南华县| 江山市| 孟村| 翼城县| 西峡县| 余庆县| 蓬安县| 石家庄市| 讷河市| 玛曲县| 景洪市| 清涧县| 鹰潭市| 荣昌县| 玛沁县| 高阳县|