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

首頁 > 系統(tǒng) > Android > 正文

Android ListView實(shí)現(xiàn)下拉頂部圖片變大效果

2019-10-22 18:19:00
字體:
供稿:網(wǎng)友

本文實(shí)例為大家分享了Android ListView下拉頂部圖片變大的具體代碼,供大家參考,具體內(nèi)容如下

在git上查看牛人的代碼,發(fā)現(xiàn)是反編譯別人的代碼,還沒加注釋,代碼也沒有完全編譯完整,所以這里我做的簡單的注釋,僅供學(xué)習(xí)。

變量說明

這里變量包含了:自定義返回動(dòng)畫加速度、自定義動(dòng)畫線程、頭部圖片view,最后的y坐標(biāo),做好的比例,做大的比例等。

private static final String TAG = "PullToZoomListView"; private static final int INVALID_VALUE = -1;//重置值 //自定義加速度動(dòng)畫 private static final Interpolator sInterpolator = new Interpolator() {  public float getInterpolation(float interpolator) {   float f = interpolator - 1.0F;   return 1.0F + f * (f * (f * (f * f)));  } }; private int mActivePointerId = INVALID_VALUE;//當(dāng)前手指的Id private FrameLayout mHeaderContainer;//頭部 private int mHeaderHeight;//頭部圖片的高度 private ImageView mHeaderImage;//頭部圖片 float mLastMotionY = INVALID_VALUE;//最后y坐標(biāo) float mLastScale = INVALID_VALUE;//最后的比例 float mMaxScale = INVALID_VALUE;//最大的比例 private OnScrollListener mOnScrollListener;//滑動(dòng)監(jiān)聽 private ScalingRunnalable mScalingRunnalable;//動(dòng)畫線程 private int mScreenHeight;//屏幕高度 private ImageView mShadow;//陰影遮罩

自定義View初始化:設(shè)置了頭部的頭部和遮罩并且設(shè)置了監(jiān)聽。

/**  * 初始化  * @param paramContext  */ private void init(Context paramContext) {  DisplayMetrics metrics = new DisplayMetrics();  ((Activity) paramContext).getWindowManager().getDefaultDisplay().getMetrics(metrics);  this.mScreenHeight = metrics.heightPixels;//屏幕高度賦值  this.mHeaderContainer = new FrameLayout(paramContext);//頭部  this.mHeaderImage = new ImageView(paramContext);//頭部圖片  int screenWidth = metrics.widthPixels;//屏幕寬度  //設(shè)置頭部View的樣式 設(shè)置屏幕寬度,最大樣式高度為屏幕高度的9/16  setHeaderViewSize(screenWidth, (int) (9.0F * (screenWidth / 16.0F)));  this.mShadow = new ImageView(paramContext);//遮罩  FrameLayout.LayoutParams layoutParams =    new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,      ViewGroup.LayoutParams.MATCH_PARENT);  layoutParams.gravity = Gravity.CENTER;  this.mShadow.setLayoutParams(layoutParams);//設(shè)置遮罩樣式  //頭部添加View  this.mHeaderContainer.addView(this.mHeaderImage);  this.mHeaderContainer.addView(this.mShadow);  //添加頭部  addHeaderView(this.mHeaderContainer);  //初始化返回動(dòng)畫  this.mScalingRunnalable = new ScalingRunnalable();  //設(shè)置監(jiān)聽  super.setOnScrollListener(this); }

開啟動(dòng)畫:判斷當(dāng)前的頭部布局底部的位置–是否大于圖片的初始化高度。

/**  * 開啟動(dòng)畫  */ private void endScraling() {  if (this.mHeaderContainer.getBottom() >= this.mHeaderHeight) {   Log.d(TAG, "this.mScalingRunnalable.startAnimation(200L)");   this.mScalingRunnalable.startAnimation(200L);  } }

多指觸碰時(shí)將第0個(gè)手指賦值。

/**  * 多點(diǎn)觸碰的時(shí)候按下,當(dāng)?shù)?個(gè)有手指抬起,再次有手指按下后,將按下的事件的手指指針作為當(dāng)前手指指針  *  * @param motionEvent  */ private void onSecondaryPointerUp(MotionEvent motionEvent) {  Log.d(TAG, "onSecondaryPointerUp motionEvent.getPointerId(0) = " + motionEvent.getPointerId(0));  Log.d(TAG, "onSecondaryPointerUp this.mActivePointerId = " + this.mActivePointerId);  if (motionEvent.getPointerId(0) == this.mActivePointerId) {   this.mLastMotionY = motionEvent.getY(0);   this.mActivePointerId = motionEvent.getPointerId(0);  }  Log.d(TAG, "onSecondaryPointerUp mLastMotionY = " + mLastMotionY);  Log.d(TAG, "onSecondaryPointerUp mActivePointerId = " + mActivePointerId); }

重置所有的數(shù)據(jù)

/** * 重置所有數(shù)據(jù)*/ private void reset() {  this.mActivePointerId = INVALID_VALUE;  this.mLastMotionY = INVALID_VALUE;  this.mMaxScale = INVALID_VALUE;  this.mLastScale = INVALID_VALUE; }

向上滾動(dòng)時(shí)修改布局樣式

@Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {  Log.d(TAG, "onScroll");  float bottomSpacing = this.mHeaderHeight - this.mHeaderContainer.getBottom();  Log.d(TAG, "onScroll bottomSpacing = " + bottomSpacing);  if ((bottomSpacing > 0.0F) && (bottomSpacing < this.mHeaderHeight)) {//如果是向上滑動(dòng)   int toUpScroll = (int) (0.65D * bottomSpacing);   this.mHeaderImage.scrollTo(0, -toUpScroll);   Log.d(TAG, "onScroll 向上滑動(dòng) toUpScroll = " + toUpScroll);  } else if (this.mHeaderImage.getScrollY() != 0) {   Log.d(TAG, "onScroll this.mHeaderImage.getScrollY() = " + this.mHeaderImage.getScrollY());   this.mHeaderImage.scrollTo(0, 0);  }  if (this.mOnScrollListener != null) {   this.mOnScrollListener.onScroll(view, firstVisibleItem, visibleItemCount, totalItemCount);  } }

不同事件處理,修改布局樣式

@Override public boolean onTouchEvent(MotionEvent motionEvent) {  switch (motionEvent.getAction() & MotionEvent.ACTION_MASK) {   case MotionEvent.ACTION_OUTSIDE:   case MotionEvent.ACTION_DOWN:    if (!this.mScalingRunnalable.mIsFinished) {     this.mScalingRunnalable.abortAnimation();    }    this.mLastMotionY = motionEvent.getY();    //獲取第一個(gè)手指指針的ID    this.mActivePointerId = motionEvent.getPointerId(0);    this.mMaxScale = (this.mScreenHeight / this.mHeaderHeight);    this.mLastScale = (this.mHeaderContainer.getBottom() / this.mHeaderHeight);    Log.d(TAG, "onTouchEvent ACTION_DOWN mLastMotionY = " + mLastMotionY);    Log.d(TAG, "onTouchEvent ACTION_DOWN mActivePointerId = " + mActivePointerId);    Log.d(TAG, "onTouchEvent ACTION_DOWN mMaxScale = " + mMaxScale);    Log.d(TAG, "onTouchEvent ACTION_DOWN mLastScale = " + mLastScale);    break;   case MotionEvent.ACTION_MOVE:    Log.d(TAG, "onTouchEvent ACTION_MOVE mActivePointerId" + mActivePointerId);    //獲取當(dāng)前id的手機(jī)指針    int pointer = motionEvent.findPointerIndex(this.mActivePointerId);    //判斷指針不為空    if (pointer == INVALID_VALUE) {     Log.e(TAG, "Invalid pointerId=" + this.mActivePointerId + " in onTouchEvent");    } else {     //如果開始沒有賦值,則需要賦值     if (this.mLastMotionY == INVALID_VALUE) {      this.mLastMotionY = motionEvent.getY(pointer);     }     if (this.mHeaderContainer.getBottom() >= this.mHeaderHeight) {      //獲取頭部樣式      ViewGroup.LayoutParams headerParams = this.mHeaderContainer.getLayoutParams();      float currentScale = ((motionEvent.getY(pointer) - this.mLastMotionY + this.mHeaderContainer.getBottom())        / this.mHeaderHeight - this.mLastScale)        / 2.0F + this.mLastScale;      if ((this.mLastScale <= 1.0D) && (currentScale < this.mLastScale)) {       //最后比例小于默認(rèn)并且當(dāng)前的比例要小于上次的比例,則修改頭部的高度       headerParams.height = this.mHeaderHeight;       this.mHeaderContainer.setLayoutParams(headerParams);       return super.onTouchEvent(motionEvent);      } else {       //否則,將當(dāng)前的比例賦值為最后一次的比例       this.mLastScale = Math.min(Math.max(currentScale, 1.0F), this.mMaxScale);       headerParams.height = ((int) (this.mHeaderHeight * this.mLastScale));       //判斷修改后的高度小于屏幕的高度       if (headerParams.height < this.mScreenHeight) {        this.mHeaderContainer.setLayoutParams(headerParams);       }       //記錄最后的y坐標(biāo)       this.mLastMotionY = motionEvent.getY(pointer);       return true;      }     }     this.mLastMotionY = motionEvent.getY(pointer);    }    break;   case MotionEvent.ACTION_UP:    Log.d(TAG, "onTouchEvent ACTION_UP 重置");    //重置    reset();    //當(dāng)手指起來的時(shí)候,結(jié)算拉伸,判斷是否開啟動(dòng)畫    endScraling();    break;   case MotionEvent.ACTION_CANCEL:    int actionIndex = motionEvent.getActionIndex();//獲取當(dāng)前最上層的指針    this.mLastMotionY = motionEvent.getY(actionIndex);//獲取最后的y坐標(biāo)    this.mActivePointerId = motionEvent.getPointerId(actionIndex);//獲取最上層指針的手指    Log.d(TAG, "onTouchEvent ACTION_CANCEL actionIndex = " + actionIndex + " mLastMotionY = " + mLastMotionY + " mActivePointerId = " + mActivePointerId);    break;   case MotionEvent.ACTION_POINTER_DOWN:    //當(dāng)?shù)诙€(gè)手指按下或者放開觸發(fā)這個(gè)事件    onSecondaryPointerUp(motionEvent);    this.mLastMotionY = motionEvent.getY(motionEvent.findPointerIndex(this.mActivePointerId));    Log.d(TAG, "onTouchEvent_Po ACTION_POINTER_DOWN mLastMotionY = " + mLastMotionY);    break;   case MotionEvent.ACTION_POINTER_UP:    //當(dāng)?shù)诙€(gè)手指按下或者放開    Log.d(TAG, "onTouchEvent_Po ACTION_POINTER_UP ");    break;  }  return super.onTouchEvent(motionEvent); }

向上返回時(shí)的動(dòng)畫

/**  * 向上返回的動(dòng)畫  */ class ScalingRunnalable implements Runnable {  long mDuration;//持續(xù)時(shí)間  boolean mIsFinished = true;//是否結(jié)束  float mScale;//比例  long mStartTime;//開始時(shí)間  ScalingRunnalable() {  }  /**   * 中止動(dòng)畫   */  public void abortAnimation() {   this.mIsFinished = true;  }  /**   * 是否中止   *   * @return   */  public boolean isFinished() {   return this.mIsFinished;  }  public void run() {   Log.d(TAG, "ScalingRunnalable mIsFinished = " + this.mIsFinished + " this.mScale = " + this.mScale);   float currentScale;   ViewGroup.LayoutParams mHeaderContainerParams;//頭部樣式   //判斷是否中止和已經(jīng)滑動(dòng)超過的默認(rèn)大小   if ((!this.mIsFinished) && (this.mScale > 1.0D)) {    float currentTime = ((float) SystemClock.currentThreadTimeMillis() - (float) this.mStartTime) / (float) this.mDuration;    currentScale = this.mScale - (this.mScale - 1.0F) * PullToZoomListView.sInterpolator.getInterpolation(currentTime);    Log.d(TAG, "ScalingRunnalable currentTime = " + currentTime + " currentScale = " + currentScale);    mHeaderContainerParams = PullToZoomListView.this.mHeaderContainer.getLayoutParams();    if (currentScale > 1.0F) {     Log.d(TAG, "ScalingRunnalable currentScale > 1.0 -- 修改頭部高度");     mHeaderContainerParams.height = PullToZoomListView.this.mHeaderHeight;     mHeaderContainerParams.height = ((int) (currentScale * PullToZoomListView.this.mHeaderHeight));     PullToZoomListView.this.mHeaderContainer.setLayoutParams(mHeaderContainerParams);     PullToZoomListView.this.post(this);//循環(huán)執(zhí)行    } else {     Log.d(TAG, "ScalingRunnalable currentScale < 1.0 -- 中止");     this.mIsFinished = true;    }   }  }  public void startAnimation(long paramLong) {   Log.d(TAG, "ScalingRunnalable 開始執(zhí)行動(dòng)畫");   this.mStartTime = SystemClock.currentThreadTimeMillis();   this.mDuration = paramLong;   this.mScale = ((float) (PullToZoomListView.this.mHeaderContainer.getBottom()) / PullToZoomListView.this.mHeaderHeight);   this.mIsFinished = false;   Log.d(TAG, "ScalingRunnalable this.mStartTime = " + this.mStartTime);   Log.d(TAG, "ScalingRunnalable this.mDuration = " + this.mDuration);   Log.d(TAG, "ScalingRunnalable this.mScale = " + this.mScale);   Log.d(TAG, "ScalingRunnalable this.mIsFinished = " + this.mIsFinished);   PullToZoomListView.this.post(this);  } }

以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持VEVB武林網(wǎng)。


注:相關(guān)教程知識(shí)閱讀請移步到Android開發(fā)頻道。
發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 石台县| 麻栗坡县| 临猗县| 马龙县| 中西区| 柳江县| 兰考县| 崇义县| 连平县| 抚州市| 遵义县| 北流市| 新源县| 余干县| 汉沽区| 崇明县| 望谟县| 治县。| 永宁县| 云安县| 沾益县| 松原市| 庆云县| 宿松县| 儋州市| 大庆市| 临洮县| 安溪县| 瑞丽市| 合水县| 礼泉县| 长垣县| 怀仁县| 泰和县| 临泉县| 溆浦县| 察隅县| 寿阳县| 班戈县| 柞水县| 九江市|