最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

android ScrollView實(shí)現(xiàn)下拉放大頭部圖片

 更新時(shí)間:2017年12月22日 16:07:13   作者:Jimi_Wu  
這篇文章主要為大家詳細(xì)介紹了android ScrollView實(shí)現(xiàn)下拉放大頭部圖片,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

前言

之前做項(xiàng)目的時(shí)候,需要實(shí)現(xiàn)類似微博個(gè)人主頁的ScrollView效果,就是到頂部時(shí)繼續(xù)下拉會(huì)放大頂部的圖片。然后在網(wǎng)上找了一篇相關(guān)的實(shí)現(xiàn),效果非常好,代碼也很簡(jiǎn)潔易懂。(傳送門: 自定義scrollView實(shí)現(xiàn)頂部圖片下拉放大),那么我這里就只是在其基礎(chǔ)上修改了一點(diǎn)點(diǎn)而已,比如在代碼中控制圖片居中、增加動(dòng)態(tài)設(shè)置放大的控件、使用自定義的最大放大倍數(shù)等,都是很簡(jiǎn)單的修改,還添加了滑動(dòng)的監(jiān)聽回調(diào)(項(xiàng)目需要)。

效果如下:

思路

老樣子,我們先來說下思路,比起代碼,思路才是最重要的。具體步驟如下:
1. 獲得要放大的控件,并獲得其寬高;
2. 在頂部時(shí)繼續(xù)往下拉,通過LayoutParams改變控件的寬高;
3. 手指抬起時(shí)初始化各項(xiàng)參數(shù),通過屬性動(dòng)畫回彈控件。

實(shí)現(xiàn)

直接看代碼

public class HeadZoomScrollView extends ScrollView {

 public HeadZoomScrollView(Context context) {
  super(context);
 }

 public HeadZoomScrollView(Context context, AttributeSet attrs) {
  super(context, attrs);
 }

 public HeadZoomScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
  super(context, attrs, defStyleAttr);
 }

 // 用于記錄下拉位置
 private float y = 0f;
 // zoomView原本的寬高
 private int zoomViewWidth = 0;
 private int zoomViewHeight = 0;

 // 是否正在放大
 private boolean mScaling = false;

 // 放大的view,默認(rèn)為第一個(gè)子view
 private View zoomView;
 public void setZoomView(View zoomView) {
  this.zoomView = zoomView;
 }

 // 滑動(dòng)放大系數(shù),系數(shù)越大,滑動(dòng)時(shí)放大程度越大
 private float mScaleRatio = 0.4f;
 public void setmScaleRatio(float mScaleRatio) {
  this.mScaleRatio = mScaleRatio;
 }

 // 最大的放大倍數(shù)
 private float mScaleTimes = 2f;
 public void setmScaleTimes(int mScaleTimes) {
  this.mScaleTimes = mScaleTimes;
 }

 // 回彈時(shí)間系數(shù),系數(shù)越小,回彈越快
 private float mReplyRatio = 0.5f;
 public void setmReplyRatio(float mReplyRatio) {
  this.mReplyRatio = mReplyRatio;
 }

 @Override
 protected void onFinishInflate() {
  super.onFinishInflate();
//  不可過度滾動(dòng),否則上移后下拉會(huì)出現(xiàn)部分空白的情況
  setOverScrollMode(OVER_SCROLL_NEVER);
//  獲得默認(rèn)第一個(gè)view
  if (getChildAt(0) != null && getChildAt(0) instanceof ViewGroup && zoomView == null) {
   ViewGroup vg = (ViewGroup) getChildAt(0);
   if (vg.getChildCount() > 0) {
    zoomView = vg.getChildAt(0);
   }
  }
 }

 @Override
 public boolean onTouchEvent(MotionEvent ev) {
  if (zoomViewWidth <= 0 || zoomViewHeight <=0) {
   zoomViewWidth = zoomView.getMeasuredWidth();
   zoomViewHeight = zoomView.getMeasuredHeight();
  }
  if (zoomView == null || zoomViewWidth <= 0 || zoomViewHeight <= 0) {
   return super.onTouchEvent(ev);
  }
  switch (ev.getAction()) {
   case MotionEvent.ACTION_MOVE:
    if (!mScaling) {
     if (getScrollY() == 0) {
      y = ev.getY();//滑動(dòng)到頂部時(shí),記錄位置
     } else {
      break;
     }
    }
    int distance = (int) ((ev.getY() - y)*mScaleRatio);
    if (distance < 0) break;//若往下滑動(dòng)
    mScaling = true;
    setZoom(distance);
    return true;
   case MotionEvent.ACTION_UP:
    mScaling = false;
    replyView();
    break;
  }
  return super.onTouchEvent(ev);
 }

 /**放大view*/
 private void setZoom(float s) {
  float scaleTimes = (float) ((zoomViewWidth+s)/(zoomViewWidth*1.0));
//  如超過最大放大倍數(shù),直接返回
  if (scaleTimes > mScaleTimes) return;

  ViewGroup.LayoutParams layoutParams = zoomView.getLayoutParams();
  layoutParams.width = (int) (zoomViewWidth + s);
  layoutParams.height = (int)(zoomViewHeight*((zoomViewWidth+s)/zoomViewWidth));
//  設(shè)置控件水平居中
  ((MarginLayoutParams) layoutParams).setMargins(-(layoutParams.width - zoomViewWidth) / 2, 0, 0, 0);
  zoomView.setLayoutParams(layoutParams);
 }

 /**回彈*/
 private void replyView() {
  final float distance = zoomView.getMeasuredWidth() - zoomViewWidth;
  // 設(shè)置動(dòng)畫
  ValueAnimator anim = ObjectAnimator.ofFloat(distance, 0.0F).setDuration((long) (distance * mReplyRatio));
  anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
   @Override
   public void onAnimationUpdate(ValueAnimator animation) {
    setZoom((Float) animation.getAnimatedValue());
   }
  });
  anim.start();
 }

 @Override
 protected void onScrollChanged(int l, int t, int oldl, int oldt) {
  super.onScrollChanged(l, t, oldl, oldt);
  if (onScrollListener!=null) onScrollListener.onScroll(l,t,oldl,oldt);
 }

 private OnScrollListener onScrollListener;
 public void setOnScrollListener(OnScrollListener onScrollListener) {
  this.onScrollListener = onScrollListener;
 }

 /**滑動(dòng)監(jiān)聽*/
 public interface OnScrollListener{
  void onScroll(int scrollX,int scrollY,int oldScrollX, int oldScrollY);
 }


}

可以看到,在onTouchEvent方法中,先判斷當(dāng)前是否為放大狀態(tài),不是的話就在頂部的時(shí)候記錄觸摸事件的位置,當(dāng)然這個(gè)寫在ACTION_DOWN事件中也是可以的,若不在頂部,則不處理。

之后計(jì)算滑動(dòng)的距離,若是往下滑動(dòng),則不處理,需要注意的是這個(gè)距離是指當(dāng)前位置與最開始的ACTION_DOWN動(dòng)作的距離,因此當(dāng)這個(gè)距離小于0的時(shí)候,便是”沒放大&&往下滑”,這個(gè)時(shí)候應(yīng)該滑動(dòng)的是ScrollView,恩,沒毛病。當(dāng)距離不小于0的時(shí)候,開始放大控件,可以看到調(diào)用了setZoom方法,注意,在這里其實(shí)控件的下拉放大、上拉恢復(fù)都做了, 回彈其實(shí)也是調(diào)用這個(gè)方法。

抬手的時(shí)候回彈,這個(gè)不需要說了。

代碼整體來說比較簡(jiǎn)單,要是你需要其他實(shí)現(xiàn),也可以很方便地加上,比如我們要放大圖片的時(shí)候像微博一樣,旋轉(zhuǎn)外部的菊花,放手的時(shí)候刷新數(shù)據(jù)怎么辦?你完全可以在
onTouchEvent中增加回調(diào)接口,然后在外部實(shí)現(xiàn)具體邏輯就可以了。

使用

直接像普通的ScollView樣使用就可以了,這個(gè)就不累贅了。

源碼:下載地址

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Android自動(dòng)化獲取卡頓信息的實(shí)現(xiàn)方法

    Android自動(dòng)化獲取卡頓信息的實(shí)現(xiàn)方法

    自動(dòng)化獲取卡頓信息就像給App裝  “行車記錄儀”  —— 實(shí)時(shí)記錄主線程的“駕駛狀態(tài)”,一旦發(fā)現(xiàn)“急剎車”(卡頓),立刻保存現(xiàn)場(chǎng)(堆棧),事后回看錄像(日志)精準(zhǔn)定位問題,本文給大家介紹了Android自動(dòng)化獲取卡頓信息的實(shí)現(xiàn)方法,需要的朋友可以參考下
    2025-02-02
  • Android操作系統(tǒng)的架構(gòu)設(shè)計(jì)分析

    Android操作系統(tǒng)的架構(gòu)設(shè)計(jì)分析

    這篇文章主要介紹了Android操作系統(tǒng)的架構(gòu)設(shè)計(jì)分析,Android系統(tǒng)架構(gòu)分為L(zhǎng)inux內(nèi)核驅(qū)動(dòng)、C/C ++框架、Java框架、Java應(yīng)用程序,本文分別講解了它的作用,需要的朋友可以參考下
    2015-06-06
  • Android畫板開發(fā)之撤銷反撤銷功能

    Android畫板開發(fā)之撤銷反撤銷功能

    這篇文章主要為大家詳細(xì)介紹了Android畫板開發(fā)之撤銷,反撤銷功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-12-12
  • 簡(jiǎn)單實(shí)現(xiàn)android輪播圖

    簡(jiǎn)單實(shí)現(xiàn)android輪播圖

    這篇文章主要為大家詳細(xì)介紹了android輪播圖的相關(guān)資料,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-01-01
  • Android ListView實(shí)現(xiàn)下拉加載功能

    Android ListView實(shí)現(xiàn)下拉加載功能

    這篇文章主要為大家詳細(xì)介紹了Android ListView實(shí)現(xiàn)下拉加載功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-08-08
  • Android開發(fā)實(shí)現(xiàn)撥打電話與發(fā)送信息的方法分析

    Android開發(fā)實(shí)現(xiàn)撥打電話與發(fā)送信息的方法分析

    這篇文章主要介紹了Android開發(fā)實(shí)現(xiàn)撥打電話與發(fā)送信息的方法,結(jié)合實(shí)例形式分析了Android撥打電話及發(fā)送信息相關(guān)布局、功能實(shí)現(xiàn)及權(quán)限控制操作技巧,需要的朋友可以參考下
    2017-12-12
  • Android實(shí)現(xiàn)夜間模式切換功能實(shí)現(xiàn)代碼

    Android實(shí)現(xiàn)夜間模式切換功能實(shí)現(xiàn)代碼

    現(xiàn)在很多App都有夜間模式,特別是閱讀類的App,夜間模式現(xiàn)在已經(jīng)是閱讀類App的標(biāo)配,本篇文章主要介紹了Android實(shí)現(xiàn)夜間模式功能實(shí)現(xiàn)代碼,有興趣的可以了解一下。
    2017-03-03
  • Android 物理游戲之重力系統(tǒng)開發(fā)示例代碼

    Android 物理游戲之重力系統(tǒng)開發(fā)示例代碼

    介紹Android 物理游戲之重力系統(tǒng),這里提供了詳細(xì)的資料整理,并附示例代碼和實(shí)現(xiàn)效果圖,有興趣的小伙伴可以參考下
    2016-08-08
  • Android獲取當(dāng)前位置的經(jīng)緯度數(shù)據(jù)

    Android獲取當(dāng)前位置的經(jīng)緯度數(shù)據(jù)

    這篇文章主要介紹了Android獲取當(dāng)前位置的經(jīng)緯度數(shù)據(jù)的相關(guān)資料,需要的朋友可以參考下
    2016-02-02
  • 詳談Android從文件讀取圖像顯示的效率問題

    詳談Android從文件讀取圖像顯示的效率問題

    下面小編就為大家?guī)硪黄斦凙ndroid從文件讀取圖像顯示的效率問題。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-03-03

最新評(píng)論

安化县| 湘乡市| 浦北县| 宣汉县| 库尔勒市| 焉耆| 东光县| 虹口区| 清丰县| 巴林左旗| 汉源县| 拉孜县| 张掖市| 长乐市| 修文县| 永登县| 吴桥县| 图片| 疏附县| 东光县| 若羌县| 砚山县| 盐源县| 武汉市| 陇西县| 长治县| 通道| 侯马市| 榆中县| 公安县| 兴和县| 渭源县| 齐河县| 石台县| 大埔区| 南召县| 额济纳旗| 丹阳市| 红原县| 高平市| 星子县|