您的位置:首页 > 移动开发 > Android开发

android自定义进度条

2017-06-03 09:37 148 查看
         好多天没写博客了,最近一直在忙手环的项目,当前项目是一个智能手环的项目,由于项目比较急,所以硬件部分是外包的,我们只负责软件的部分,这周也一直花费主要的心思在研究这些东西上面了,后面我会做一些蓝牙方面的东西,也会把他共享出来,这周做了蛮多的东西,项目上也做了很多的动画特效,今天拿一个比较常规,也比较常见的特效拿出来说下,也分析下类似与这种效果该怎么去写。

      首先看下UI给我发过来的效果图。



很明显这是一个fragment中一个listview的进度条,这个时候首先第一个就想到的是progressbar,但是我们在做项目的时候不能只是想到把这个界面给做出来,有时候项目可能不需要我们做一些特效,但是作为android开发的人员,要做的不仅仅是这样,应该尽量的把界面做的好看,需要加入一个动画。下面是我效果做完后的截图。



看起来效果不太好,由于手机在显示到电脑上的时候有点卡,但是效果已经出来了,第一步就是把背景弄出来,这个背景首先肯定是可以自定义出来的,但是有个更简单的办法,不要忘记了android有个非常强大的背景功能,像这种左边是方形的右边的圆形的,一个shape就搞定了。

下面shape的代码

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#D3D3D3" />
<corners android:topLeftRadius="0dp"
android:topRightRadius="15dp"
android:bottomRightRadius="15dp"
android:bottomLeftRadius="0dp"/>
<stroke android:width="2dp
4000
" android:color="#D3D3D3" />
</shape>


下面是每个listview中item的代码

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">

<com.eben.zhukeyunfu.Activity.view.ProgressView
android:background="@drawable/cycle_squal_biankuang"
android:id="@+id/progress"
android:layout_marginTop="10dp"
android:layout_marginRight="10dp"
android:layout_marginBottom="10dp"
android:layout_width="match_parent"
android:layout_height="30dp"/>
<TextView
android:id="@+id/number"
android:layout_marginLeft="10dp"
android:layout_gravity="center_vertical"
android:textColor="@color/white"
android:text="1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>

<TextView
android:id="@+id/number2"
android:layout_marginLeft="50dp"
android:layout_gravity="center_vertical"
android:textColor="@color/white"
android:text="12′19″"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>

<TextView
android:id="@+id/number3"
android:layout_marginRight="20dp"
android:layout_gravity="center_vertical|right"
android:textColor="@color/white"
android:text="30′19″"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>

</FrameLayout>


当然这个item上的文字也是不需要绘制的,直接framelayout包裹下就行了。

listview的代码

<ListView
android:divider="@null"
android:id="@+id/sport_list"
android:layout_width="match_parent"
android:layout_height="match_parent">

</ListView>


接下来就是自定义progressView的代码:

package com.eben.zhukeyunfu.Activity.view;

/*
*  @项目名:  Zhukeyunfu
*  @包名:    com.eben.zhukeyunfu.Activity.view
*  @文件名:   ProgressView
*  @创建者:   huhai
*  @创建时间:  2017/5/25 17:36
*  @描述:    TODO
*/

import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

import com.eben.zhukeyunfu.Activity.utils.WindowUtils;
import com.eben.zhukeyunfu.R;

public class ProgressView extends View {
private String TAG="ProgressView";

/**分段颜色*/
private static final int[] SECTION_COLORS = {Color.GREEN, Color.YELLOW, Color.RED};
/**进度条最大值*/
private float maxCount;
/**进度条当前值*/
private float currentCount;
/**画笔*/
private Paint mPaint;
private int   mWidth,mHeight;
private int mViewWidth;
private int mViewHeight;
private Rect 
e48e
mRect;
private int mScreenWidth;
private RectF mRectf;
private float progresscount;

public ProgressView(Context context, AttributeSet attrs,
int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView(context);
}

public ProgressView(Context context, AttributeSet attrs) {
super(context, attrs);
initView(context);
mScreenWidth = WindowUtils.screenWidth(context);
mRect = new Rect(0, 0,(int)(progresscount/maxCount)*mViewWidth, mViewHeight);

}
//开启动画效果
private void initanimator() {
ObjectAnimator animator = ObjectAnimator.ofFloat(null, "", 0, currentCount);
animator.setDuration(2000);
animator.setRepeatCount(0);
animator.start();
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
progresscount = (float)animation.getAnimatedValue();
invalidate();
}
});

}

public ProgressView(Context context) {
super(context);
initView(context);
}

private void initView(Context context) {

mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setColor(getResources().getColor(R.color.biaoti));
mPaint.setStyle(Paint.Style.FILL);//充满
mPaint.setAntiAlias(true);// 设置画笔的锯齿效果
mPaint.setStrokeCap(Paint.Cap.ROUND);
}

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//改变值
//mRect = new Rect(0, 0,(int)(progresscount/maxCount)*mViewWidth, mViewHeight);
mRect.set(0, 0,(int)((progresscount/100)*mViewWidth), mViewHeight);
Log.d(TAG,(int)((progresscount/100)*mViewWidth)+"----长度");

canvas.drawRect(mRect, mPaint);

canvas.drawCircle((int)((progresscount/100)*mViewWidth), mViewHeight/2, mViewHeight/2, mPaint);

}

private int dipToPx(int dip) {
float scale = getContext().getResources().getDisplayMetrics().density;
return (int) (dip * scale + 0.5f * (dip >= 0 ? 1 : -1));
}

/***
* 设置最大的进度值
* @param maxCount
*/
public void setMaxCount(float maxCount) {
this.maxCount = maxCount;
}

/***
* 设置当前的进度值
* @param currentCount
*/
public void setCurrentCount(float currentCount) {
this.currentCount = currentCount > maxCount ? maxCount : currentCount;

initanimator();
//invalidate();

}

public float getMaxCount() {
return maxCount;
}

public float getCurrentCount() {
return currentCount;
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
/*特别注意,此处必须要自己进行测量,否则系统会默认讲 wrap_cotent与match_parent视为相同,也就是会填充整个布局*/
setMeasuredDimension(measure(widthMeasureSpec), measure(heightMeasureSpec));
getViewXY();

//计算百分比所占的位置

}

/*自己测量view的宽高*/
private int measure(int measureSpec) {
int result = 0;
//分别获取测量模式 和 测量大小
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);

//如果是精确度模式,呢就按xml中定义的来
if (specMode == MeasureSpec.EXACTLY) {
result = specSize;
//如果是最大测量,就按照屏幕的宽度计算
}else if( specMode == MeasureSpec.AT_MOST) {
result = mScreenWidth;
}

return result;
}

/*获取自定义view的宽度*/
private void getViewXY() {
mViewWidth = getMeasuredWidth();
mViewHeight = getMeasuredHeight();
}
}


代码中使用:

mSportList = (ListView) view.findViewById(R.id.sport_list);
mAdapter=new Myadapter();
mSportList.setAdapter(mAdapter);


class Myadapter extends BaseAdapter{

@Override
public int getCount() {
return data.length;
}

@Override
public Object getItem(int i) {
return null;
}

@Override
public long getItemId(int i) {
return 0;
}

@Override
public View getView(int i, View view, ViewGroup viewGroup) {
ViewHolder holder = null;
if (holder==null){
holder=new ViewHolder();
view= LayoutInflater.from(mContext).inflate(R.layout.sport_path_item, null);
holder.number= (TextView) view.findViewById(R.id.number);
holder.mProgressView= (ProgressView) view.findViewById(R.id.progress);

view.setTag(holder);
}
else {

holder = (ViewHolder) view.getTag();
}

holder.number.setText(data[i]);
holder.mProgressView.setMaxCount(100);
holder.mProgressView.setCurrentCount(dataProgress[i]);
return view;
}
class  ViewHolder {
TextView  number;
ProgressView mProgressView;

}
}


由于是整个项目中的一部分,没办法把整个代码都放上来,但是你可以直接copy进去使用。好了就这么多了,其实很简单的,代码中已经做了很详细的注释,不清楚的请加q286384819,咱们一起探讨IOS、android的学习
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: