<Excerpt in index | 首页摘要> 
RecyclerView实现下拉放大
<The rest of contents | 余下全文>  
概述
经常有这样的产品需求。
某个界面顶部16 :9的大图
要求在顶部向下拽的时候缩放这个大图
来实现下拉放大的效果
效果图

思路
首先封装adapter给RecyclerView添加一个头部
然后封装一个我们自己的RecyclerView
重写onTouch()方法
这里重点说下。
最开始我的想法是利用属性动画来放大。
时候发现是可以放大。但是会造成header和item1 重叠。
所以这里横向放大用的属性动画
纵向放大是直接修改的header的height来实现的。
具体代码
先看Act:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 
 | package com.gloomyer.pullzoomdemo;
 import android.os.Bundle;
 import android.support.v7.app.AppCompatActivity;
 import android.support.v7.widget.RecyclerView;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.TextView;
 
 public class MainActivity extends AppCompatActivity {
 
 private MyRecyclerView mRecyclerView;
 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 
 mRecyclerView = (MyRecyclerView) findViewById(R.id.mRecyclerView);
 mRecyclerView.setAdapter(new MyAdapter());
 }
 
 public int getWidht() {
 try {
 return getWindowManager().getDefaultDisplay().getWidth();
 } catch (Exception e) {
 }
 return 720;
 }
 
 class MyHolder extends RecyclerView.ViewHolder {
 TextView tv;
 
 public MyHolder(View itemView) {
 super(itemView);
 if (itemView instanceof TextView)
 tv = (TextView) itemView;
 
 }
 }
 
 private class MyAdapter extends RecyclerView.Adapter<MyHolder> {
 @Override
 public MyHolder onCreateViewHolder(ViewGroup parent, int viewType) {
 View view = LayoutInflater.from(parent.getContext())
 .inflate(
 viewType == 0
 ? android.R.layout.simple_list_item_1
 : R.layout.header, parent, false);
 if (viewType == 1) {
 view.getLayoutParams().height = (int) (getWidht() / 16.0f * 9);
 mRecyclerView.setZoomView(view);
 }
 return new MyHolder(view);
 }
 
 @Override
 public void onBindViewHolder(MyHolder holder, int position) {
 if (getItemViewType(position) == 0) {
 holder.tv.setText("pos:" + position);
 }
 }
 
 @Override
 public int getItemViewType(int position) {
 if (position == 0)
 return 1;
 return 0;
 }
 
 @Override
 public int getItemCount() {
 return 30;
 }
 }
 }
 
 
 | 
非常简单。
header就是一个imageview
| 12
 3
 4
 5
 6
 7
 
 | <?xml version="1.0" encoding="utf-8"?><ImageView xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_width="match_parent"
 android:layout_height="180dp"
 android:background="#fff"
 android:scaleType="fitXY"
 android:src="@drawable/pic" />
 
 | 
重点在我们封装的RecyclerView
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
 100
 101
 102
 103
 
 | package com.gloomyer.pullzoomdemo;
 import android.content.Context;
 import android.support.annotation.Nullable;
 import android.support.v7.widget.LinearLayoutManager;
 import android.support.v7.widget.RecyclerView;
 import android.util.AttributeSet;
 import android.util.Log;
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewConfiguration;
 
 
 
 
 
 public class MyRecyclerView extends RecyclerView {
 
 private static final String TAG = "MyRecyclerView";
 private LinearLayoutManager mLayoutManager;
 private int mTouchSlop;
 private View zoomView;
 
 public MyRecyclerView(Context context) {
 this(context, null);
 }
 
 public MyRecyclerView(Context context, @Nullable AttributeSet attrs) {
 this(context, attrs, 0);
 }
 
 public MyRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) {
 super(context, attrs, defStyle);
 mLayoutManager = new LinearLayoutManager(context);
 setLayoutManager(mLayoutManager);
 mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
 }
 
 public void setZoomView(View v) {
 this.zoomView = v;
 }
 
 private float downY;
 
 int countSize;
 
 int defaultHeight;
 
 @Override
 public boolean onTouchEvent(MotionEvent e) {
 if (countSize == 0
 && zoomView != null) {
 defaultHeight = zoomView.getHeight();
 countSize = getHeight() - zoomView.getHeight();
 zoomView.setPivotX(zoomView.getWidth() / 2);
 zoomView.setPivotY(0);
 zoomView.invalidate();
 Log.e(TAG, "height:" + countSize);
 }
 if (mLayoutManager.findFirstCompletelyVisibleItemPosition() == 0
 && zoomView != null) {
 if (e.getAction() == MotionEvent.ACTION_DOWN) {
 downY = e.getY();
 } else if (e.getAction() == MotionEvent.ACTION_MOVE) {
 
 float moveY = e.getY();
 int dY = (int) (moveY - downY);
 boolean isScroll = Math.abs(dY) > mTouchSlop;
 
 if (isScroll) {
 if (dY > 0) {
 
 Log.i(TAG, "xxxx:" + (dY - mTouchSlop));
 
 float scroll = (dY - mTouchSlop) * 0.8f / countSize;
 scroll *= 1.0;
 scroll += 1;
 
 zoomView.setScaleX(scroll);
 
 zoomView.getLayoutParams().height = (int) (defaultHeight * scroll);
 
 if (getAdapter() != null)
 getAdapter().notifyDataSetChanged();
 return true;
 }
 }
 } else if (e.getAction() == MotionEvent.ACTION_UP
 || e.getAction() == MotionEvent.ACTION_CANCEL) {
 
 zoomView.setScaleY(1);
 zoomView.getLayoutParams().height = defaultHeight;
 if (getAdapter() != null)
 getAdapter().notifyDataSetChanged();
 invalidate();
 }
 }
 return super.onTouchEvent(e);
 }
 
 
 }
 
 
 |