Android自定义实现淘宝下拉刷新效果

概述

目前下拉刷新的样式是多饰多样,今天我们一起来自定义淘宝下拉刷新,其实淘宝下拉刷新比较的简单就是一个圆环和一个小箭头的显示和隐藏,那么先看看我们的实现的效果。

是不是和淘宝有点像呢?那么现在我们来看看如何实现这个效果。我们这里为了省事,提供了2张照片  第一是“随时随地,想淘就淘”的照片,第二种就是小箭头照片,这里就自己画了,主要就是实现那个圆弧的绘制和旋转动画了。首先说这里的下拉刷新我用的是比较有名的 https://github.com/chrisbanes/Android-PullToRefresh 这个大家肯定很熟悉了,这里我修改了这个库可以自定义头部和底部。

步骤:

1、自定义一个view。(包含圆弧的绘制和箭头的显示和隐藏)
2、自定义头部。

1)、创建attrs文件

<declare-styleable name="TaoBaoView">
    <attr name="ringProgressColor" format="color" />
    <attr name="ringWidth" format="dimension" />
    <attr name="ringImage" format="reference" />
    <attr name="ringmax" format="integer" />
  </declare-styleable>

2、创建一个类 TaoBaoView.class

public class TaoBaoView extends View{ 

  //圆环进度颜色
  private int ringProgressColor; 

  //圆环的宽度
  private float ringWidth; 

  //最大值
  private int ringMax; 

  //中间的icon
  private Bitmap ringImage; 

  //中间X坐标
  private int centerX; 

  //中间Y坐标
  private int centerY; 

  //画笔
  private Paint mPaint; 

  //View宽度
  private int width; 

  //View高度
  private int height; 

  //进度
  private int progress; 

  //半径
  private int radius; 

  //是否显示图标
  private boolean isShowIcon=true; 

  public TaoBaoView(Context context) {
    this(context,null);
  } 

  public TaoBaoView(Context context, AttributeSet attrs) {
    this(context, attrs,0);
  } 

  public TaoBaoView(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    TypedArray typedArray=context.obtainStyledAttributes(attrs, R.styleable.TaoBaoView);
    ringProgressColor=typedArray.getColor(R.styleable.TaoBaoView_ringProgressColor, Color.GRAY);
    ringWidth=typedArray.getDimension(R.styleable.TaoBaoView_ringWidth, 5);
    ringMax=typedArray.getInteger(R.styleable.TaoBaoView_ringmax, 50);
    ringImage= BitmapFactory.decodeResource(getResources(),
        typedArray.getResourceId(R.styleable.TaoBaoView_ringImage,R.mipmap.jiantou));
    init(); 

  } 

  private void init() {
    mPaint=new Paint();
  } 

  @Override
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec); 

    int widthMode=MeasureSpec.getMode(widthMeasureSpec);
    int widthSize=MeasureSpec.getSize(widthMeasureSpec);
    int heightMode=MeasureSpec.getMode(heightMeasureSpec);
    int heightSize=MeasureSpec.getSize(heightMeasureSpec); 

    if(widthMode==MeasureSpec.AT_MOST)width=dp2px(30);
    else width=widthSize;
    if(heightMode==MeasureSpec.AT_MOST)height=dp2px(30);
    else height=heightSize;
    setMeasuredDimension(width,height);
  } 

  @Override
  protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
    super.onLayout(changed, left, top, right, bottom);
    //获取中心点的位置
    centerX=getWidth()/2;
    centerY=getHeight()/2;
    radius=(int) (centerX - ringWidth / 2);
  } 

  @Override
  protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);
    //确定View的宽高
    width = w;
    height = h;
  } 

  @Override
  public void draw(Canvas canvas) {
    super.draw(canvas); 

    drawProgress(canvas);
    drawImage(canvas);
  } 

  /**
   * 绘制图片
   * @param canvas
   */
  private void drawImage(Canvas canvas) {
    if(isShowIcon)
    canvas.drawBitmap(ringImage,centerX-ringImage.getWidth()/2,centerY-ringImage.getHeight()/2,mPaint);
  } 

  /**
   * 绘制进度条
   * @param canvas
   */
  private void drawProgress(Canvas canvas) { 

    mPaint.setAntiAlias(true);
    mPaint.setColor(ringProgressColor);
    mPaint.setStrokeWidth(ringWidth);
    //设置画笔样式
    mPaint.setStyle(Paint.Style.STROKE);
    RectF rectF=new RectF(centerX-radius,centerY-radius,centerX+radius,centerY+radius);
    //绘制圆弧
    canvas.drawArc(rectF,-110,-360*progress/ringMax,false,mPaint);
  } 

  /**
   * dp转px
   * @param dp
   * @return
   */
  public int dp2px(int dp){
    float density = getContext().getResources().getDisplayMetrics().density;
    return (int) (dp * density + 0.5f);
  } 

  /**
   * 设置进度
   * @param progress
   */
  public synchronized void setProgress(int progress){
    if(progress<0){
      progress=0;
    }
    if(progress>=ringMax){
      progress=ringMax;
    }
    this.progress=progress;
    postInvalidate();
  } 

  /**
   * 设置是否显示图标
   * @param isShow
   */
  public synchronized void setIsShowIcon(boolean isShow){
    this.isShowIcon=isShow;
  }
}

3、创建一个headerLayout  下拉刷新头部

public class HeaderLayout extends LoadingLayoutBase { 

  private Context mContext;
  private RotateAnimation refreshingAnimation;
  private TextView ring_refresh_status;
  private TaoBaoView mTaoBaoView;
  private LinearLayout header_base;
  private LinearLayout header_layout; 

  public HeaderLayout(Context context) {
    this(context, PullToRefreshBase.Mode.PULL_FROM_START);
  } 

  public HeaderLayout(Context context, PullToRefreshBase.Mode mode) {
    super(context);
    init(context,mode);
  } 

  private void init(Context mContext,PullToRefreshBase.Mode mode) {
    this.mContext=mContext;
    LayoutInflater.from(mContext).inflate(R.layout.taobao_view, this);
    header_base=(LinearLayout)findViewById(R.id.header_base);
    header_layout=(LinearLayout)findViewById(R.id.refresh_header_content);
    mTaoBaoView=(TaoBaoView)findViewById(R.id.taobao_view);
    ring_refresh_status=(TextView)findViewById(R.id.taobao_tv);
    refreshingAnimation = (RotateAnimation) AnimationUtils.loadAnimation(mContext, R.anim.rotating);
    LinearInterpolator lir = new LinearInterpolator();
    refreshingAnimation.setInterpolator(lir);
    mTaoBaoView.setProgress(90);
    LayoutParams lp = (LayoutParams) header_base.getLayoutParams();
    lp.gravity = mode == PullToRefreshBase.Mode.PULL_FROM_END ? Gravity.TOP : Gravity.BOTTOM;
    reset();
  } 

  @Override
  public int getContentSize() {
    return header_layout.getHeight();
  } 

  /**
   * 下拉可以刷新
   */
  @Override
  public void pullToRefresh() {
    ring_refresh_status.setText("下拉刷新");
    mTaoBaoView.setIsShowIcon(true);
  } 

  /**
   * 松开后刷新
   */
  @Override
  public void releaseToRefresh() {
    ring_refresh_status.setText("松开刷新");
    mTaoBaoView.setIsShowIcon(false);
  } 

  /**
   * 下拉中
   * @param scaleOfLayout scaleOfLayout
   */
  @Override
  public void onPull(float scaleOfLayout) {
    scaleOfLayout = scaleOfLayout > 1.0f ? 1.0f : scaleOfLayout;
    int progress=(int) ((scaleOfLayout)*100);
    mTaoBaoView.setProgress(progress>90?90:progress); 

  } 

  /**
   * 正在刷新
   */
  @Override
  public void refreshing() {
    mTaoBaoView.setIsShowIcon(false);
    ring_refresh_status.setText("正在刷新");
    mTaoBaoView.startAnimation(refreshingAnimation);
  } 

  @Override
  public void reset() {
    mTaoBaoView.clearAnimation();
  } 

  @Override
  public void setPullLabel(CharSequence pullLabel) { 

  } 

  @Override
  public void setRefreshingLabel(CharSequence refreshingLabel) { 

  } 

  @Override
  public void setReleaseLabel(CharSequence releaseLabel) { 

  }
}

4、在mainactivity中:

mPullToRefreshListView=(PullToRefreshListView)findViewById(R.id.list);
mPullToRefreshListView.setHeaderLayout(new HeaderLayout(this));

附上github:https://github.com/dalong982242260/TaoBaoRefresh2

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Android仿美团淘宝实现多级下拉列表菜单功能

    我们在常用的电商或者旅游APP中,例如美团,手机淘宝等等,都能够看的到有那种下拉式的二级列表菜单.具体如图所示: 上面两张图就是美团的一个二级列表菜单的一个展示.我相信很多人都想开发一个跟它一样的功能放到自己的APP中.好,接下来我们就开始动手,解决它. 1.结构分析 首先,我们给出这个下拉菜单需要的组建.我们用线框图来分析. 1)如上图所示,最外围的是一个Activity,顶部包含了一个View的容器,这个容器主要是装载ToggleButton来实现诸如美团里面的"美食,全城,理我最近,刷选&

  • Android自定义实现淘宝下拉刷新效果

    概述 目前下拉刷新的样式是多饰多样,今天我们一起来自定义淘宝下拉刷新,其实淘宝下拉刷新比较的简单就是一个圆环和一个小箭头的显示和隐藏,那么先看看我们的实现的效果. 是不是和淘宝有点像呢?那么现在我们来看看如何实现这个效果.我们这里为了省事,提供了2张照片  第一是"随时随地,想淘就淘"的照片,第二种就是小箭头照片,这里就自己画了,主要就是实现那个圆弧的绘制和旋转动画了.首先说这里的下拉刷新我用的是比较有名的 https://github.com/chrisbanes/Android-P

  • 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://sche

  • Android仿京东、天猫下拉刷新效果

    说到下拉刷新,相信大家都不陌生,现在基本上每个项目都会用到.我们公司的项目一直都是使用SwipeRefreshLayout,官方的Material Design风格,好用少Bug.现在下拉刷新大概有下面几种实现方式:一种是直接包在ListView或者RecyclerView的头部,有的则是像SwipeRefreshLayout一样,包在视图的最外层,个人建议使用包在最外层的做法,可拓展性比较强.下面用包在最外层的方法实现京东和天猫的下拉刷新. 1.使用框架Android-Ultra-Pull-T

  • Android仿百度外卖自定义下拉刷新效果

    现如今的APP各式各样,同样也带来了各种需求,一个下拉刷新都能玩出花样了,前两天订饭的时候不经意间看到了"百度外卖"的下拉刷新,今天的主题就是它–自定义下拉刷新动画. 看一下实现效果吧: 动画 我们先来看看Android中的动画吧: Android中的动画分为三种: Tween动画,这一类的动画提供了旋转.平移.缩放等效果. Alpha – 淡入淡出 Scale – 缩放效果 Roate – 旋转效果 Translate – 平移效果 Frame动画(帧动画),这一类动画可以创建一个D

  • Android实现RecyclerView下拉刷新效果

    本文为大家分享了Android实现RecyclerView下拉刷新效果的具体代码,供大家参考,具体内容如下 思路 RealPullRefreshView继承了一个LinearLayout 里面放置了一个刷新头布局,将其margin_top设置为负的刷新头的高度的 再添加一个RecyclerView 触摸事件分发机制,当在特定条件下让RealPullRefreshView拦截触摸事件,否则的话,不拦截,让RecyclerView自己去处理触摸事件 在手指下拉时,定义好不同的状态STATE,在不同状

  • Android使用PullToRefresh实现上拉加载和下拉刷新效果的代码

    在没给大家介绍正文之前,先给大家介绍展示下运行图,如果大家感觉还不错,请继续往下阅读: 相关阅读:分享Android中pullToRefresh的使用心得 项目已同步至:https://github.com/nanchen2251/pullToRefreshDemo 简单使用详情: 1)studio可以直接在app的module设置中直接进行搜索,但是有-的必须添上,而不能用空格代替,为了更加了解这个东西,我还是推荐大家去这里看看,奉上网址: https://github.com/chrisba

  • Android中使用RecyclerView实现下拉刷新和上拉加载

    推荐阅读:使用RecyclerView添加Header和Footer的方法                       RecyclerView的使用之HelloWorld RecyclerView 是Android L版本中新添加的一个用来取代ListView的SDK,它的灵活性与可替代性比listview更好.本文给大家介绍如何为RecyclerView添加下拉刷新和上拉加载,过去在ListView当中添加下拉刷新和上拉加载是非常方便的利用addHeaderView和addFooterVie

  • Android程序开发之Listview下拉刷新上拉(滑动分页)加载更多

    最近做的类似于微博的项目中,有个Android功能要使用到listview的向下拉刷新来刷新最新消息,向上拉刷新(滑动分页)来加载更多. 新浪微博就是使用这种方式的典型. 当用户从网络上读取微博的时候,如果一下子全部加载用户未读的微博这将耗费比较长的时间,造成不好的用户体验,同时一屏的内容也不足以显示如此多的内容.这时候,我们就需要用到另一个功能,那就是listview的分页了,其实这个分页可以做成客户端的分页,也可以做成服务器端的分页(点击加载时,从服务器对应的加载第N页就好了!!!).通过分

  • Android使用PullToRefresh完成ListView下拉刷新和左滑删除功能

    ListView下刷新刷功能相信从事Android开发的猿友们并不陌生,包括现在Google亲儿子SwipeRefreshLayout实现效果在一些APP上也能看见(不过个人不喜欢官方的刷新效果).本文就带领一些刚入门android的朋友或者一起爱分享的朋友来简单的实现ListView的下拉刷新和左滑删除效果. 一.本文主要内容: 使用PullToRefresh完成ListView下拉.上拉刷新: 扩展PullToRefresh完美的实现ListView左滑删除效果: 注意:本文中的PullTo

  • Python抓取淘宝下拉框关键词的方法

    本文实例讲述了Python抓取淘宝下拉框关键词的方法.分享给大家供大家参考.具体如下: import urllib2,re for key in open('key.txt'): do = "http://suggest.taobao.com/sug?code=utf-8&q=%s" % key.rstrip() _re = re.findall('\[\"(.*?)\",\".*?\"\]',urllib2.urlopen(do).re

随机推荐