<Excerpt in index | 首页摘要>
RecyclerView实现下拉放大
<The rest of contents | 余下全文>
概述
经常有这样的产品需求。
某个界面顶部16 :9的大图
要求在顶部向下拽的时候缩放这个大图
来实现下拉放大的效果
效果图
思路
首先封装adapter给RecyclerView添加一个头部
然后封装一个我们自己的RecyclerView
重写onTouch()方法
这里重点说下。
最开始我的想法是利用属性动画来放大。
时候发现是可以放大。但是会造成header和item1 重叠。
所以这里横向放大用的属性动画
纵向放大是直接修改的header的height来实现的。
具体代码
先看Act:
1 2 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
1 2 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
1 2 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); }
}
|