溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Android中如何使用自定義view實現(xiàn)ListView下拉的視差特效功能

發(fā)布時間:2021-07-10 10:29:17 來源:億速云 閱讀:190 作者:小新 欄目:移動開發(fā)

這篇文章給大家分享的是有關(guān)Android中如何使用自定義view實現(xiàn)ListView下拉的視差特效功能的內(nèi)容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。

一、概述:

現(xiàn)在流型的APP如微信朋友圈,QQ空間,微博個人展示都有視差特效的影子。

如圖:下拉圖片會產(chǎn)生圖片拉升的效果,放手后圖片有彈回到原處:

Android中如何使用自定義view實現(xiàn)ListView下拉的視差特效功能

那我們?nèi)绾螌崿F(xiàn)呢?

1)重寫ListView控件:
2)重寫里面的overScrollBy方法
3)在松手后執(zhí)行值動畫

二、具體實現(xiàn):

1.創(chuàng)建ParallaListView 自定義ListView

public class ParallaListView extends ListView {
  private static final String TAG = "tag";
  public ParallaListView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
  }
  public ParallaListView(Context context, AttributeSet attrs) {
    this(context, attrs, 0);
  }
  public ParallaListView(Context context) {
    this(context, null);
  }
}

2)添加到布局里:

<?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" >
  <com.android.imooc.paralla.ParallaListView
    android:id="@+id/lv_paralla"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
  </com.android.imooc.paralla.ParallaListView>
</LinearLayout>

3)生成主頁,填充數(shù)據(jù):

public class ParallaActivity extends Activity {
  private ParallaListView mListView;
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_paralla);
    initViews();
  }
  private void initViews() {
    mListView = (ParallaListView) findViewById(R.id.lv_paralla);
    mListView.setAdapter(new ArrayAdapter<String>(ParallaActivity.this, android.R.layout.simple_list_item_1, Cheeses.NAMES));
  }
}

4)創(chuàng)建頭布局:

<?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/iv_header"
    android:scaleType="centerCrop"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/parallax_img" />
</LinearLayout>

圖片設(shè)成scaleType="centerCrop"模式

其它模式說明:

Android中如何使用自定義view實現(xiàn)ListView下拉的視差特效功能

5)在主頁里找到頭布局并添加到listview里

View mHeader = LayoutInflater.from(this).inflate(R.layout.view_paralla_header, null);
mListView = (ParallaListView) findViewById(R.id.lv_paralla);
mListView.addHeaderView(mHeader);

三、功能實現(xiàn):

1.現(xiàn)在基本能看到效果了,但我們必須要拖動圖片,這就要實現(xiàn)這個方法overScrollBy

因為拖動是Y軸方向,所以只要打印Y軸方向的各個參數(shù)就好了

@Override
protected boolean overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY, int scrollRangeX,
  int scrollRangeY, int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) {
    Logger.i(TAG, "deltaY="+deltaY + " scrollX="+scrollX+ " scrollRangeY="+scrollRangeY + " maxOverScrollY=" +maxOverScrollY + " isTouchEvent=" +isTouchEvent);
    return super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX, scrollRangeY, maxOverScrollX, maxOverScrollY,
        isTouchEvent);
}

得到數(shù)據(jù)下拉:deltaY=-3 scrollX=0 scrollRangeY=0 maxOverScrollY=0 isTouchEvent=true

得到數(shù)據(jù)上拉:deltaY=4 scrollX=0 scrollRangeY=0 maxOverScrollY=0 isTouchEvent=true

2.如果是下拉,我們把值賦給header,但我們?nèi)绾潍@得高度呢?

1)在主頁里初始化圖片,然后設(shè)置到parallaListView里

ImageView iv = (ImageView) findViewById(R.id.iv_head);
mListView.setParallaImage(iv);

2)在parallaListView創(chuàng)建方法setParallaImage

public void setParallaImage(ImageView iv) {
    mImageView = iv;
    //在這個方法里獲得高度
    int height = iv.getHeight();
    int measureHeight = iv.getMeasuredHeight();
    int instrinsicHeight = iv.getDrawable().getIntrinsicHeight();
    Logger.i(TAG, "height="+height + " measureHeight="+measureHeight+ " instrinsicHeight="+instrinsicHeight );
}

得到結(jié)果:height=0 measureHeight=0 instrinsicHeight=732

為什么會如此:因為此時的圖片還沒有初始化

那我們?nèi)绾蔚玫礁叨饶兀?/p>

記得有個方法叫做iv.getViewTreeObserver(),那我們就在這個方法的監(jiān)聽事件里得到高度

iv.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
  @Override
  public void onGlobalLayout() {
    //當布局填充完成后,此方法會被調(diào)用
    mListView.setParallaImage(iv);
    //移除監(jiān)聽
    iv.getViewTreeObserver().removeGlobalOnLayoutListener(this);
  }
});

此時得到的高度height=240 measureHeight=240 instrinsicHeight=732

3)把值賦給圖片就能實現(xiàn)拉伸的效果了

if (isTouchEvent && deltaY < 0) {
  mHeight += Math.abs(deltaY);
  if (mHeight <= mBitmapHeight) {
    mImageView.getLayoutParams().height = mHeight;
    mImageView.requestLayout();
  }
}

3.松手后圖片回彈,這個功能在onTouchEvent里實現(xiàn):

@Override
public boolean onTouchEvent(MotionEvent ev) {
    switch (ev.getAction()) {
    case MotionEvent.ACTION_UP:
      final int startHeight = mImageView.getHeight();
      final int endHeight = mBitmapHeight;
      //值動畫
      //valueAnim(startHeight, endHeight);
      //豎直移動動畫
      ResetAnimation anim = new ResetAnimation(mImageView, startHeight, endHeight);
      anim.setInterpolator(new OvershootInterpolator());
      startAnimation(anim);
      break;
    default:
      break;
    }
    return super.onTouchEvent(ev);
}

4、動畫實現(xiàn):

/**
 * @描述     使用平移動畫實現(xiàn)下拉圖片后彈射回去
 * @項目名稱   App_imooc
 * @包名     com.android.imooc.paralla
 * @類名     ResetAnimation
 * @author   chenlin
 * @date    2016年5月29日 下午12:27:00
 * @version   1.0
 */
public class ResetAnimation extends Animation {
  private ImageView mImageView;
  private int mStartHeight;
  private int mEndHeight;
  public ResetAnimation(ImageView imageView, int startHeight, int endHeight) {
    this.mImageView = imageView;
    this.mStartHeight = startHeight;
    this.mEndHeight = endHeight;
    setDuration(500);
  }
  @Override
  protected void applyTransformation(float interpolatedTime, Transformation t) {
    int newHeight = (int) (ValueUtil.evalute(interpolatedTime, mStartHeight, mEndHeight) + 0.5f);
    mImageView.getLayoutParams().height = newHeight;
    mImageView.requestLayout();
    super.applyTransformation(interpolatedTime, t);
  }
}

感謝各位的閱讀!關(guān)于“Android中如何使用自定義view實現(xiàn)ListView下拉的視差特效功能”這篇文章就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI