您好,登錄后才能下訂單哦!
這篇文章給大家分享的是有關(guān)Android中如何使用自定義view實現(xiàn)ListView下拉的視差特效功能的內(nèi)容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。
一、概述:
現(xiàn)在流型的APP如微信朋友圈,QQ空間,微博個人展示都有視差特效的影子。
如圖:下拉圖片會產(chǎn)生圖片拉升的效果,放手后圖片有彈回到原處:
那我們?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"
模式
其它模式說明:
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)容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!
免責聲明:本站發(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)容。