码迷,mamicode.com
首页 > 其他好文 > 详细

9.视差特效、回弹动画、overScrollBy

时间:2015-12-12 23:11:28      阅读:253      评论:0      收藏:0      [点我收藏+]

标签:

视差特效 
应用场景: 微信朋友圈, QQ空间, 微博个人展示
功能实现:
> 1. 之前重写onTouch, 如今重写overScrollBy
> 2. 松手之后执行动画, 类型估值器
技术分享
activity_main
  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2. xmlns:tools="http://schemas.android.com/tools"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. tools:context=".MainActivity" >
  6. <com.itheima.parallaxdemo.ui.MyListView
  7. android:id="@+id/lv"
  8. android:layout_width="match_parent"
  9. android:layout_height="match_parent" />
  10. </RelativeLayout>
view_header
  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2. android:layout_width="match_parent"
  3. android:layout_height="match_parent"
  4. android:orientation="vertical" >
  5. <ImageView
  6. android:id="@+id/iv"
  7. android:layout_width="match_parent"
  8. android:layout_height="160dp"
  9. android:scaleType="centerCrop"
  10. android:src="@drawable/parallax_img" />
  11. </LinearLayout>
MyListView
  1. /**
  2. * 视差特效ListView
  3. * overScrollBy
  4. * @author poplar
  5. *
  6. */
  7. public class MyListView extends ListView {
  8. private static final String TAG = "TAG";
  9. private int mOriginalHeight;
  10. private int drawableHeight;
  11. private ImageView mImage;
  12. public MyListView(Context context, AttributeSet attrs, int defStyle) {
  13. super(context, attrs, defStyle);
  14. }
  15. public MyListView(Context context, AttributeSet attrs) {
  16. super(context, attrs);
  17. }
  18. public MyListView(Context context) {
  19. super(context);
  20. }
  21. /**
  22. * 设置ImageView图片, 拿到引用
  23. * @param mImage
  24. */
  25. public void setParallaxImage(ImageView mImage) {
  26. this.mImage = mImage;
  27. mOriginalHeight = mImage.getHeight(); // 160
  28. drawableHeight = mImage.getDrawable().getIntrinsicHeight(); // 488,图片的高,而不是显示的高
  29. Log.d(TAG, "height: " + mOriginalHeight + " drawableHeight: " + drawableHeight);
  30. }
  31. @Override
  32. protected boolean overScrollBy(int deltaX, int deltaY,
  33. int scrollX, int scrollY, int scrollRangeX, int scrollRangeY,
  34. int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) {
  35. // deltaY : 竖直方向的瞬时偏移量 / 变化量 dx 顶部到头下拉为-, 底部到头上拉为+
  36. // scrollY : 竖直方向的偏移量 / 变化量
  37. // scrollRangeY : 竖直方向滑动的范围
  38. // maxOverScrollY : 竖直方向最大滑动范围
  39. // isTouchEvent : 是否是手指触摸滑动, true为手指, false为惯性
  40. Log.d(TAG, "deltaY: " +deltaY + " scrollY: " + scrollY + " scrollRangeY: " + scrollRangeY
  41. + " maxOverScrollY: " + maxOverScrollY + " isTouchEvent: " + isTouchEvent);
  42. // 手指拉动 并且 是下拉
  43. if(isTouchEvent && deltaY < 0){
  44. // 把拉动的瞬时变化量的绝对值交给Header, 就可以实现放大效果
  45. if(mImage.getHeight() <= drawableHeight){
  46. int newHeight = (int) (mImage.getHeight() + Math.abs(deltaY / 3.0f));
  47. // 高度不超出图片最大高度时,才让其生效
  48. mImage.getLayoutParams().height = newHeight;
  49. mImage.requestLayout();
  50. }
  51. }
  52. return super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX,
  53. scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent);
  54. }
  55. @Override
  56. public boolean onTouchEvent(MotionEvent ev) {
  57. switch (ev.getAction()) {
  58. case MotionEvent.ACTION_UP:
  59. // 执行回弹动画, 方式一: 属性动画\值动画
  60. // 从当前高度mImage.getHeight(), 执行动画到原始高度mOriginalHeight
  61. final int startHeight = mImage.getHeight();
  62. final int endHeight = mOriginalHeight;
  63. // valueAnimator(startHeight, endHeight);
  64. // 执行回弹动画, 方式二: 自定义Animation
  65. ResetAnimation animation = new ResetAnimation(mImage, startHeight, endHeight);
  66. startAnimation(animation);
  67. break;
  68. }
  69. return super.onTouchEvent(ev);
  70. }
  71. private void valueAnimator(final int startHeight, final int endHeight) {
  72. ValueAnimator mValueAnim = ValueAnimator.ofInt(1);//不起作用,写几都行
  73. mValueAnim.addUpdateListener(new AnimatorUpdateListener() {
  74. @Override
  75. public void onAnimationUpdate(ValueAnimator mAnim) {
  76. float fraction = mAnim.getAnimatedFraction();
  77. // percent 0.0 -> 1.0
  78. Log.d(TAG, "fraction: " +fraction);
  79. Integer newHeight = evaluate(fraction, startHeight, endHeight);//固值器
  80. mImage.getLayoutParams().height = newHeight;//设置imageview高度
  81. mImage.requestLayout();
  82. }
  83. });
  84. mValueAnim.setInterpolator(new OvershootInterpolator());
  85. mValueAnim.setDuration(500);
  86. mValueAnim.start();
  87. }
  88. public Integer evaluate(float fraction, Integer startValue, Integer endValue) {
  89. int startInt = startValue;
  90. return (int)(startInt + fraction * (endValue - startInt));
  91. }
  92. }
ResetAnimation
  1. public class ResetAnimation extends Animation {
  2. private final ImageView mImage;
  3. private final int startHeight;
  4. private final int endHeight;
  5. public ResetAnimation(ImageView mImage, int startHeight, int endHeight) {
  6. this.mImage = mImage;
  7. this.startHeight = startHeight;
  8. this.endHeight = endHeight;
  9. setInterpolator(new OvershootInterpolator());
  10. //设置动画执行时长
  11. setDuration(500);
  12. }
  13. @Override
  14. protected void applyTransformation(float interpolatedTime, Transformation t) {
  15. // interpolatedTime 0.0f -> 1.0f
  16. Integer newHeight = evaluate(interpolatedTime, startHeight, endHeight);
  17. mImage.getLayoutParams().height = newHeight;//设置imageview高
  18. mImage.requestLayout();
  19. super.applyTransformation(interpolatedTime, t);
  20. }
  21. /**
  22. * 类型估值器
  23. * @param fraction
  24. * @param startValue
  25. * @param endValue
  26. * @return
  27. */
  28. public Integer evaluate(float fraction, Integer startValue, Integer endValue) {
  29. int startInt = startValue;
  30. return (int)(startInt + fraction * (endValue - startInt));
  31. }
  32. }
MainActivity
  1. public class MainActivity extends Activity {
  2. @Override
  3. protected void onCreate(Bundle savedInstanceState) {
  4. super.onCreate(savedInstanceState);
  5. setContentView(R.layout.activity_main);
  6. final MyListView mListView = (MyListView) findViewById(R.id.lv);
  7. mListView.setOverScrollMode(View.OVER_SCROLL_NEVER);
  8. // 加Header
  9. final View mHeaderView = View.inflate(MainActivity.this, R.layout.view_header, null);
  10. final ImageView mImage = (ImageView) mHeaderView.findViewById(R.id.iv);
  11. mListView.addHeaderView(mHeaderView);
  12. mHeaderView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
  13. @Override
  14. public void onGlobalLayout() {
  15. // 当布局填充结束之后, 此方法会被调用
  16. mListView.setParallaxImage(mImage);
  17. mHeaderView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
  18. }
  19. });
  20. // 填充数据
  21. mListView.setAdapter(new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_1, Cheeses.NAMES));
  22. }
  23. }





9.视差特效、回弹动画、overScrollBy

标签:

原文地址:http://www.cnblogs.com/liuyu0529/p/5041944.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!