Android開發(fā)使用自定義view實(shí)現(xiàn)ListView下拉的視差特效功能
本文實(shí)例講述了Android開發(fā)使用自定義view實(shí)現(xiàn)ListView下拉的視差特效功能。分享給大家供大家參考,具體如下:
一、概述:
現(xiàn)在流型的APP如微信朋友圈,QQ空間,微博個(gè)人展示都有視差特效的影子。
如圖:下拉圖片會(huì)產(chǎn)生圖片拉升的效果,放手后圖片有彈回到原處:

那我們?nèi)绾螌?shí)現(xiàn)呢?
1)重寫ListView控件:
2)重寫里面的overScrollBy方法
3)在松手后執(zhí)行值動(dòng)畫
二、具體實(shí)現(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);
三、功能實(shí)現(xiàn):
1.現(xiàn)在基本能看到效果了,但我們必須要拖動(dòng)圖片,這就要實(shí)現(xiàn)這個(gè)方法overScrollBy
因?yàn)橥蟿?dòng)是Y軸方向,所以只要打印Y軸方向的各個(gè)參數(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;
//在這個(gè)方法里獲得高度
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
為什么會(huì)如此:因?yàn)榇藭r(shí)的圖片還沒有初始化
那我們?nèi)绾蔚玫礁叨饶兀?/p>
記得有個(gè)方法叫做iv.getViewTreeObserver(),那我們就在這個(gè)方法的監(jiān)聽事件里得到高度
iv.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
//當(dāng)布局填充完成后,此方法會(huì)被調(diào)用
mListView.setParallaImage(iv);
//移除監(jiān)聽
iv.getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
});
此時(shí)得到的高度height=240 measureHeight=240 instrinsicHeight=732
3)把值賦給圖片就能實(shí)現(xiàn)拉伸的效果了
if (isTouchEvent && deltaY < 0) {
mHeight += Math.abs(deltaY);
if (mHeight <= mBitmapHeight) {
mImageView.getLayoutParams().height = mHeight;
mImageView.requestLayout();
}
}
3.松手后圖片回彈,這個(gè)功能在onTouchEvent里實(shí)現(xiàn):
@Override
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_UP:
final int startHeight = mImageView.getHeight();
final int endHeight = mBitmapHeight;
//值動(dòng)畫
//valueAnim(startHeight, endHeight);
//豎直移動(dòng)動(dòng)畫
ResetAnimation anim = new ResetAnimation(mImageView, startHeight, endHeight);
anim.setInterpolator(new OvershootInterpolator());
startAnimation(anim);
break;
default:
break;
}
return super.onTouchEvent(ev);
}
4、動(dòng)畫實(shí)現(xiàn):
/**
* @描述 使用平移動(dòng)畫實(shí)現(xiàn)下拉圖片后彈射回去
* @項(xiàng)目名稱 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);
}
}
四、源碼下載:
完整實(shí)例代碼點(diǎn)擊此處本站下載。
更多關(guān)于Android相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Android控件用法總結(jié)》、《Android開發(fā)入門與進(jìn)階教程》、《Android視圖View技巧總結(jié)》、《Android編程之a(chǎn)ctivity操作技巧總結(jié)》、《Android數(shù)據(jù)庫操作技巧總結(jié)》及《Android資源操作技巧匯總》
希望本文所述對大家Android程序設(shè)計(jì)有所幫助。
- Android 自定義View的使用介紹
- Android自定義View實(shí)現(xiàn)廣告信息上下滾動(dòng)效果
- Android自定義View實(shí)現(xiàn)折線圖效果
- Android自定義View實(shí)現(xiàn)帶數(shù)字的進(jìn)度條實(shí)例代碼
- Android自定義View實(shí)現(xiàn)豎直跑馬燈效果案例解析
- Android自定義view制作絢麗的驗(yàn)證碼
- Android自定義View之繼承TextView繪制背景
- 實(shí)例講解Android中的View類以及自定義View控件的方法
- Android自定義view實(shí)現(xiàn)阻尼效果的加載動(dòng)畫
- android開發(fā)教程之實(shí)現(xiàn)listview下拉刷新和上拉刷新效果
- Android實(shí)現(xiàn)上拉加載更多以及下拉刷新功能(ListView)
相關(guān)文章
Android手機(jī)衛(wèi)士之確認(rèn)密碼對話框
這篇文章主要為大家詳細(xì)介紹了Android手機(jī)衛(wèi)士之確認(rèn)密碼對話框,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-10-10
Android 自定義日期段選擇控件功能(開始時(shí)間-結(jié)束時(shí)間)
這篇文章主要介紹了Android 自定義日期段選擇控件功能,開始時(shí)間-結(jié)束時(shí)間。本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-04-04
android自定義view實(shí)現(xiàn)圓周運(yùn)動(dòng)
這篇文章主要為大家詳細(xì)介紹了android自定義view實(shí)現(xiàn)逆時(shí)針和順時(shí)針轉(zhuǎn)動(dòng)的圓周運(yùn)動(dòng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-03-03
Android實(shí)現(xiàn)淘寶選中商品尺寸的按鈕組實(shí)例
這篇文章介紹的是仿淘寶中的選中商品不同尺寸,比如衣服有L、M、XL等等的款式。這時(shí)候我們就需要一個(gè)button組來進(jìn)行了,當(dāng)時(shí)這個(gè)時(shí)候里面的尺寸可能有很多,那怎么辦呢?這里我們就肯定要做個(gè)自適應(yīng)的按鈕組了,要不然弄出來也沒用。2016-08-08

