标签:
视差特效
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity" ><com.itheima.parallaxdemo.ui.MyListViewandroid:id="@+id/lv"android:layout_width="match_parent"android:layout_height="match_parent" /></RelativeLayout>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical" ><ImageViewandroid:id="@+id/iv"android:layout_width="match_parent"android:layout_height="160dp"android:scaleType="centerCrop"android:src="@drawable/parallax_img" /></LinearLayout>
/*** 视差特效ListView* overScrollBy* @author poplar**/public class MyListView extends ListView {private static final String TAG = "TAG";private int mOriginalHeight;private int drawableHeight;private ImageView mImage;public MyListView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);}public MyListView(Context context, AttributeSet attrs) {super(context, attrs);}public MyListView(Context context) {super(context);}/*** 设置ImageView图片, 拿到引用* @param mImage*/public void setParallaxImage(ImageView mImage) {this.mImage = mImage;mOriginalHeight = mImage.getHeight(); // 160drawableHeight = mImage.getDrawable().getIntrinsicHeight(); // 488,图片的高,而不是显示的高Log.d(TAG, "height: " + mOriginalHeight + " drawableHeight: " + drawableHeight);}@Overrideprotected boolean overScrollBy(int deltaX, int deltaY,int scrollX, int scrollY, int scrollRangeX, int scrollRangeY,int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) {// deltaY : 竖直方向的瞬时偏移量 / 变化量 dx 顶部到头下拉为-, 底部到头上拉为+// scrollY : 竖直方向的偏移量 / 变化量// scrollRangeY : 竖直方向滑动的范围// maxOverScrollY : 竖直方向最大滑动范围// isTouchEvent : 是否是手指触摸滑动, true为手指, false为惯性Log.d(TAG, "deltaY: " +deltaY + " scrollY: " + scrollY + " scrollRangeY: " + scrollRangeY+ " maxOverScrollY: " + maxOverScrollY + " isTouchEvent: " + isTouchEvent);// 手指拉动 并且 是下拉if(isTouchEvent && deltaY < 0){// 把拉动的瞬时变化量的绝对值交给Header, 就可以实现放大效果if(mImage.getHeight() <= drawableHeight){int newHeight = (int) (mImage.getHeight() + Math.abs(deltaY / 3.0f));// 高度不超出图片最大高度时,才让其生效mImage.getLayoutParams().height = newHeight;mImage.requestLayout();}}return super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX,scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent);}@Overridepublic boolean onTouchEvent(MotionEvent ev) {switch (ev.getAction()) {case MotionEvent.ACTION_UP:// 执行回弹动画, 方式一: 属性动画\值动画// 从当前高度mImage.getHeight(), 执行动画到原始高度mOriginalHeightfinal int startHeight = mImage.getHeight();final int endHeight = mOriginalHeight;// valueAnimator(startHeight, endHeight);// 执行回弹动画, 方式二: 自定义AnimationResetAnimation animation = new ResetAnimation(mImage, startHeight, endHeight);startAnimation(animation);break;}return super.onTouchEvent(ev);}private void valueAnimator(final int startHeight, final int endHeight) {ValueAnimator mValueAnim = ValueAnimator.ofInt(1);//不起作用,写几都行mValueAnim.addUpdateListener(new AnimatorUpdateListener() {@Overridepublic void onAnimationUpdate(ValueAnimator mAnim) {float fraction = mAnim.getAnimatedFraction();// percent 0.0 -> 1.0Log.d(TAG, "fraction: " +fraction);Integer newHeight = evaluate(fraction, startHeight, endHeight);//固值器mImage.getLayoutParams().height = newHeight;//设置imageview高度mImage.requestLayout();}});mValueAnim.setInterpolator(new OvershootInterpolator());mValueAnim.setDuration(500);mValueAnim.start();}public Integer evaluate(float fraction, Integer startValue, Integer endValue) {int startInt = startValue;return (int)(startInt + fraction * (endValue - startInt));}}
public class ResetAnimation extends Animation {private final ImageView mImage;private final int startHeight;private final int endHeight;public ResetAnimation(ImageView mImage, int startHeight, int endHeight) {this.mImage = mImage;this.startHeight = startHeight;this.endHeight = endHeight;setInterpolator(new OvershootInterpolator());//设置动画执行时长setDuration(500);}@Overrideprotected void applyTransformation(float interpolatedTime, Transformation t) {// interpolatedTime 0.0f -> 1.0fInteger newHeight = evaluate(interpolatedTime, startHeight, endHeight);mImage.getLayoutParams().height = newHeight;//设置imageview高mImage.requestLayout();super.applyTransformation(interpolatedTime, t);}/*** 类型估值器* @param fraction* @param startValue* @param endValue* @return*/public Integer evaluate(float fraction, Integer startValue, Integer endValue) {int startInt = startValue;return (int)(startInt + fraction * (endValue - startInt));}}
public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);final MyListView mListView = (MyListView) findViewById(R.id.lv);mListView.setOverScrollMode(View.OVER_SCROLL_NEVER);// 加Headerfinal View mHeaderView = View.inflate(MainActivity.this, R.layout.view_header, null);final ImageView mImage = (ImageView) mHeaderView.findViewById(R.id.iv);mListView.addHeaderView(mHeaderView);mHeaderView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {@Overridepublic void onGlobalLayout() {// 当布局填充结束之后, 此方法会被调用mListView.setParallaxImage(mImage);mHeaderView.getViewTreeObserver().removeGlobalOnLayoutListener(this);}});// 填充数据mListView.setAdapter(new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_1, Cheeses.NAMES));}}
标签:
原文地址:http://www.cnblogs.com/liuyu0529/p/5041944.html