自定義右拉刷新和下拉刷新的Recyclerview

package com.tencent.wcenter.ui.view; import android.animation.ObjectAnimator; import android.annotation.SuppressLint; import android.content.Context; import android.graphics.drawable.AnimationDrawable; import android.graphics.drawable.BitmapDrawable; import android.os.Handler; import android.os.Message; import android.util.AttributeSet; import android.util.Log; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.recyclerview.widget.RecyclerView; import com.tencent.wcenter.R; /** * @author kcyu * @date :2022/2/8 10:59 */ @SuppressLint("ViewConstructor") public class WTRecyclerView extends RecyclerView { private Context mContext; private static final int REFRESH_HEADER = 10086; private static final int FIRST = 1; private static final int TWO = 2; private static final int ONLY = 3; private static final int LAST = 4; private float mLastY = -1; private int mMeasuredHeight = -1; private float mLastX = -1; private int mMeasuredWidth = -1; private HeadViewHolder h; private boolean releaseToRefresh = false; private RefreshListener r; private AnimationDrawable drawable; private static final String TAG = WTRecyclerView.class.getSimpleName(); public WTRecyclerView(@NonNull Context context) { this(context,null); } public WTRecyclerView(@NonNull Context context, @Nullable AttributeSet attrs) { this(context, attrs,0); } public WTRecyclerView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); setAdapter(new AdapterWrapper(null)); this.mContext = context; } private class AdapterWrapper extends Adapter { private Adapter mAdapter; AdapterWrapper(Adapter adapter) { this.mAdapter = adapter; } @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { if (viewType == REFRESH_HEADER) { h = new HeadViewHolder(LayoutInflater.from(mContext) .inflate(R.layout.item_refresh_header_land, parent, false)); LayoutParams lp = new LayoutParams(0, ViewGroup.LayoutParams.MATCH_PARENT); h.itemView.setLayoutParams(lp); return h; } else if (viewType == FIRST){ return new FirstViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_recommend_first_land, parent, false)); }else if (viewType == TWO){ return new TwoViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_recommend_two_land, parent, false)); }else if (viewType == ONLY){ return new OnlyViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_recommend_only_land, parent, false)); }else{ return new LastViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_recommend_last_land, parent, false)); } } @Override public void onBindViewHolder(ViewHolder holder, int position) { } @Override public int getItemCount() { return 5; } @Override public int getItemViewType(int position) { // return position == 0 ? REFRESH_HEADER : 0; if (position == 0){ return REFRESH_HEADER; }else if (position == 1){ return FIRST; } else if (position == 2 ){ return TWO; }else if (position == 3){ return ONLY; } return LAST; } } public static class FirstViewHolder extends RecyclerView.ViewHolder{ public FirstViewHolder(@NonNull View itemView) { super(itemView); } } public static class TwoViewHolder extends RecyclerView.ViewHolder{ public TwoViewHolder(@NonNull View itemView) { super(itemView); } } public static class OnlyViewHolder extends RecyclerView.ViewHolder{ public OnlyViewHolder(@NonNull View itemView) { super(itemView); } } public static class LastViewHolder extends RecyclerView.ViewHolder{ TextView tv_last; public LastViewHolder(@NonNull View itemView) { super(itemView); tv_last= itemView.findViewById(R.id.tv_last); } } @SuppressLint("ClickableViewAccessibility") @Override public boolean onTouchEvent(MotionEvent e) { // if (mLastY == -1) { // mLastY = e.getRawY(); // } // if (mMeasuredHeight == -1) { // mMeasuredHeight = h.getMeasureHeight(); // } if (mLastX == -1) { mLastX = e.getRawX(); } if (mMeasuredWidth == -1) { mMeasuredWidth = h.getMeasureWidth(); } switch (e.getAction()) { case MotionEvent.ACTION_DOWN: break; case MotionEvent.ACTION_MOVE: // float deltaY = e.getRawY() - mLastY; // mLastY = e.getRawY(); // onMove(deltaY / 3); float deltaX = e.getRawX() - mLastX; Log.e(TAG, "onTouchEvent:e.getRawX()="+e.getRawX() +",mLastX= "+mLastX +", deltaX= "+deltaX); mLastX = e.getRawX(); onMove(deltaX /5); break; default: // mLastY = -1; // if (releaseToRefresh) refresh(); // else refreshComplete(); mLastX = -1; if (releaseToRefresh) refresh(); else refreshComplete(); break; } return super.onTouchEvent(e); } static class HeadViewHolder extends ViewHolder { public HeadViewHolder(View itemView) { super(itemView); } public int getMeasureHeight() { itemView.measure(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); return itemView.getMeasuredHeight(); } public int getMeasureWidth(){ itemView.measure(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); return itemView.getMeasuredWidth(); } public void setVisibleHeight(int height) { if (height < 0) height = 0; LayoutParams lp = (LayoutParams) itemView.getLayoutParams(); lp.height = height; itemView.setLayoutParams(lp); } public void setVisibleWidth(int width){ if (width < 0) width = 0; LayoutParams lp = (LayoutParams) itemView.getLayoutParams(); lp.width = width; itemView.setLayoutParams(lp); } public int getVisibleHeight() { LayoutParams lp = (LayoutParams) itemView.getLayoutParams(); return lp.height; } public int getVisibleWidth() { LayoutParams lp = (LayoutParams) itemView.getLayoutParams(); Log.e(TAG, "getVisibleWidth: lp.width="+lp.width ); return lp.width; } public ImageView getArrowImg() { return (ImageView) itemView.findViewById(R.id.iv_arrow); } public ImageView getRefreshImg() { return (ImageView) itemView.findViewById(R.id.iv_refresh); } public void changeText(String text) { TextView refreshTitle = (TextView) itemView.findViewById(R.id.tv_refresh_text); refreshTitle.setText(text); } } public void refreshComplete() { if (releaseToRefresh) { ImageView arrowImg = h.getArrowImg(); ObjectAnimator rotate = ObjectAnimator.ofFloat(arrowImg, "rotation", 180f, 0f); rotate.setDuration(300); rotate.start(); } releaseToRefresh = false; handler.sendEmptyMessageDelayed(1, 800); } @SuppressLint("HandlerLeak") Handler handler = new Handler() { @Override public void handleMessage(Message msg) { switch (msg.what) { case 1: // h.setVisibleHeight(0); h.setVisibleWidth(0); h.changeText("右拉刷新"); break; case 2: if (drawable != null) drawable.stop(); ImageView refreshImg = h.getRefreshImg(); ImageView arrowImg = h.getArrowImg(); arrowImg.setVisibility(VISIBLE); refreshImg.setVisibility(GONE); h.changeText("刷新完成"); refreshComplete(); break; default: break; } } }; public void onMove(float deltaY) { // h.setVisibleHeight((int) deltaY + h.getVisibleHeight()); // if (h.getVisibleHeight() > mMeasuredHeight) { // if (!releaseToRefresh) { // //旋轉箭頭 // ImageView arrowImg = h.getArrowImg(); // ObjectAnimator rotate = ObjectAnimator.ofFloat(arrowImg, "rotation", 0f, 180f); // h.changeText("釋放刷新"); // rotate.setDuration(300); // rotate.start(); // releaseToRefresh = true; // } // } h.setVisibleWidth((int) (deltaY+h.getVisibleWidth())); // h.setVisibleWidth(136); if (h.getVisibleWidth() > mMeasuredWidth) { Log.e(TAG, "onMove: h.getVisibleWidth()="+h.getVisibleWidth()+",mMeasuredWidth= " +mMeasuredWidth); if (!releaseToRefresh) { //旋轉箭頭 stopScroll(); ImageView arrowImg = h.getArrowImg(); ObjectAnimator rotate = ObjectAnimator.ofFloat(arrowImg, "rotation", 0f, 180f); h.changeText("釋放刷新"); rotate.setDuration(300); rotate.start(); releaseToRefresh = true; } } } private void refresh() { ImageView refreshImg = h.getRefreshImg(); ImageView arrowImg = h.getArrowImg(); arrowImg.setVisibility(GONE); refreshImg.setVisibility(VISIBLE); drawable = (AnimationDrawable) refreshImg.getDrawable(); drawable.start(); h.changeText("刷新中..."); //todo 數據請求完成後 handler.sendEmptyMessageDelayed(2,3000); } public void setPullToRefreshListener(RefreshListener r) { this.r = r; } public interface RefreshListener { void refresh(); } }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章