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

首頁 > 系統 > Android > 正文

Android自定義控件ScrollView實現上下滑動功能

2019-10-21 21:45:46
字體:
來源:轉載
供稿:網友

本文實例為大家分享了Android ScrollView實現上下滑動功能的具體代碼,供大家參考,具體內容如下

package com.example.zhuang;import android.content.Context;import android.util.AttributeSet;import android.util.DisplayMetrics;import android.view.MotionEvent;import android.view.View;import android.view.ViewGroup;import android.view.WindowManager;import android.widget.Scroller;public class MyScrollView extends ViewGroup {  private int mScreeHeight;//屏幕高度  private Scroller mScroller;  private int mLastY;  private int mStart;  private int mEnd;  private Context context;  public MyScrollView(Context context) {    super(context);    initView(context);  }  public MyScrollView(Context context, AttributeSet attrs) {    super(context, attrs);    initView(context);  }  public MyScrollView(Context context, AttributeSet attrs,            int defStyleAttr) {    super(context, attrs, defStyleAttr);    initView(context);  }  private void initView(Context context) {    WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);    //DisplayMetrics 類提供了一種關于顯示的通用信息,如顯示大小,分辨率和字體。    DisplayMetrics dm = new DisplayMetrics();    wm.getDefaultDisplay().getMetrics(dm);    mScreeHeight = dm.heightPixels;//高度(像素)    mScroller = new Scroller(context);  }  //繼承ViewGroup必須要實現的方法  @Override  protected void onLayout(boolean changed, int l, int t, int r, int b) {    int childCount = getChildCount();//獲取子view的個數    //設置ViewGroup的高度    MarginLayoutParams mlp = (MarginLayoutParams) getLayoutParams();    mlp.height = mScreeHeight * childCount;    setLayoutParams(mlp);    for (int i = 0; i < childCount; i++) {      View child = getChildAt(i);      if (child.getVisibility() != View.GONE) {        //參數為相對父容器的左上右下位置,第三個參數必須為r        child.layout(0, i * mScreeHeight, r, (i + 1) * mScreeHeight);      }    }  }  @Override  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {    super.onMeasure(widthMeasureSpec, heightMeasureSpec);    int count = getChildCount();    for (int i = 0; i < count; i++) {      View child = getChildAt(i);      measureChild(child, widthMeasureSpec, heightMeasureSpec);    }  }  @Override  public boolean onTouchEvent(MotionEvent event) {    int y = (int) event.getY();//相對于view的y值,getRawY()是相對屏幕    switch (event.getAction()) {      case MotionEvent.ACTION_DOWN:        mLastY = y;//上一次的y值        mStart = getScrollY();//記錄觸摸起點        break;      case MotionEvent.ACTION_MOVE:        if(!mScroller.isFinished()) {          mScroller.abortAnimation();//放棄移到最終位置        }        int dy = mLastY - y;//偏移距離        //如果滑動距離小于0或大于屏幕高度,不偏移        if(getScrollY()<0){          dy = 0;        }        if(getScrollY() > getHeight()-mScreeHeight){          dy = 0;        }        scrollBy(0,dy);//移動        mLastY = y;        break;      case MotionEvent.ACTION_UP:        int dScrollY = checkAlignment();//整體移動的距離        if(dScrollY > 0){          if(dScrollY < mScreeHeight / 3){            mScroller.startScroll(0,getScrollY(),0,-dScrollY);          }else{            mScroller.startScroll(0,getScrollY(),0,mScreeHeight-dScrollY);          }        }else{          if(-dScrollY < mScreeHeight / 3){            mScroller.startScroll(0,getScrollY(),0,-dScrollY);          }else{            mScroller.startScroll(0,getScrollY(),0,-mScreeHeight-dScrollY);          }        }        break;    }    postInvalidate();    return true;  }  private int checkAlignment(){     mEnd = getScrollY();//記錄觸摸終點    boolean isUp = ((mEnd - mStart)>0) ? true : false;    int lastPrev = mEnd % mScreeHeight;    int lastNext = mScreeHeight - lastPrev;    if(isUp){      return lastPrev;//向上    }else      return -lastNext;  }  @Override  public void computeScroll() {    super.computeScroll();    if(mScroller.computeScrollOffset()){//返回true,表示還未移動完      scrollTo(0,mScroller.getCurrY());//移到當前位置      postInvalidate();      //invalidate()是用來刷新View的,必須是在UI線程中進行工作。      //postInvalidate()可以在非UI線程調用    }  }}

知識點:

1、獲取屏幕參數代碼:

DisplayMetrics metric = new DisplayMetrics(); //API 17之后使用,獲取的像素寬高包含虛擬鍵所占空間,在API 17之前通過反射獲取 context.getWindowManager().getDefaultDisplay().getRealMetrics(metric); //獲取的像素寬高不包含虛擬鍵所占空間 //context.getWindowManager().getDefaultDisplay().getMetrics(metric); int width = metric.widthPixels; // 寬度(像素) int height = metric.heightPixels; // 高度(像素) float density = metric.density; // dp縮放因子 int densityDpi = metric.densityDpi; // 廣義密度 float xdpi = metric.xdpi;//x軸方向的真實密度 float ydpi = metric.ydpi;//y軸方向的真實密度 

屏幕高度值包含了狀態欄的像素,非沉浸模式下真實的Activity高度需要減去狀態欄的高度。獲取狀態欄高度代碼:

private int getStatusBarHeight() {   Rect rect = new Rect();   getWindow().getDecorView().getWindowVisibleDisplayFrame(rect);   return rect.top; } 

屏幕參數Width和Height的值和屏幕方向有關,另外4個值和屏幕方向無關。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VEVB武林網。


注:相關教程知識閱讀請移步到Android開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 大理市| 巫溪县| 辽宁省| 广河县| 兴和县| 九江县| 保康县| 确山县| 个旧市| 安龙县| 辰溪县| 依安县| 邯郸县| 双城市| 伊川县| 汉川市| 东平县| 全州县| 宁德市| 宣恩县| 永吉县| 台江县| 金沙县| 岳阳市| 巴里| 达孜县| 岗巴县| 申扎县| 屏南县| 玉林市| 抚松县| 东丰县| 张家口市| 恭城| 交口县| 太原市| 德兴市| 合作市| 民勤县| 南通市| 惠州市|