国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android自定義實現頂部粘性下拉刷新效果

2019-10-22 18:25:30
字體:
來源:轉載
供稿:網友

本文實例為大家分享了Android實現頂部粘性下拉刷新效果的具體代碼,供大家參考,具體內容如下

學習:視頻地址

Android,頂部粘性,下拉刷新

activity_view_mv代碼

<?xml version="1.0" encoding="utf-8"?><RelativeLayout  xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/rl_view"  android:layout_width="match_parent"  android:layout_height="wrap_content" >  <trunk.doi.base.ui.activity.test.TouchPullView   android:id="@+id/cs_view"   android:layout_width="match_parent"   android:layout_height="wrap_content"   app:pColor="@color/cff3e19"   app:pContentDrawable="@drawable/shape_circle"   app:pContentDrawableMargin="2dp"   app:pDragHeight="100dp"   app:pTangentAngle="110"   app:pRadius="15dp"   app:pTargetGravityHeight="4dp"   app:pTargetWidth="200dp"   />  <trunk.doi.base.ui.activity.test.TestViewBezer   android:layout_width="match_parent"   android:visibility="gone"   android:layout_height="wrap_content"   /></RelativeLayout>

ViewMvActivity代碼

import android.os.Bundle;import android.support.annotation.Nullable;import android.view.MotionEvent;import android.view.View;import android.widget.RelativeLayout;import butterknife.BindView;import trunk.doi.base.R;import trunk.doi.base.base.BaseActivity;public class ViewMvActivity extends BaseActivity { @BindView(R.id.cs_view) TouchPullView csView; @BindView(R.id.rl_view) RelativeLayout rl_view; private float mTouchStartY; private static final float TOUCH_MOVE_MAX_Y=600; @Override protected int initLayoutId() {  return R.layout.activity_view_mv; } @Override protected void initView(@Nullable Bundle savedInstanceState) {  rl_view.setOnTouchListener(new View.OnTouchListener() {   @Override   public boolean onTouch(View v, MotionEvent event) {    int action=event.getActionMasked();    switch (action){     case MotionEvent.ACTION_DOWN:      mTouchStartY=event.getY();      return true;     case MotionEvent.ACTION_MOVE:      float y=event.getY();      if(y>=mTouchStartY){       float moveSize= y-mTouchStartY;       float progress=moveSize>=TOUCH_MOVE_MAX_Y?1:moveSize/TOUCH_MOVE_MAX_Y;       csView.setProgress(progress);      }      return true;     case MotionEvent.ACTION_UP:      csView.release();      return true;     default:      break;    }    return false;   }  }); } @Override protected void setListener() { } @Override protected void initData() { }}

TouchPullView代碼

import android.animation.ValueAnimator;import android.content.Context;import android.content.res.TypedArray;import android.graphics.Canvas;import android.graphics.Paint;import android.graphics.Path;import android.graphics.drawable.Drawable;import android.os.Build;import android.support.annotation.Nullable;import android.support.annotation.RequiresApi;import android.support.v4.view.animation.PathInterpolatorCompat;import android.util.AttributeSet;import android.util.Log;import android.view.View;import android.view.animation.DecelerateInterpolator;import android.view.animation.Interpolator;import trunk.doi.base.R;/** * 作者:Mr.Lee on 2017-9-27 11:57 * 郵箱:569932357@qq.com */public class TouchPullView extends View { //圓的畫筆 private Paint mCirclePaint; //圓的半徑 private int mCircleRadius=50; private float mCirclePointX; private float mCirclePointY; private float mProgress; //可拖拽高度 private int mDragHeigh=800; //目標寬度 private int mTargetWidth=400; //貝塞爾曲線 private Path mPath=new Path(); private Paint mPathPaint; //重心點最終高度,決定控制點的Y坐標 private int mTargetGravityHeight=10; //角度變換 0-135 private int mTangentAngle=100; private Interpolator mProgressInterpolator=new DecelerateInterpolator(); private Interpolator mTanentAngleInterpolator; private Drawable mContent=null; private int mContentMargin=0; public TouchPullView(Context context) {  super(context);  init(null); } public TouchPullView(Context context, @Nullable AttributeSet attrs) {  super(context, attrs);  init(attrs); } public TouchPullView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {  super(context, attrs, defStyleAttr);  init(attrs); } @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) public TouchPullView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {  super(context, attrs, defStyleAttr, defStyleRes);  init(attrs); } /**  * 初始化  */ private void init(AttributeSet attrs){  final Context context=getContext();  TypedArray array=context.obtainStyledAttributes(attrs, R.styleable.TouchPullView,0,0);  int color=array.getColor(R.styleable.TouchPullView_pColor,0x20000000);  mCircleRadius=(int)array.getDimension(R.styleable.TouchPullView_pRadius,mCircleRadius);  mDragHeigh=array.getDimensionPixelOffset(R.styleable.TouchPullView_pDragHeight,mDragHeigh);  mTangentAngle=array.getInteger(R.styleable.TouchPullView_pTangentAngle,mTangentAngle);  mTargetWidth=array.getDimensionPixelOffset(R.styleable.TouchPullView_pDragHeight,mTargetWidth);  mTargetGravityHeight=array.getDimensionPixelOffset(R.styleable.TouchPullView_pTargetGravityHeight,mTargetGravityHeight);  mContent=array.getDrawable(R.styleable.TouchPullView_pContentDrawable);  mContentMargin=array.getDimensionPixelOffset(R.styleable.TouchPullView_pContentDrawableMargin,0);  array.recycle();  Paint p=new Paint(Paint.ANTI_ALIAS_FLAG);  //抗鋸齒  p.setAntiAlias(true);  //防抖動  p.setDither(true);  //填充方式  p.setStyle(Paint.Style.FILL);  p.setColor(color);  mCirclePaint=p;  //初始化路徑部分畫筆  p=new Paint(Paint.ANTI_ALIAS_FLAG);  //抗鋸齒  p.setAntiAlias(true);  //防抖動  p.setDither(true);  //填充方式  p.setStyle(Paint.Style.FILL);  p.setColor(color);  mPathPaint=p;  //切角路徑插值器  mTanentAngleInterpolator= PathInterpolatorCompat.create(    (mCircleRadius*2.0f)/mDragHeigh,    90.0f/mTangentAngle  ); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) {  super.onSizeChanged(w, h, oldw, oldh);  updatePathLayout(); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {//  super.onMeasure(widthMeasureSpec, heightMeasureSpec);  int widthMode=MeasureSpec.getMode(widthMeasureSpec);  int width=MeasureSpec.getSize(widthMeasureSpec);  int heighMode=MeasureSpec.getMode(heightMeasureSpec);  int heigh=MeasureSpec.getSize(heightMeasureSpec);  int iHeigh=(int)((mDragHeigh*mProgress+0.5)+ 2*mCircleRadius+getPaddingTop()+getPaddingBottom());  int iWidth=2*mCircleRadius+getPaddingLeft()+getPaddingRight();  int measureWidth,measureHeigh;  if(widthMode==MeasureSpec.EXACTLY){   measureWidth=width;  }else if(widthMode==MeasureSpec.AT_MOST){   measureWidth=Math.min(iWidth,width);  }else{   measureWidth=iWidth;  }  if(heighMode==MeasureSpec.EXACTLY){   measureHeigh=heigh;  }else if(heighMode==MeasureSpec.AT_MOST){   measureHeigh=Math.min(iHeigh,heigh);  }else{   measureHeigh=iHeigh;  }  setMeasuredDimension(measureWidth,measureHeigh); } @Override protected void onDraw(Canvas canvas) {  super.onDraw(canvas);  int count=canvas.save();  float tranX=(getWidth()-getValueByLine(getWidth(),mTargetWidth,mProgress))/2;  canvas.translate(tranX,0);  canvas.drawPath(mPath,mPathPaint);  //畫圓  canvas.drawCircle(mCirclePointX,mCirclePointY,mCircleRadius,mCirclePaint);  Drawable drawable=mContent;  if(drawable!=null){   canvas.save();   //剪切矩形區域   canvas.clipRect(drawable.getBounds());   //繪制   drawable.draw(canvas);   canvas.restore();  }  canvas.restoreToCount(count); } /**  * 設置進度  * @param progress  */ public void setProgress(float progress){  Log.e("TAG","progress="+progress);  mProgress=progress;  //重新請求測量  requestLayout(); } private void updatePathLayout(){  final float progress=mProgressInterpolator.getInterpolation(mProgress);  //獲取可繪制區域高度寬度  final float w=getValueByLine(getWidth(),mTargetWidth,mProgress);  final float h=getValueByLine(0,mDragHeigh,mProgress);  //X對稱軸的參數,圓的圓心X  final float cPointX=w/2;  //圓的半徑  final float cRadius=mCircleRadius;  //圓的圓心Y坐標  final float cPointY =h-cRadius;  //控制點結束Y坐標  final float endControlY=mTargetGravityHeight;  mCirclePointX=cPointX;  mCirclePointY= cPointY;  final Path path=mPath;  //重置  path.reset();  path.moveTo(0,0);  //左邊部分的結束點和控制點  float lEndPointX,lEndPointY;  float lControlPointX,lControlPointY;  //角度轉弧度  float angle=mTangentAngle*mTanentAngleInterpolator.getInterpolation(progress);  double radian=Math.toRadians(angle);  float x=(float) (Math.sin(radian)*cRadius);  float y=(float) (Math.cos(radian)*cRadius);  lEndPointX=cPointX-x;  lEndPointY= cPointY +y;  //控制點y坐標變化  lControlPointY=getValueByLine(0,endControlY,progress);  //控制點與結束定之前的高度  float tHeigh=lEndPointY-lControlPointY;  //控制點與x坐標的距離  float tWidth= (float) (tHeigh/Math.tan(radian));  lControlPointX=lEndPointX-tWidth;  //左邊貝塞爾曲線  path.quadTo(lControlPointX,lControlPointY,lEndPointX,lEndPointY);  //連接到右邊  path.lineTo(cPointX+(cPointX-lEndPointX),lEndPointY);  //右邊貝塞爾曲線  path.quadTo(cPointX+cPointX-lControlPointX,lControlPointY,w,0);  //更新內容部分Drawable  updateContentLayout(cPointX,cPointY,cRadius); } /**  * 對內容部分進行測量并設置  * @param cx  * @param cy  * @param radius  */ private void updateContentLayout(float cx,float cy,float radius){  Drawable drawable=mContent;  if(drawable!=null){   int margin=mContentMargin;   int l=(int)(cx-radius+margin);   int r=(int)(cx+radius-margin);   int t=(int)(cy-radius+margin);   int b=(int)(cy+radius-margin);   drawable.setBounds(l,t,r,b);  } } //釋放動畫 private ValueAnimator valueAnimator; /**  * 添加釋放動作  */ public void release(){  if(valueAnimator==null){   ValueAnimator animator=ValueAnimator.ofFloat(mProgress,0f);   animator.setInterpolator(new DecelerateInterpolator());   animator.setDuration(400);   animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {    @Override    public void onAnimationUpdate(ValueAnimator animation) {     Object val=animation.getAnimatedValue();     if(val instanceof Float){      setProgress((Float) val);     }    }   });   valueAnimator=animator;  }else{   valueAnimator.cancel();   valueAnimator.setFloatValues(mProgress,0f);  }  valueAnimator.start(); } /**  * 獲取當前值  * @param start  * @param end  * @param progress  * @return  */ private float getValueByLine(float start,float end ,float progress){  return start+(end-start)*progress; } }

TestViewBezer代碼

import android.content.Context;import android.graphics.Canvas;import android.graphics.Paint;import android.graphics.Path;import android.os.Build;import android.support.annotation.Nullable;import android.support.annotation.RequiresApi;import android.util.AttributeSet;import android.view.View;/** * 作者:Mr.Lee on 2017-9-27 18:08 * 郵箱:569932357@qq.com */public class TestViewBezer extends View { private Paint mPaint=new Paint(Paint.ANTI_ALIAS_FLAG); private Path mPath=new Path(); public TestViewBezer(Context context) {  super(context);  init(); } public TestViewBezer(Context context, @Nullable AttributeSet attrs) {  super(context, attrs);  init(); } public TestViewBezer(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {  super(context, attrs, defStyleAttr);  init(); } @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) public TestViewBezer(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {  super(context, attrs, defStyleAttr, defStyleRes);  init(); } private void init(){  Paint paint=mPaint;  paint.setAntiAlias(true);  paint.setDither(true);  mPaint.setColor(0xff000000);  paint.setStyle(Paint.Style.STROKE);  paint.setStrokeWidth(10);  Path path=mPath;  path.moveTo(100,100);  path.lineTo(400,400);  path.quadTo(600,100,800,400);  path.moveTo(400,800);  path.cubicTo(500,600,700,1200,800,800); } @Override protected void onDraw(Canvas canvas) {  super.onDraw(canvas);  canvas.drawPath(mPath,mPaint);  canvas.drawPoint(600,100,mPaint);  canvas.drawPoint(500,600,mPaint);  canvas.drawPoint(700,1200,mPaint); }}

attr_pull.xml代碼

 <declare-styleable name="TouchPullView">  <attr name="pColor" format="color" />  <attr name="pRadius" format="dimension" />  <attr name="pDragHeight" format="dimension"></attr>  <attr name="pTangentAngle" format="integer" />  <attr name="pTargetWidth" format="dimension" />  <attr name="pTargetGravityHeight" format="dimension" />  <attr name="pContentDrawable" format="reference" />  <attr name="pContentDrawableMargin" format="dimension" /> </declare-styleable>

shape_circle代碼

<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval" > <solid android:color="#fff" /></shape>

 

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VEVB武林網。


注:相關教程知識閱讀請移步到Android開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 丁青县| 遵义县| 香格里拉县| 教育| 宁国市| 昌江| 阳信县| 来安县| 壤塘县| 海门市| 上饶市| 佳木斯市| 峡江县| 成安县| 伊春市| 南城县| 汉阴县| 巴青县| 衡阳县| 莱西市| 宽城| 阿坝县| 和田县| 安平县| 永兴县| 会同县| 乐陵市| 霞浦县| 三明市| 绥中县| 乌拉特后旗| 泗洪县| 丰县| 崇礼县| 保德县| 洛阳市| 石门县| 渝中区| 探索| 贵南县| 原平市|