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

首頁 > 系統 > Android > 正文

Android通過overScrollBy實現下拉視差特效

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

overScrollBy實現下拉視差特效,效果圖如下

Android,overScrollBy,下拉視差

先來分析overScrollBy方法的使用,它是View的方法,參數有點多:

/**   * 當滑動的超出上,下,左,右最大范圍時回調   *   * @param deltaX     x方向的瞬時偏移量,左邊到頭,向右拉為負,右邊到頭,向左拉為正   * @param deltaY     y方向的瞬時偏移量,頂部到頭,向下拉為負,底部到頭,向上拉為正   * @param scrollX    水平方向的永久偏移量   * @param scrollY    豎直方向的永久偏移量   * @param scrollRangeX  水平方向滑動的范圍   * @param scrollRangeY  豎直方向滑動的范圍   * @param maxOverScrollX 水平方向最大滑動范圍   * @param maxOverScrollY 豎直方向最大滑動范圍   * @param isTouchEvent  是否是手指觸摸滑動, true為手指, false為慣性   * @return   */   @Override   protected boolean overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY,                  int scrollRangeX, int scrollRangeY, int maxOverScrollX,                  int maxOverScrollY, boolean isTouchEvent) {     return super.overScrollBy(deltaX, deltaY, scrollX, scrollY,         scrollRangeX, scrollRangeY, maxOverScrollX, maxOverScrollY,         isTouchEvent);   } 

大致步驟如下:

1.這整體是一個ListView,所以需要自定義一個ListView.
2.處理頭部布局文件,將其以HeaderView的方式添加到自定義的ListView中
3.需要獲取HeaderView的ImageView的初始高度和ImageView中圖片的高度.因為這2個高度將決定下來的時候圖片拉出的范圍,以及松手后圖片回彈的動畫效果.對應控件寬高的獲取,有興趣的可以看這篇文章淺談自定義View的寬高獲取
4.在overScrollBy方法內通過修改ImageView的LayoutParams的height值來顯示更多的圖片內容.
5.在onTouchEvent方法內處理ACTION_UP事件,使ImageView有回彈的動畫效果,這里介紹2種方式,分別是屬性動畫和自定義動畫.

好了,先來看HeaderView的布局文件:

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"   android:layout_width="match_parent"   android:layout_height="match_parent"   android:orientation="vertical" >   <ImageView     android:id="@+id/imageView"     android:layout_width="match_parent"     android:layout_height="160dp"     <span style="color:#ff0000;">android:scaleType="centerCrop"</span>     android:src="@drawable/header" /> </LinearLayout> 

沒什么特別的,就是一個ImageView,通過src設置了一張圖片,這里唯一要將的就是scaleType屬性,我這邊設置了centerCrop,以圖片的最小的邊開始截取,因為這里選擇的圖片是高度大于寬度的,所以裁剪的時候會保留完整的寬度,中心裁剪,如下圖所示:

Android,overScrollBy,下拉視差

自定義ListView代碼,整體代碼還是比較簡短的.

/**  * Created by mChenys on 2015/12/23.  */ public class MyListView extends ListView {   private ImageView mHeaderIv; //HeaderView 的ImageView   private int mOriginalHeight; //最初ImageView的高度   private int mDrawableHeight;//ImageView中圖片的高度    public MyListView(Context context) {     this(context, null);   }    public MyListView(Context context, AttributeSet attrs) {     this(context, attrs, 0);   }    public MyListView(Context context, AttributeSet attrs, int defStyleAttr) {     super(context, attrs, defStyleAttr);     init();   }    /**    * 設置頭部和獲取高度信息    */   private void init() {     //初始化頭部文件     View headerView = View.inflate(getContext(), R.layout.view_header, null);     mHeaderIv = (ImageView) headerView.findViewById(R.id.imageView);     //將其添加到ListView的頭部     addHeaderView(headerView);     //通過設置監聽來獲取控件的高度     mHeaderIv.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {       @TargetApi(Build.VERSION_CODES.JELLY_BEAN)       @Override       public void onGlobalLayout() {         //只需監聽一次,否則之后的onLayout方法回調的時候還是會回調這里         mHeaderIv.getViewTreeObserver().removeOnGlobalLayoutListener(this);         mOriginalHeight = mHeaderIv.getMeasuredHeight();//獲取ImageView的初始高度         mDrawableHeight = mHeaderIv.getDrawable().getIntrinsicHeight();//獲取ImageView中圖片的高度       }     });     //去掉下拉到頭部后的藍色線     setOverScrollMode(OVER_SCROLL_NEVER);   }    /**    * 當滑動的超出上,下,左,右最大范圍時回調    *    * @param deltaX     x方向的瞬時偏移量,左邊到頭,向右拉為負,右邊到頭,向左拉為正    * @param deltaY     y方向的瞬時偏移量,頂部到頭,向下拉為負,底部到頭,向上拉為正    * @param scrollX    水平方向的永久偏移量    * @param scrollY    豎直方向的永久偏移量    * @param scrollRangeX  水平方向滑動的范圍    * @param scrollRangeY  豎直方向滑動的范圍    * @param maxOverScrollX 水平方向最大滑動范圍    * @param maxOverScrollY 豎直方向最大滑動范圍    * @param isTouchEvent  是否是手指觸摸滑動, true為手指, false為慣性    * @return    */   @Override   protected boolean overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY,                   int scrollRangeX, int scrollRangeY, int maxOverScrollX,                   int maxOverScrollY, boolean isTouchEvent) {     // 手指拉動并且是下拉     if (isTouchEvent && deltaY < 0) {       // 把拉動的瞬時變化量的絕對值交給Header, 就可以實現放大效果       if (mHeaderIv.getHeight() <= mDrawableHeight) {         // 高度不超出圖片最大高度時,才讓其生效         int newHeight = (int) (mHeaderIv.getHeight() + Math.abs(deltaY / 3.0f));//這里除以3是為了達到視差的效果         mHeaderIv.getLayoutParams().height = newHeight;         //此方法必須調用,調用后會重新調用onMeasure和onLayout方法進行測量和定位         mHeaderIv.requestLayout();       }     }     return super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX, scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent);   }    @Override   public boolean onTouchEvent(MotionEvent ev) {     switch (ev.getAction()) {       case MotionEvent.ACTION_UP:         // 執行回彈動畫, 方式一: 屬性動畫/值動畫         //獲取ImageView在松手時的高度         int currHeight = mHeaderIv.getHeight();         // 從當前高度mHeaderIv.getHeight(), 執行動畫到原始高度mOriginalHeight         ValueAnimator animator = ValueAnimator.ofInt(currHeight, mOriginalHeight);         animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {           @Override           public void onAnimationUpdate(ValueAnimator animation) {             int value = (int) animation.getAnimatedValue();             mHeaderIv.getLayoutParams().height = value;             //此方法必須調用,調用后會重新調用onMeasure和onLayout方法進行測量和定位             mHeaderIv.requestLayout();           }         });         animator.setDuration(500);         animator.setInterpolator(new OvershootInterpolator());         animator.start();          //方式二,通過自定義動畫         /*ResetAnimation animation = new ResetAnimation(mHeaderIv, mHeaderIv.getHeight(), mOriginalHeight);         startAnimation(animation);*/         break;     }     return super.onTouchEvent(ev);   } } 

看看自定義動畫:

/**  * 自定義動畫  * Created by mChenys on 2015/12/24.  */ public class ResetAnimation extends Animation {   private final ImageView headerIv; //要執行動畫的目標ImageView   private final int startHeight;//執行動畫的開始時的高度   private final int endHeight;//執行動畫結束時的高度   private IntEvaluator mEvaluator; //整型估值器    /**    * 構造方法初始化    *    * @param headerIv  應用動畫的目標控件    * @param startHeight 開始的高度    * @param endHeight  結束的高度    */   public ResetAnimation(ImageView headerIv, int startHeight, int endHeight) {     this.headerIv = headerIv;     this.startHeight = startHeight;     this.endHeight = endHeight;     //定義一個int類型的類型估值器,用于獲取實時變化的高度值     mEvaluator = new IntEvaluator();     //設置動畫持續時間     setDuration(500);     //設置插值器     setInterpolator(new OvershootInterpolator());   }    /**    * 在指定的時間內一直執行該方法,直到動畫結束    * interpolatedTime:0-1 標識動畫執行的進度或者百分比    *    * @param interpolatedTime    * @param t    */   @Override   protected void applyTransformation(float interpolatedTime, Transformation t) {     int currHeight = mEvaluator.evaluate(interpolatedTime, startHeight, endHeight);     //通過LayoutParams不斷的改變其高度     headerIv.getLayoutParams().height = currHeight;     //此方法必須調用,調用后會重新調用onMeasure和onLayout方法進行測量和定位     headerIv.requestLayout();   } } 

MainActivity測試類:

public class MainActivity extends AppCompatActivity {    @Override   protected void onCreate(Bundle savedInstanceState) {     super.onCreate(savedInstanceState);     MyListView listView = new MyListView(this);     listView.setDividerHeight(1);     listView.setSelector(new ColorDrawable());     listView.setCacheColorHint(Color.TRANSPARENT);     listView.setAdapter(new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, Cheeses.NAMES));     setContentView(listView);   } } 

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


注:相關教程知識閱讀請移步到Android開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 兴海县| 兴山县| 武定县| 广宁县| 陇川县| 广昌县| 瑞丽市| 罗甸县| 山东省| 灵石县| 济宁市| 连州市| 额尔古纳市| 普安县| 芦山县| 泸水县| 江油市| 阿克苏市| 正阳县| 汉川市| 四会市| 阳高县| 张家界市| 项城市| 青岛市| 涡阳县| 颍上县| 南木林县| 轮台县| 光泽县| 宜丰县| 望谟县| 巫溪县| 容城县| 日照市| 木兰县| 高陵县| 大宁县| 从化市| 元阳县| 永顺县|