亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

android開發(fā)通過(guò)Scroller實(shí)現(xiàn)過(guò)渡滑動(dòng)效果操作示例

 更新時(shí)間:2020年01月22日 11:59:20   作者:初心不負(fù)  
這篇文章主要介紹了android開發(fā)通過(guò)Scroller實(shí)現(xiàn)過(guò)渡滑動(dòng)效果,結(jié)合實(shí)例形式分析了Android Scroller類實(shí)現(xiàn)過(guò)渡滑動(dòng)效果的基本原理與實(shí)現(xiàn)技巧,需要的朋友可以參考下

本文實(shí)例講述了android開發(fā)通過(guò)Scroller實(shí)現(xiàn)過(guò)渡滑動(dòng)效果。分享給大家供大家參考,具體如下:

主要介紹一下Scroller這個(gè)類,它可以實(shí)現(xiàn)過(guò)渡滑動(dòng)的效果,使滑動(dòng)看起來(lái)不是那么生硬,當(dāng)然它用大量的重繪來(lái)實(shí)現(xiàn),invalidate();通過(guò)源碼看:

看構(gòu)造方法

 /**
   * Create a Scroller with the default duration and interpolator.
   */
  public Scroller(Context context) {
    this(context, null);
  }
  /**
   * Create a Scroller with the specified interpolator. If the interpolator is
   * null, the default (viscous) interpolator will be used. "Flywheel" behavior will
   * be in effect for apps targeting Honeycomb or newer.
   */
  public Scroller(Context context, Interpolator interpolator) {
    this(context, interpolator,
        context.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.HONEYCOMB);
  }
  /**
   * Create a Scroller with the specified interpolator. If the interpolator is
   * null, the default (viscous) interpolator will be used. Specify whether or
   * not to support progressive "flywheel" behavior in flinging.
   */
  public Scroller(Context context, Interpolator interpolator, boolean flywheel) {
    mFinished = true;
    if (interpolator == null) {
      mInterpolator = new ViscousFluidInterpolator();
    } else {
      mInterpolator = interpolator;
    }
    mPpi = context.getResources().getDisplayMetrics().density * 160.0f;
    mDeceleration = computeDeceleration(ViewConfiguration.getScrollFriction());
    mFlywheel = flywheel;
    mPhysicalCoeff = computeDeceleration(0.84f); // look and feel tuning
  }

我們用默認(rèn)的就行,傳個(gè)context就行了,其他的什么差值器,先不管了

然后調(diào)用startScroll,傳遞我們歧視滑動(dòng)位置和滑動(dòng)的偏移量,還有可選的默認(rèn)持續(xù)時(shí)間,默認(rèn)為250毫秒
這個(gè)方法是用來(lái)賦值的,接下來(lái)會(huì)調(diào)用invalidate()進(jìn)行重新繪制,然后就會(huì)onDraw(),這時(shí)候會(huì)調(diào)用
computeScroll()這個(gè)方法,我們重寫這個(gè)方法,computeScrollOffset()是判斷動(dòng)畫有沒(méi)有結(jié)束的一個(gè)方法,沒(méi)結(jié)束的時(shí)候,我們根據(jù)滑動(dòng)的偏移位置進(jìn)行移動(dòng)也就是scrollto到scroller的當(dāng)前位置,再次調(diào)用invalidate(),由此無(wú)數(shù)的重回進(jìn)行拼接形成了平滑的滑動(dòng)

/**
   * Call this when you want to know the new location. If it returns true,
   * the animation is not yet finished.
   */
  public boolean computeScrollOffset() {
    if (mFinished) {
      return false;
    }
    int timePassed = (int)(AnimationUtils.currentAnimationTimeMillis() - mStartTime);
    if (timePassed < mDuration) {
      switch (mMode) {
      case SCROLL_MODE:
        final float x = mInterpolator.getInterpolation(timePassed * mDurationReciprocal);
        mCurrX = mStartX + Math.round(x * mDeltaX);
        mCurrY = mStartY + Math.round(x * mDeltaY);
        break;
      case FLING_MODE:
        final float t = (float) timePassed / mDuration;
        final int index = (int) (NB_SAMPLES * t);
        float distanceCoef = 1.f;
        float velocityCoef = 0.f;
        if (index < NB_SAMPLES) {
          final float t_inf = (float) index / NB_SAMPLES;
          final float t_sup = (float) (index + 1) / NB_SAMPLES;
          final float d_inf = SPLINE_POSITION[index];
          final float d_sup = SPLINE_POSITION[index + 1];
          velocityCoef = (d_sup - d_inf) / (t_sup - t_inf);
          distanceCoef = d_inf + (t - t_inf) * velocityCoef;
        }
        mCurrVelocity = velocityCoef * mDistance / mDuration * 1000.0f;
        mCurrX = mStartX + Math.round(distanceCoef * (mFinalX - mStartX));
        // Pin to mMinX <= mCurrX <= mMaxX
        mCurrX = Math.min(mCurrX, mMaxX);
        mCurrX = Math.max(mCurrX, mMinX);
        mCurrY = mStartY + Math.round(distanceCoef * (mFinalY - mStartY));
        // Pin to mMinY <= mCurrY <= mMaxY
        mCurrY = Math.min(mCurrY, mMaxY);
        mCurrY = Math.max(mCurrY, mMinY);
        if (mCurrX == mFinalX && mCurrY == mFinalY) {
          mFinished = true;
        }
        break;
      }
    }
    else {
      mCurrX = mFinalX;
      mCurrY = mFinalY;
      mFinished = true;
    }
    return true;
  }

 public void startScroll(int startX, int startY, int dx, int dy) {
    startScroll(startX, startY, dx, dy, DEFAULT_DURATION);
  }
 public void startScroll(int startX, int startY, int dx, int dy, int duration) {
    mMode = SCROLL_MODE;
    mFinished = false;
    mDuration = duration;
    mStartTime = AnimationUtils.currentAnimationTimeMillis();
    mStartX = startX;
    mStartY = startY;
    mFinalX = startX + dx;
    mFinalY = startY + dy;
    mDeltaX = dx;
    mDeltaY = dy;
    mDurationReciprocal = 1.0f / (float) mDuration;
  }

public class MoveFreeView extends View{
  private int movedX;
  private int movedY;
  private Scroller mScroller;
  public MoveFreeView(Context context) {
    super(context);
  }
  public MoveFreeView(Context context, @Nullable AttributeSet attrs) {
    super(context, attrs);
    mScroller = new Scroller(context);
  }
  public MoveFreeView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
  }
  @Override
  public boolean onTouchEvent(MotionEvent event) {
    //獲取觸摸點(diǎn)到邊界坐標(biāo)
    int x = (int) event.getX();
    int y = (int) event.getY();
    switch (event.getAction()){
      case MotionEvent.ACTION_DOWN:
        movedX = x;
        movedY = y;
        break;
      case MotionEvent.ACTION_MOVE:
        int offsetX = x-movedX;
        int offsetY = y-movedY;
        layout(getLeft()+offsetX,getTop()+offsetY,getRight()+offsetX,getBottom()+offsetY);
        break;
    }
    return super.onTouchEvent(event);
  }
  //供外界調(diào)用通過(guò)傳遞x,y的的滑動(dòng)距離
  public void smoothScrollTo(int destinyX,int destinyY){
    //向右側(cè),下方滑動(dòng),請(qǐng)傳遞負(fù)值
    int scrollX = getScrollX();
    int scrollY = getScrollY();
    int delta = destinyX - scrollX;
    int deltaY = destinyY - scrollY;
    mScroller.startScroll(scrollX,scrollY,delta,deltaY,5000);
    invalidate();
  }
  @Override
  public void computeScroll() {
    super.computeScroll();
    //true則表示滑動(dòng)未結(jié)束
    if (mScroller.computeScrollOffset()){
      ((View) getParent()).scrollTo(mScroller.getCurrX(),mScroller.getCurrY());
      invalidate();
    }
  }
}

private MoveFreeView button;
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    button = (MoveFreeView) findViewById(R.id.custon);
    button.smoothScrollTo(-400,-300);
    //    button.startAnimation(AnimationUtils.loadAnimation(this,R.anim.translate));
//    ObjectAnimator animtor1 = ObjectAnimator.ofFloat(button, "translationX", 0, 300);
//    ObjectAnimator animtor2 = ObjectAnimator.ofFloat(button, "translationY", 0, 300);
//    ObjectAnimator animator3 = ObjectAnimator.ofFloat(button,"rotationX",0.0f,360f);
//    ObjectAnimator animator4 = ObjectAnimator.ofFloat(button,"scaleX",1.5f,0.5f);
//    AnimatorSet set= new AnimatorSet();
//    set.setDuration(5000);
//    set.playTogether(animtor1,animtor2,animator3,animator4);
//    set.addListener(new Animator.AnimatorListener() {
//      @Override
//      public void onAnimationStart(Animator animator) {
//
//      }
//
//      @Override
//      public void onAnimationEnd(Animator animator) {
//        //動(dòng)畫結(jié)束時(shí)做一些事情
//      }
//
//      @Override
//      public void onAnimationCancel(Animator animator) {
//
//      }
//
//      @Override
//      public void onAnimationRepeat(Animator animator) {
//
//      }
//    });
//    set.start();
  }
}

更多關(guān)于Android相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Android開發(fā)入門與進(jìn)階教程》、《Android調(diào)試技巧與常見問(wèn)題解決方法匯總》、《Android基本組件用法總結(jié)》、《Android視圖View技巧總結(jié)》、《Android布局layout技巧總結(jié)》及《Android控件用法總結(jié)

希望本文所述對(duì)大家Android程序設(shè)計(jì)有所幫助。

相關(guān)文章

  • Android 圖片處理避免出現(xiàn)oom的方法詳解

    Android 圖片處理避免出現(xiàn)oom的方法詳解

    本篇文章主要介紹了Android 圖片處理避免出現(xiàn)oom的方法詳解,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-09-09
  • Android 圖片存入系統(tǒng)相冊(cè)更新顯示實(shí)例詳解

    Android 圖片存入系統(tǒng)相冊(cè)更新顯示實(shí)例詳解

    這篇文章主要介紹了Android 圖片存入系統(tǒng)相冊(cè)更新顯示實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下
    2017-06-06
  • Android自定義UI之粒子效果

    Android自定義UI之粒子效果

    這篇文章主要為大家詳細(xì)介紹了Android自定義UI之粒子效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-10-10
  • ReactiveCocoa代碼實(shí)踐之-RAC網(wǎng)絡(luò)請(qǐng)求重構(gòu)

    ReactiveCocoa代碼實(shí)踐之-RAC網(wǎng)絡(luò)請(qǐng)求重構(gòu)

    這篇文章主要介紹了ReactiveCocoa代碼實(shí)踐之-RAC網(wǎng)絡(luò)請(qǐng)求重構(gòu) 的相關(guān)資料,需要的朋友可以參考下
    2016-04-04
  • 基于Android RecyclerView實(shí)現(xiàn)宮格拖拽效果

    基于Android RecyclerView實(shí)現(xiàn)宮格拖拽效果

    在Android發(fā)展的進(jìn)程中,網(wǎng)格布局一直比較有熱度,其中一個(gè)原因是對(duì)用戶來(lái)說(shuō)便捷操作,對(duì)app廠商而言也會(huì)帶來(lái)很多的曝光量,本篇我們會(huì)使用RecyclerView來(lái)實(shí)現(xiàn)網(wǎng)格拖拽,本篇將結(jié)合圖片分片案例,實(shí)現(xiàn)拖拽效果,需要的朋友可以參考下
    2024-03-03
  • Android不使用自定義布局情況下實(shí)現(xiàn)自定義通知欄圖標(biāo)的方法

    Android不使用自定義布局情況下實(shí)現(xiàn)自定義通知欄圖標(biāo)的方法

    這篇文章主要介紹了Android不使用自定義布局情況下實(shí)現(xiàn)自定義通知欄圖標(biāo)的方法,實(shí)例分析了Android通知欄圖標(biāo)的創(chuàng)建技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-12-12
  • Android畫中畫窗口開啟方法

    Android畫中畫窗口開啟方法

    Android8.0 Oreo(API Level26)允許活動(dòng)啟動(dòng)畫中畫Picture-in-picture(PIP)模式。PIP是一種特殊類型的多窗口模式,主要用于視頻播放。PIP模式已經(jīng)可用于Android TV,而Android8.0則讓該功能可進(jìn)一步用于其他Android設(shè)備
    2023-01-01
  • Android帶氣泡的第三方Tab選項(xiàng)卡

    Android帶氣泡的第三方Tab選項(xiàng)卡

    這篇文章主要介紹了Android帶氣泡的第三方Tab選項(xiàng)卡的實(shí)例代碼,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2017-02-02
  • 淺談Android中適配器的notifyDataSetChanged()為何有時(shí)不刷新

    淺談Android中適配器的notifyDataSetChanged()為何有時(shí)不刷新

    這篇文章主要介紹了淺談Android中適配器的notifyDataSetChanged()為何有時(shí)不刷新,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • android中intent傳遞list或者對(duì)象的方法

    android中intent傳遞list或者對(duì)象的方法

    這篇文章主要介紹了android中intent傳遞list或者對(duì)象的方法,分析羅列了常用的幾種方法,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-01-01

最新評(píng)論