Android自定義實現淘寶下拉刷新效果
概述
目前下拉刷新的樣式是多飾多樣,今天我們一起來自定義淘寶下拉刷新,其實淘寶下拉刷新比較的簡單就是一個圓環(huán)和一個小箭頭的顯示和隱藏,那么先看看我們的實現的效果。

是不是和淘寶有點像呢?那么現在我們來看看如何實現這個效果。我們這里為了省事,提供了2張照片 第一是“隨時隨地,想淘就淘”的照片,第二種就是小箭頭照片,這里就自己畫了,主要就是實現那個圓弧的繪制和旋轉動畫了。首先說這里的下拉刷新我用的是比較有名的 https://github.com/chrisbanes/Android-PullToRefresh 這個大家肯定很熟悉了,這里我修改了這個庫可以自定義頭部和底部。
步驟:
1、自定義一個view。(包含圓弧的繪制和箭頭的顯示和隱藏)
2、自定義頭部。
1)、創(chuàng)建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、創(chuàng)建一個類 TaoBaoView.class
public class TaoBaoView extends View{
//圓環(huán)進度顏色
private int ringProgressColor;
//圓環(huán)的寬度
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、創(chuàng)建一個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
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
Android RadarView雷達圖(蜘蛛網圖)的實現代碼
這篇文章主要介紹了Android RadarView雷達圖(蜘蛛網圖)的實現代碼,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-03-03
淺談Android Studio 3.0 工具新特性的使用 Android Profiler 、Device File
這篇文章主要介紹了淺談Android Studio 3.0 工具新特性的使用 Android Profiler 、Device File Explorer的相關資料,需要的朋友可以參考下2017-11-11

