Android开发-各种各样好看漂亮的进度条,指示器,加载提示汇总【代码粘过来就可以用】
导读:之前项目中用到一些进度条,找了不少,打算写个demo自己总结一下,留着以后用, 有些是自己写的,有些是github上找的别人的库,如果大家觉得好看可以用,直接下载复制代码到项目里就可以用,ok 废话少说,先上图
1.绿色进度条,可以固定的
布局;
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:textSize="20sp" android:layout_marginTop="30dp" android:layout_centerHorizontal="true" android:text="设置当前进度固定不可拖动" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <LinearLayout android:id="@+id/full" android:layout_centerInParent="true" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="60dp"> <TextView android:id="@+id/progesss_value1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/percentage" android:gravity="center" android:paddingBottom="8dp" android:paddingLeft="4dp" android:paddingRight="4dp" android:paddingTop="2dp" android:textColor="@android:color/white" android:textSize="12sp" android:text="20%" /> <ProgressBar android:layout_gravity="center_horizontal" android:id="@+id/progesss1" style="@style/Widget.AppCompat.ProgressBar.Horizontal" android:layout_width="330dp" android:layout_height="wrap_content" android:background="@drawable/myprogressbar" android:indeterminateDrawable="@android:drawable/progress_indeterminate_horizontal" android:indeterminateOnly="false" android:max="100" android:maxHeight="50dp" android:minHeight="16dp" android:progress="20" android:progressDrawable="@drawable/myprogressbar" /> </LinearLayout> </RelativeLayout>其实就是普通的进度条改了样式而已通过设置一个父view包裹progress和textview
通过计算距离父view偏移量,把textview设置距离数值的位置,然后数值就是直接得到进度条的进度然后添加就ok了
代码;
public class Loading1 extends Activity { private ProgressBar progesss; private TextView progesssValue; private LinearLayout full; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.loading1); progesss = (ProgressBar) findViewById(R.id.progesss1); progesssValue = (TextView) findViewById(R.id.progesss_value1); full = (LinearLayout) findViewById(R.id.full); initview(); } private void initview() { progesss.setProgress(66); progesssValue.setText(new StringBuffer().append(progesss.getProgress()).append("%")); setPosWay1(); // ToastUtil.showToast("进度为66"); // Toast.makeText(this,"进度为:--66",Toast.LENGTH_SHORT).show(); // full.setOnTouchListener(new View.OnTouchListener() { // // @Override // public boolean onTouch(View v, MotionEvent event) { // int w = getWindowManager().getDefaultDisplay().getWidth(); // switch (event.getAction()) { // case MotionEvent.ACTION_DOWN: // x1 = (int) event.getRawX(); // progesss.setProgress(100 * x1 / w); // setPos(); // break; // case MotionEvent.ACTION_MOVE: // x2 = (int) event.getRawX(); // dx = x2 - x1; // if (Math.abs(dx) > w / 100) { //改变条件 调整进度改变速度 // x1 = x2; // 去掉已经用掉的距离, 去掉这句 运行看看会出现效果 // progesss.setProgress(progesss.getProgress() + dx * 100 / w); // setPos(); // } // break; // case MotionEvent.ACTION_UP: // break; // } // return true; // } // }); } @Override public void onWindowFocusChanged(boolean hasFocus) { super.onWindowFocusChanged(hasFocus); if (hasFocus) { setPos(); } } private void setPosWay1() { progesssValue.post(new Runnable() { @Override public void run() { setPos(); } }); } /** * 设置进度显示在对应的位置 */ public void setPos() { int w = getWindowManager().getDefaultDisplay().getWidth(); Log.e("w=====", "" + w); ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) progesssValue.getLayoutParams(); int pro = progesss.getProgress(); int tW = progesssValue.getWidth(); if (w * pro / 100 + tW * 0.3 > w) { params.leftMargin = (int) (w - tW * 1.1); } else if (w * pro / 100 < tW * 0.7) { params.leftMargin = 0; } else { params.leftMargin = (int) (w * pro / 100 - tW * 0.7); } progesssValue.setLayoutParams(params); } }2.可拖动的绿色进度条
布局;
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:textSize="20sp" android:layout_marginTop="30dp" android:layout_centerHorizontal="true" android:text="横向滑动调整当前进度" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <LinearLayout android:id="@+id/full" android:layout_centerInParent="true" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="60dp"> <TextView android:id="@+id/progesss_value1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/percentage" android:gravity="center" android:paddingBottom="8dp" android:paddingLeft="4dp" android:paddingRight="4dp" android:paddingTop="2dp" android:textColor="@android:color/white" android:textSize="12sp" android:text="20%" /> <ProgressBar android:layout_gravity="center_horizontal" android:id="@+id/progesss1" style="@style/Widget.AppCompat.ProgressBar.Horizontal" android:layout_width="330dp" android:layout_height="wrap_content" android:background="@drawable/myprogressbar" android:indeterminateDrawable="@android:drawable/progress_indeterminate_horizontal" android:indeterminateOnly="false" android:max="100" android:maxHeight="50dp" android:minHeight="16dp" android:progress="20" android:progressDrawable="@drawable/myprogressbar" /> </LinearLayout> <TextView android:id="@+id/numjd" android:layout_centerHorizontal="true" android:layout_marginBottom="20dp" android:text="当前进度:0" android:textColor="#FF9966" android:textSize="50sp" android:layout_alignParentBottom="true" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </RelativeLayout>代码;设置外层group的触摸监听事件,判断手势,按下,移动,抬起然后设置进度变化,最主要就是文本要对应在进度条数值位置上
public class Loading11 extends Activity { private ProgressBar progesss; private TextView progesssValue,textnum; private LinearLayout full; private int x0,x1, x2, dx; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.loading11); progesss = (ProgressBar) findViewById(R.id.progesss1); progesssValue = (TextView) findViewById(R.id.progesss_value1); full = (LinearLayout) findViewById(R.id.full); textnum = (TextView) findViewById(R.id.numjd); initview(); } private void initview() { //外面的父view设置触摸监听事件 full.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { int w = getWindowManager().getDefaultDisplay().getWidth(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: x1 = (int) event.getRawX(); progesss.setProgress(100 * x1 / w); setPos(); break; case MotionEvent.ACTION_MOVE: x2 = (int) event.getRawX(); dx = x2 - x1; if (Math.abs(dx) > w / 100) { //改变条件 调整进度改变速度 x1 = x2; // 去掉已经用掉的距离, 去掉这句 运行看看会出现效果 progesss.setProgress(progesss.getProgress() + dx * 100 / w); setPos(); } break; case MotionEvent.ACTION_UP: break; } return true; } }); } @Override public void onWindowFocusChanged(boolean hasFocus) { super.onWindowFocusChanged(hasFocus); if (hasFocus) { setPos(); } } private void setPosWay1() { progesssValue.post(new Runnable() { @Override public void run() { setPos(); } }); } /** * 设置进度显示在对应的位置 */ public void setPos() { int w = getWindowManager().getDefaultDisplay().getWidth(); Log.e("w=====", "" + w); ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) progesssValue.getLayoutParams(); int pro = progesss.getProgress(); int tW = progesssValue.getWidth(); if (w * pro / 100 + tW * 0.3 > w) { params.leftMargin = (int) (w - tW * 1.1); } else if (w * pro / 100 < tW * 0.7) { params.leftMargin = 0; } else { params.leftMargin = (int) (w * pro / 100 - tW * 0.7); } progesssValue.setLayoutParams(params); progesssValue.setText(new StringBuffer().append(progesss.getProgress()).append("%")); // ToastUtil.showToast("进度为:--"+progesss.getProgress()); // Toast.makeText(this,"进度为:--"+progesss.getProgress(),Toast.LENGTH_SHORT).show(); textnum.setText("当前进度:"+progesss.getProgress()); }3.简易seekbar进度条
布局;
<?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:orientation="vertical" android:background="#93b3d7" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:text="seekbar进度条\n在onStopTrackingTouch方法里修改\n//通过修改这里显示隐藏滑动后的进度数\nmWrapperIndicator.setVisibility\n(View.VISIBLE);" android:layout_centerHorizontal="true" android:layout_marginTop="20dp" android:textSize="20sp" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <RelativeLayout android:layout_centerInParent="true" android:layout_width="match_parent" android:layout_height="60dp"> <com.mylibrary.SeekBarIndicated android:id="@+id/mSeekBarIndicated" android:layout_centerHorizontal="true" android:layout_centerVertical="true" android:layout_width="340dp" android:layout_height="match_parent" app:indicator_paddingBottom="2dp" app:seekbar_marginBottom="10dp" app:indicator_textMarginTop="8dp" app:seekbar_progressDrawable="@drawable/myprogressbar" /> </RelativeLayout> <TextView android:id="@+id/numjd" android:layout_centerHorizontal="true" android:layout_marginBottom="20dp" android:text="当前进度:0" android:textColor="#FF9966" android:textSize="50sp" android:layout_alignParentBottom="true" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </RelativeLayout>
代码;自定义view 实现seekbar的监听 ui界面比原生的好看
package com.mylibrary; import android.annotation.SuppressLint; import android.annotation.TargetApi; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Color; import android.graphics.Rect; import android.os.Build; import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.ViewTreeObserver; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.RelativeLayout; import android.widget.SeekBar; import android.widget.TextView; @SuppressLint("NewApi") public class SeekBarIndicated extends FrameLayout implements SeekBar.OnSeekBarChangeListener { private ViewGroup mWrapperIndicator; private ImageView mImageViewIndicator; //显示图片 private TextView mTextViewProgress; //显示文字 private SeekBar mSeekBar; //滑动 private int mSeekBarMarginLeft = 0; private int mSeekBarMarginTop = 0; private int mSeekBarMarginBottom = 0; private int mSeekBarMarginRight = 0; private String mIndicatorText; private int mSeekBarMin = 0; private SeekBar.OnSeekBarChangeListener mOnSeekBarChangeListener; private TextProvider mTextProviderIndicator; private int mMeasuredWidth; public SeekBarIndicated(Context context) { super(context); if (!isInEditMode()) init(context); } public SeekBarIndicated(Context context, AttributeSet attrs) { super(context, attrs); if (!isInEditMode()) init(context, attrs, 0); } public SeekBarIndicated(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); if (!isInEditMode()) init(context, attrs, defStyleAttr); } private void init(Context context) { init(context, null, 0); } private void init(Context context, AttributeSet attrs, int defStyle) { View view = LayoutInflater.from(context).inflate( R.layout.view_seekbar_indicated, this); bindViews(view); if (attrs != null) setAttributes(context, attrs, defStyle); mSeekBar.setOnSeekBarChangeListener(this); mTextViewProgress.setText(String.valueOf(mSeekBar.getProgress())); getViewTreeObserver().addOnGlobalLayoutListener( new ViewTreeObserver.OnGlobalLayoutListener() { @TargetApi(Build.VERSION_CODES.JELLY_BEAN) @Override public void onGlobalLayout() { mMeasuredWidth = mSeekBar.getWidth() - mSeekBar.getPaddingLeft() - mSeekBar.getPaddingRight(); mSeekBar.setPadding( mSeekBar.getPaddingLeft(), mSeekBar.getPaddingTop() + mWrapperIndicator.getHeight(), mSeekBar.getPaddingRight(), mSeekBar.getPaddingBottom()); setIndicator(); getViewTreeObserver() .removeOnGlobalLayoutListener(this); } }); // mWrapperIndicator.setVisibility(View.GONE); } private void bindViews(View view) { mWrapperIndicator = (ViewGroup) view .findViewById(R.id.wrapper_seekbar_indicator); mImageViewIndicator = (ImageView) view .findViewById(R.id.img_seekbar_indicator); mTextViewProgress = (TextView) view .findViewById(R.id.txt_seekbar_indicated_progress); mSeekBar = (SeekBar) view.findViewById(R.id.seekbar); mTextViewProgress.setGravity(1); } @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { setIndicator(); if (mOnSeekBarChangeListener != null) mOnSeekBarChangeListener.onProgressChanged(seekBar, progress, fromUser); } @Override public void onStartTrackingTouch(SeekBar seekBar) { if (mOnSeekBarChangeListener != null) { mOnSeekBarChangeListener.onStartTrackingTouch(seekBar); mWrapperIndicator.setVisibility(View.VISIBLE); } } @Override public void onStopTrackingTouch(SeekBar seekBar) { if (mOnSeekBarChangeListener != null) { mOnSeekBarChangeListener.onStopTrackingTouch(seekBar); //通过修改这里显示隐藏滑动后的进度数 mWrapperIndicator.setVisibility(View.VISIBLE); } } @TargetApi(Build.VERSION_CODES.JELLY_BEAN) private void setIndicator() { if (mTextProviderIndicator != null) { mTextViewProgress.setText(mTextProviderIndicator .provideText(getProgress())); } else { if (mIndicatorText != null) { try { mTextViewProgress.setText(String.valueOf(String.format( mIndicatorText, getProgress()))); } catch (Exception e) { mTextViewProgress.setText(String.valueOf(getProgress())); } } else { mTextViewProgress.setText(String.valueOf(getProgress())); } } Rect padding = new Rect(); mSeekBar.getThumb().getPadding(padding); int thumbPos = mSeekBar.getPaddingLeft() + mMeasuredWidth * mSeekBar.getProgress() / mSeekBar.getMax(); thumbPos = (int) Math.ceil(thumbPos); mWrapperIndicator.setX(thumbPos - (int) Math.ceil(mWrapperIndicator.getWidth() / 2)); } private void setAttributes(Context context, AttributeSet attrs, int defStyle) { // then obtain typed array TypedArray arr = context.obtainStyledAttributes(attrs, R.styleable.SeekBarIndicated, defStyle, 0); // and get values you need by indexes from your array attributes defined // above mSeekBarMarginLeft = arr.getDimensionPixelSize( R.styleable.SeekBarIndicated_seekbar_marginLeft, 0); mSeekBarMarginTop = arr.getDimensionPixelSize( R.styleable.SeekBarIndicated_seekbar_marginTop, 0); mSeekBarMarginRight = arr.getDimensionPixelSize( R.styleable.SeekBarIndicated_seekbar_marginRight, 0); mSeekBarMarginBottom = arr.getDimensionPixelSize( R.styleable.SeekBarIndicated_seekbar_marginBottom, 0); mSeekBarMin = arr.getInt(R.styleable.SeekBarIndicated_seekbar_min, 0); int seekBarMax = arr.getInt(R.styleable.SeekBarIndicated_seekbar_max, 100); int seekBarThumbId = arr.getResourceId( R.styleable.SeekBarIndicated_seekbar_thumb, 0); int seekBarProgressDrawableId = arr.getResourceId( R.styleable.SeekBarIndicated_seekbar_progressDrawable, 0); int indicatorTextStyle = arr.getInt( R.styleable.SeekBarIndicated_indicator_textStyle, 0); int indicatorPaddingLeft = arr.getDimensionPixelSize( R.styleable.SeekBarIndicated_indicator_paddingLeft, 0); int indicatorPaddingTop = arr.getDimensionPixelSize( R.styleable.SeekBarIndicated_indicator_paddingTop, 0); int indicatorPaddingRight = arr.getDimensionPixelSize( R.styleable.SeekBarIndicated_indicator_paddingRight, 0); int indicatorPaddingBottom = arr.getDimensionPixelSize( R.styleable.SeekBarIndicated_indicator_paddingBottom, 0); mWrapperIndicator.setPadding(indicatorPaddingLeft, indicatorPaddingTop, indicatorPaddingRight, indicatorPaddingBottom); setMin(mSeekBarMin); setMax(seekBarMax); if (seekBarThumbId > 0) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) mSeekBar.setThumb(getResources().getDrawable(seekBarThumbId)); else mSeekBar.setThumb(getResources().getDrawable(seekBarThumbId, null)); } if (seekBarProgressDrawableId > 0) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) mSeekBar.setProgressDrawable(getResources().getDrawable( seekBarProgressDrawableId)); else mSeekBar.setProgressDrawable(getResources().getDrawable( seekBarProgressDrawableId, null)); } mIndicatorText = arr .getString(R.styleable.SeekBarIndicated_indicator_text); mTextViewProgress.setTypeface(mTextViewProgress.getTypeface(), indicatorTextStyle); mSeekBar.setPadding(mSeekBar.getPaddingLeft() + mSeekBarMarginLeft, mSeekBar.getPaddingTop() + mSeekBarMarginTop, mSeekBar.getPaddingRight() + mSeekBarMarginRight, mSeekBar.getPaddingBottom() + mSeekBarMarginBottom); setIndicatorImage(arr); setIndicatorTextAttributes(arr); arr.recycle(); } private void setIndicatorTextAttributes(TypedArray arr) { RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) mTextViewProgress .getLayoutParams(); int indicatorTextMarginLeft = arr.getDimensionPixelSize( R.styleable.SeekBarIndicated_indicator_textMarginLeft, layoutParams.leftMargin); int indicatorTextMarginTop = arr.getDimensionPixelSize( R.styleable.SeekBarIndicated_indicator_textMarginTop, getContext().getResources().getDimensionPixelSize( R.dimen.indicator_txt_margin_top)); int indicatorTextMarginRight = arr.getDimensionPixelSize( R.styleable.SeekBarIndicated_indicator_textMarginRight, layoutParams.rightMargin); int indicatorTextMarginBottom = arr.getDimensionPixelSize( R.styleable.SeekBarIndicated_indicator_textMarginBottom, layoutParams.bottomMargin); int indicatorTextColor = arr.getColor( R.styleable.SeekBarIndicated_indicator_textColor, Color.WHITE); if (arr.hasValue(R.styleable.SeekBarIndicated_indicator_textCenterHorizontal)) { boolean centerHorizontal = arr .getBoolean( R.styleable.SeekBarIndicated_indicator_textCenterHorizontal, false); if (centerHorizontal) { layoutParams.addRule(RelativeLayout.CENTER_HORIZONTAL); if (!arr.hasValue(R.styleable.SeekBarIndicated_indicator_textMarginTop)) indicatorTextMarginTop = 0; } } else { layoutParams.addRule(RelativeLayout.CENTER_HORIZONTAL); } if (arr.hasValue(R.styleable.SeekBarIndicated_indicator_textCenterVertical)) { boolean centerVertical = arr.getBoolean( R.styleable.SeekBarIndicated_indicator_textCenterVertical, false); if (centerVertical) layoutParams.addRule(RelativeLayout.CENTER_VERTICAL); } // mTextViewProgress.setTextColor(indicatorTextColor); layoutParams.setMargins(indicatorTextMarginLeft, indicatorTextMarginTop, indicatorTextMarginBottom, indicatorTextMarginRight); mTextViewProgress.setLayoutParams(layoutParams); } private void setIndicatorImage(TypedArray arr) { int imageResourceId = arr.getResourceId( R.styleable.SeekBarIndicated_indicator_src, R.drawable.color_seekbar_pop_bg); mImageViewIndicator.setImageResource(imageResourceId); } public void setMax(int max) { mSeekBar.setMax(max - mSeekBarMin); } public void setMin(int min) { mSeekBarMin = min; } public void setValue(int value) { mSeekBar.setProgress(value); setIndicator(); } public void setOnSeekBarChangeListener( SeekBar.OnSeekBarChangeListener onSeekBarChangeListener) { mOnSeekBarChangeListener = onSeekBarChangeListener; } public void setTextProviderIndicator(TextProvider textProviderIndicator) { mTextProviderIndicator = textProviderIndicator; } public int getProgress() { int unsignedMin = mSeekBarMin < 0 ? mSeekBarMin * -1 : mSeekBarMin; return mSeekBar.getProgress() + unsignedMin; } public interface TextProvider { String provideText(int progress); } private void setFormattedString(TextView textView, String baseText, Object value) { try { textView.setText(String.format(baseText, value)); } catch (Exception e) { textView.setText(String.valueOf(value)); } } }
seekBarIndicated = (SeekBarIndicated) findViewById(R.id.mSeekBarIndicated); numjd = (TextView) findViewById(R.id.numjd); seekBarIndicated.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { //修改进度的回调 numjd.setText("当前进度:"+progress); } @Override public void onStartTrackingTouch(SeekBar seekBar) { } @Override public void onStopTrackingTouch(SeekBar seekBar) { } });
4.炫酷装B进度条
布局;
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:myMagicProgress="http://schemas.android.com/apk/res-auto" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <RelativeLayout android:layout_centerInParent="true" android:background="#14acae" android:layout_width="match_parent" android:layout_height="wrap_content"> <com.panghaha.it.loading.View.MyProgress android:id="@+id/myprogress" android:layout_width="match_parent" android:layout_height="80dp" myMagicProgress:circleProgressRadus="60dp" myMagicProgress:horizonalProgressHeight="10dp" myMagicProgress:textProgressSize="14sp" myMagicProgress:colorProgress="#fd9112" myMagicProgress:colorSecondProgress="#1592ff" /> </RelativeLayout> <Button android:id="@+id/btnOK" android:onClick="onClick" android:layout_marginTop="20dp" android:layout_alignParentRight="true" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="确定" /> <EditText android:id="@+id/et_progress" android:layout_marginTop="20dp" android:inputType="number" android:layout_toLeftOf="@id/btnOK" android:hint="输入进度" android:layout_alignParentLeft="true" android:layout_width="match_parent" android:layout_height="wrap_content" /> <TextView android:id="@+id/numjd" android:visibility="invisible" android:layout_centerHorizontal="true" android:layout_marginBottom="20dp" android:text="当前进度:0" android:textColor="#FF9966" android:textSize="50sp" android:layout_alignParentBottom="true" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </RelativeLayout>代码;
进度条由水平的进度条和圆形的进度条组合而成
package com.panghaha.it.loading.View; import android.animation.ObjectAnimator; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.RectF; import android.util.AttributeSet; import android.view.View; import android.view.animation.DecelerateInterpolator; /** * Description 酷炫水平进度条 * Author: pang * Date: 2016-08-22 * Time: 14:59 */ public class HorizonalProgress extends View { private int viewWidth;//view的宽度 private int viewHigth;//view的高度 private Paint mPaint;//画笔 212 62 96 private int colorSecondProgress = Color.argb(255,229,237,245);//背景圆颜色,进度条背景色 private int colorProgress = Color.argb(255,19,146,255);//背景圆颜色,一级进度条颜色 private int progressHeight = 30;//进度条的高度 private RectF rectF = new RectF(); private int curProgress = 0; //必须小于等于100 大于0 private int oldProgress = 0; public void setColorSecondProgress(int colorSecondProgress) { this.colorSecondProgress = colorSecondProgress; } public void setColorProgress(int colorProgress) { this.colorProgress = colorProgress; } public void setProgressHeight(int progressHeight) { this.progressHeight = progressHeight; } public void setCurProgress(int curProgress) { this.curProgress = curProgress; invalidate(); } public HorizonalProgress(Context context) { this(context,null); } public HorizonalProgress(Context context, AttributeSet attrs) { this(context, attrs,0); } public HorizonalProgress(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } private void init(){ //初始化坐标画笔 mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);// mPaint.setColor(colorSecondProgress); mPaint.setAntiAlias(true); mPaint.setStyle(Paint.Style.STROKE);//空心 curProgress = 0; } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int widthSize = MeasureSpec.getSize(widthMeasureSpec); int widthMode = MeasureSpec.getMode(widthMeasureSpec); int heightMode = MeasureSpec.getMode(heightMeasureSpec); int heightSize = MeasureSpec.getSize(heightMeasureSpec); int height; int width; //宽度测量 if (widthMode == MeasureSpec.EXACTLY) { width = widthSize; } else { width = getMeasuredWidth(); } viewWidth = width; //高度测量 if (heightMode == MeasureSpec.EXACTLY) { height = heightSize; } else { height = getMeasuredHeight(); } //进度条的高度根据 viewHigth = progressHeight; setMeasuredDimension(width, viewHigth); } /** * 绘制进度 * @param canvas */ private void drawProgress(Canvas canvas){ rectF.left = 0; rectF.right = viewWidth; rectF.top = 0; rectF.bottom = viewHigth; mPaint.setStyle(Paint.Style.FILL); mPaint.setColor(colorSecondProgress); //灰色背景 canvas.drawRoundRect(rectF,viewHigth/2,viewHigth/2,mPaint); //进度 mPaint.setColor(colorProgress); rectF.right = curProgress * viewWidth / 100; canvas.drawRoundRect(rectF,viewHigth/2,viewHigth/2,mPaint); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); drawProgress(canvas); } public void setProgress(int progress){ if (progress < 0 || progress > 100) return; ObjectAnimator o = ObjectAnimator.ofInt(this, "curProgress", oldProgress, progress); o.setDuration(1000); o.setInterpolator(new DecelerateInterpolator()); o.start(); oldProgress = progress; } }
下面是圆形的
package com.panghaha.it.loading.View; import android.animation.ObjectAnimator; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.RectF; import android.util.AttributeSet; import android.view.View; import android.view.animation.DecelerateInterpolator; import com.panghaha.it.loading.R; /** * Description 圆形装逼进度条 * Author: tu * Date: 2016-08-19 * Time: 14:33 */ public class CircleProgress extends View{ private float textSize = getResources().getDimension(R.dimen.text_size_14); private float dotX, dotY;//圆点xy private int viewWidth;//view的宽度 private int viewHigth;//view的高度 private Paint mPaint,mPaintArc;//画笔 212 62 96 // private int colorBg = Color.argb(255,54,68,76);//背景圆颜色 private int colorBg = Color.WHITE;//背景圆颜色 // private int colorWhite = Color.argb(255,255,255,255);//文字颜色 private int colorWhite = Color.BLACK;//文字颜色 // private int colorWhite = getResources().getColor(R.color.titbar_color);//文字颜色 // private int colorBlack = Color.argb(255,34,49,59);//第二刻度颜色 private int colorBlack = Color.WHITE;//第二刻度颜色 private int colorBlue = Color.argb(255,94,248,249);//刻度颜色 // private int colorBlue = Color.WHITE;//刻度颜色 private int pandding = 10; private RectF rectF; private float radius = 10;//半径 private float scaleLineLenth = 5;//刻度线长 private int scaleAngle = 10;//刻度间隔 private int scaleWidth = 5;//刻度宽度 private int curProgress = 0;//0 ~ 100进度 当前进度 private int oldProgress = 0; public void setColorBlue(int colorBlue) { this.colorBlue = colorBlue; } public void setTextSize(float textSize) { this.textSize = textSize; } public int getCurProgress() { return curProgress; } public void setCurProgress(int curProgress) { this.curProgress = curProgress; invalidate(); } public CircleProgress(Context context) { this(context,null); } public CircleProgress(Context context, AttributeSet attrs) { this(context, attrs,0); } public CircleProgress(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(context); } /** * 初始化画笔 */ private void init(Context context) { //初始化坐标画笔 mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);// mPaintArc = new Paint(Paint.ANTI_ALIAS_FLAG);// mPaint.setColor(colorWhite); mPaintArc.setColor(colorBg); mPaint.setAntiAlias(true); mPaintArc.setAntiAlias(true); mPaint.setTextSize(15); mPaint.setStyle(Paint.Style.STROKE);//空心 //当前进度 } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int widthSize = MeasureSpec.getSize(widthMeasureSpec); int widthMode = MeasureSpec.getMode(widthMeasureSpec); int heightMode = MeasureSpec.getMode(heightMeasureSpec); int heightSize = MeasureSpec.getSize(heightMeasureSpec); int height; int width; //宽度测量 if (widthMode == MeasureSpec.EXACTLY) { width = widthSize; } else { width = getMeasuredWidth(); } dotX = width / 2; viewWidth = width; //高度测量 if (heightMode == MeasureSpec.EXACTLY) { height = heightSize; } else { height = getMeasuredHeight(); } viewHigth = height; dotY = height / 2; radius = dotX-(getPaddingLeft() + getPaddingRight())/2; scaleLineLenth = radius/3; rectF = new RectF(dotX - radius, dotY - radius, dotX + radius, dotY + radius); setMeasuredDimension(width, height); } private void drawProgress(Canvas canvas){ if(mPaintArc == null){ return; } //圆 mPaintArc.setStyle(Paint.Style.FILL); canvas.drawCircle(dotX, dotY, radius, mPaintArc); //中心进度值 mPaint.setStyle(Paint.Style.FILL_AND_STROKE);//实心 mPaint.setTextAlign(Paint.Align.CENTER); mPaint.setStrokeWidth(1); mPaint.setTextSize(textSize); mPaint.setColor(colorWhite); canvas.drawText(curProgress + "%",dotX, dotY+getResources().getDimension(R.dimen.text_size_14)/2 ,mPaint); //黑色刻度 12点钟方向为起始点(-90°),正时针方法绘制 for (int angle = -90; angle <= 270; angle += scaleAngle){ float xY[] = caculCoordinate(angle); if(xY != null) { mPaint.setStrokeWidth(scaleWidth); mPaint.setColor(colorBlack); canvas.drawLine(xY[0], xY[1],xY[2],xY[3], mPaint); } } //进度算法 //360 除与 scaleAngle(进度间隔10) = 36; 再拿进度总数100换算当前进度 //算出当前进度占几个刻度 int curProgressCount = curProgress * (360/scaleAngle) /100; int angleStart = -90; for (int count = 0; count < curProgressCount;count ++){ float xY[] = caculCoordinate(angleStart); if(xY != null) { mPaint.setStrokeWidth(scaleWidth); mPaint.setColor(colorBlue); canvas.drawLine(xY[0], xY[1],xY[2],xY[3], mPaint); } angleStart += scaleAngle; } } /** * 根据圆心角 计算圆周上的坐标 * @param angle * @return xY[0] startX; xY[1] startY; xY[2] endX; xY[3] endY; */ private float[] caculCoordinate(int angle){ //angle >180 angle = angle -180 float xY[] = new float[4]; //角度处理 int tempAngle = Math.abs(angle); float tempScaleLineLenth = scaleLineLenth; if(270 > tempAngle && tempAngle >= 180) { tempAngle = tempAngle - 180; xY[0] = dotX - getCoordinateX(tempAngle,radius); xY[1] = dotY - getCoordinateY(tempAngle,radius); xY[2] = xY[0] + getCoordinateX(tempAngle,tempScaleLineLenth); xY[3] = xY[1] + getCoordinateY(tempAngle,tempScaleLineLenth); }else if(180 > tempAngle && tempAngle > 90){ tempAngle = 180 - tempAngle; xY[0] = dotX - getCoordinateX(tempAngle,radius); xY[1] = dotY + getCoordinateY(tempAngle,radius); xY[2] = xY[0] + getCoordinateX(tempAngle,tempScaleLineLenth); xY[3] = xY[1] - getCoordinateY(tempAngle,tempScaleLineLenth); }else if(90 >= tempAngle && tempAngle >= 0){ xY[0] = dotX + getCoordinateX(tempAngle,radius); xY[1] = angle < 0 ? dotY - getCoordinateY(tempAngle,radius) : dotY + getCoordinateY(tempAngle,radius); xY[2] = xY[0] - getCoordinateX(tempAngle,tempScaleLineLenth); xY[3] = angle < 0 ? xY[1] + getCoordinateY(tempAngle,tempScaleLineLenth) : xY[1] - getCoordinateY(tempAngle,tempScaleLineLenth); } return xY; } /** * 获取圆周上y值相对值 * @param tempAngle * @param radius 算开始坐标是传半径,算结束坐标时传刻度线的长度 * @return */ private float getCoordinateY(int tempAngle,float radius){ //利用正弦函数算出y坐标 return (float) (Math.sin(tempAngle*Math.PI/180)*(radius - 15)); //10 是离圆弧的距离 } /** * 获取圆周上X值相对值 * @param tempAngle * @return */ private float getCoordinateX(int tempAngle,float radius){ //利用余弦函数算出y坐标 return (float) (Math.cos(tempAngle*Math.PI/180)*(radius - 15)); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); drawProgress(canvas); } public void setProgress(int progress){ if (progress < 0 || progress > 100) return; ObjectAnimator o = ObjectAnimator.ofInt(this, "curProgress", oldProgress, progress); o.setDuration(1000); o.setInterpolator(new DecelerateInterpolator()); o.start(); oldProgress = progress; } }
然后是组合起来的view
package com.panghaha.it.loading.View; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Color; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; import android.view.ViewTreeObserver; import android.view.ViewTreeObserver.OnGlobalLayoutListener; import android.widget.RelativeLayout; import com.panghaha.it.loading.R; /** * Description 组合装逼进度 * Author: pang * Date: 2016-08-22 * Time: 15:36 */ public class MyProgress extends RelativeLayout { private Context context; private float textProgressSize;//圆形进度条中间文字 private float horizonalProgressHeight;//横条高度 private float circleProgressRadus;//圆形半径 private int colorProgress;//进度条颜色,圆盘刻度颜色 private int colorSecondProgress;//进度条背景颜色 private boolean flagPaint = true;//绘图标志 public int newProgress; private CircleProgress mCircleProgress; private HorizonalProgress mHorizonalProgress; //private int touchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();//最小滑动阀值 public MyProgress(Context context) { this(context,null); } public MyProgress(Context context, AttributeSet attrs) { this(context, attrs,0); } public MyProgress(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); this.context = context; init(attrs); ViewTreeObserver vto = getViewTreeObserver(); vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() { @Override public void onGlobalLayout() { if(flagPaint){ flagPaint = false; initHorizonalProgress(); }else{ } } }); } private void init(AttributeSet attrs){ flagPaint = true; //获取自定义xml属性 TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.myMagicProgress); int n = typedArray.getIndexCount(); for (int i = 0; i < n; i++) { int attr = typedArray.getIndex(i); switch (attr) { case R.styleable.myMagicProgress_circleProgressRadus: // Log.e("tag", "typedArray.getDimension(attr, 0)="+typedArray.getDimension(attr, 0)+",typedArray.getDimension(i, 0)="+typedArray.getDimension(i, 0)); circleProgressRadus = typedArray.getDimension(attr, 0); break; case R.styleable.myMagicProgress_horizonalProgressHeight: horizonalProgressHeight = typedArray.getDimension(attr, 0); break; case R.styleable.myMagicProgress_textProgressSize: textProgressSize = typedArray.getDimension(attr, 0); break; case R.styleable.myMagicProgress_colorProgress: colorProgress = typedArray.getColor(attr, Color.GRAY); break; case R.styleable.myMagicProgress_colorSecondProgress: colorSecondProgress = typedArray.getColor(attr, Color.GRAY); break; default: break; } } //横向进度条稍后设置参数,需要圆形进度条绘图完成,根据宽度绘制左右边距 mHorizonalProgress = new HorizonalProgress(getContext()); mHorizonalProgress.setProgressHeight((int) horizonalProgressHeight); mHorizonalProgress.setColorSecondProgress(colorSecondProgress); mHorizonalProgress.setColorProgress(colorProgress); int radus = (int) circleProgressRadus; mCircleProgress = new CircleProgress(getContext()); mCircleProgress.setTextSize(textProgressSize); mCircleProgress.setColorBlue(colorProgress); LayoutParams cp_lp = new LayoutParams(radus,radus); cp_lp.addRule(RelativeLayout.CENTER_VERTICAL); mCircleProgress.setLayoutParams(cp_lp); addView(mHorizonalProgress); addView(mCircleProgress); initView(); } private float mDownX; private float disX, llX; private void initView(){ mCircleProgress.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View view, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: mDownX = event.getX(); // Log.d("Tag",event.getX() + ":" + event.getRawX()); break; case MotionEvent.ACTION_MOVE: // Log.d("Tag",event.getX() + ":" + event.getRawX()); disX = event.getX() - mDownX; llX = mCircleProgress.getX() + disX; // Log.e("tag", "disX="+disX+",llX="+llX+",mHorizonalProgress.getWidth()="+mHorizonalProgress.getWidth()); //校正边界,反正滑块划出 llX = checkoundary(llX); jindu = llX; mCircleProgress.setX(llX); //计算进度条百分比 newProgress = getProgress(llX); //更新进度条 updateProgress(newProgress); break; case MotionEvent.ACTION_UP: break; default: break; } return true; } }); } /** * 绘制横向进度条 */ public void initHorizonalProgress(){ // Log.e("tag", "mCircleProgress.getWidth()="+mCircleProgress.getWidth()); //设置边距,左右空出滑块半径的距离 LayoutParams hp_lp = new LayoutParams(LayoutParams.MATCH_PARENT,(int) horizonalProgressHeight); hp_lp.leftMargin = mCircleProgress.getWidth()/2; hp_lp.rightMargin = mCircleProgress.getWidth()/2; hp_lp.addRule(RelativeLayout.CENTER_VERTICAL); mHorizonalProgress.setLayoutParams(hp_lp); } /** * 校正边界 * @return */ public float checkoundary(float llX){ if(llX<0){ llX = 0f; }else if(llX>mHorizonalProgress.getWidth()){ llX = mHorizonalProgress.getWidth(); } return llX; } /** * 换算百分比 */ public int getProgress(float llX){ return (int) ((llX/mHorizonalProgress.getWidth())*100); } /** * 更新进度 * @param newProgress */ public void updateProgress(int newProgress){ // Log.e("tag", "newProgress="+newProgress); mCircleProgress.setProgress(newProgress); mHorizonalProgress.setProgress(newProgress); } private float jindu; /**外部调用获取进度*/ public String getJindu(){ return jindu+""; } }
et_progress = (EditText) findViewById(R.id.et_progress); myProgress = (MyProgress) findViewById(R.id.myprogress); // textnum = (TextView) findViewById(R.id.numjd); // textnum.setText("当前进度:"+myProgress.getJindu()); } public void onClick(View v){ if(TextUtils.isEmpty(et_progress.getText().toString())) return; //更新进度条 myProgress.updateProgress(Integer.parseInt(et_progress.getText().toString()));5.气泡进度条1
布局;
<?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:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_centerHorizontal="true" android:text="气泡进度条1\nBubbleSeekBar" android:textColor="#00c3e8" android:textSize="35sp" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <RelativeLayout android:layout_centerInParent="true" android:layout_width="match_parent" android:layout_height="60dp"> <com.xw.repo.BubbleSeekBar android:layout_centerHorizontal="true" android:layout_centerVertical="true" android:id="@+id/bubbleseekbar" android:layout_width="340dp" android:layout_height="50dp" android:layout_marginTop="8dp" app:bsb_bubble_text_color="#ffffff" app:bsb_max="100" app:bsb_min="0" app:bsb_progress="0" app:bsb_section_count="1" app:bsb_section_text_position="bottom_sides" app:bsb_show_progress_in_float="true" app:bsb_show_section_mark="true" app:bsb_show_section_text="true" app:bsb_show_thumb_text="true"/> </RelativeLayout> <TextView android:id="@+id/numjd" android:layout_centerHorizontal="true" android:layout_marginBottom="20dp" android:text="当前进度:0" android:textColor="#FF9966" android:textSize="50sp" android:layout_alignParentBottom="true" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </RelativeLayout>代码;
mBbubbleSeekBar = (BubbleSeekBar) findViewById(R.id.bubbleseekbar); numtext = (TextView) findViewById(R.id.numjd); /** * 如果嵌套scrollview 会有随着scrollview滑动气泡离进度条越来越高的bug 下面的方法可以修正偏移量 * * scrollView.setScrollViewListener(new MyScrollView.ScrollViewListener() { @Override public void onScrollChanged(MyScrollView scrollView, int x, int y, int oldx, int oldy) { // 调用修正偏移方法 mBbubbleSeekBar.correctOffsetWhenContainerOnScrolling(); } }); */ //进度条 mBbubbleSeekBar.setOnProgressChangedListener(new BubbleSeekBar.OnProgressChangedListener() { @Override public void onProgressChanged(int progress, float progressFloat) { // LogUtil.d("进度1---->>", progress+""); numtext.setText("当前进度:"+progress); } @Override public void getProgressOnActionUp(int progress, float progressFloat) { } @Override public void getProgressOnFinally(int progress, float progressFloat) { } }); // mBbubbleSeekBar.setProgress(proooo); }6.气泡进度条2 ;这个气泡有动画,出现和消失时候
布局;
<?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:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_centerHorizontal="true" android:text="气泡进度条2\nDiscreteSeekBar\n气泡出现消失有动画" android:textColor="#00c3e8" android:textSize="35sp" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <RelativeLayout android:layout_centerInParent="true" android:layout_width="match_parent" android:layout_height="60dp"> <org.adw.library.widgets.discreteseekbar.DiscreteSeekBar android:id="@+id/disseebar" android:layout_width="match_parent" android:layout_height="match_parent" app:dsb_min="0" app:dsb_max="100" app:dsb_rippleColor="#3a7eec" app:dsb_indicatorColor="#3a7eec" /> </RelativeLayout> <TextView android:id="@+id/numjd" android:layout_centerHorizontal="true" android:layout_marginBottom="20dp" android:text="当前进度:0" android:textColor="#FF9966" android:textSize="50sp" android:layout_alignParentBottom="true" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </RelativeLayout>
代码;
private DiscreteSeekBar discreteSeekBar; private TextView numtext; @Override protected void onCreate( Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.loading5); discreteSeekBar = (DiscreteSeekBar) findViewById(R.id.disseebar); numtext = (TextView) findViewById(R.id.numjd); // 设置固定数值的方法 // discreteSeekBar.setNumericTransformer(new DiscreteSeekBar.NumericTransformer() { // @Override // public int transform(int value) { // return 88; // } // }); discreteSeekBar.setOnProgressChangeListener(new DiscreteSeekBar.OnProgressChangeListener() { @Override public void onProgressChanged(DiscreteSeekBar seekBar, int value, boolean fromUser) { // 进度回调 numtext.setText("当前进度:"+value); } @Override public void onStartTrackingTouch(DiscreteSeekBar seekBar) { } @Override public void onStopTrackingTouch(DiscreteSeekBar seekBar) { } }); }7.仿守望先锋加载进度条
布局;
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_centerHorizontal="true" android:text="守望先锋进度条" android:textColor="#00c3e8" android:textSize="35sp" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <com.chenzy.owloading.OWLoadingView android:id="@+id/owloading" android:layout_width="200dp" android:layout_height="200dp" android:layout_centerInParent="true"> </com.chenzy.owloading.OWLoadingView> <Button android:id="@+id/btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_marginBottom="20dp" android:layout_centerHorizontal="true" android:text="开始" /> </RelativeLayout>
代码;
owLoadingView = (OWLoadingView) findViewById(R.id.owloading); btn = (Button) findViewById(R.id.btn); // owLoadingView.setAutoStartAnim(true);//设置自动开启动画 btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if(btn.getText().equals("开始")){ owLoadingView.startAnim(); btn.setText("中止"); }else{ owLoadingView.stopAnim(); btn.setText("开始"); } } }); }
8.仿ios加载进度条和progresswheel
布局;
<?xml version="1.0" encoding="UTF-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:wheel="http://schemas.android.com/apk/res-auto" android:layout_width="150dp" android:layout_height="150dp" android:layout_gravity="center" android:background="@drawable/tips_bg" android:gravity="center" > <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:orientation="vertical" > <com.panghaha.it.loading.View.ProgressWheel android:layout_width="80dp" android:layout_height="80dp" android:layout_gravity="center" android:layout_marginBottom="10.0dip" android:clickable="false" android:gravity="center" wheel:matProg_barColor="#5592FB" wheel:matProg_progressIndeterminate="true" /> <TextView android:id="@+id/tips_loading_msg" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:gravity="center" android:lineSpacingExtra="3.0dip" android:text="asdf" android:textColor="#ffffffff" android:textSize="17.0sp" /> </LinearLayout> </RelativeLayout>
<?xml version="1.0" encoding="UTF-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="150dp" android:layout_height="150dp" android:layout_gravity="center" android:background="@drawable/tips_bg" android:gravity="center" > <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:orientation="vertical" > <ProgressBar android:layout_width="80dp" android:layout_height="80dp" android:layout_gravity="center" android:layout_marginBottom="10dp" android:clickable="false" android:gravity="center" style="@style/mProgress_circle" android:indeterminateDrawable="@drawable/myloading" /> <TextView android:id="@+id/tips_loading_msg" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:gravity="center" android:lineSpacingExtra="3.0dip" android:text="asdf" android:textColor="#ffffffff" android:textSize="17.0sp" /> </LinearLayout> </RelativeLayout>
代码;
package com.panghaha.it.loading; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.support.annotation.Nullable; import android.support.v7.app.AppCompatActivity; import android.view.View; import com.panghaha.it.loading.View.LoadingDialog; /*** * ━━━━ Code is far away from ━━━━━━ * () () * ( ) ( ) * ( ) ( ) * ┏┛┻━━━┛┻┓ * ┃ ━ ┃ * ┃ ┳┛ ┗┳ ┃ * ┃ ┻ ┃ * ┗━┓ ┏━┛ * ┃ ┃ * ┃ ┗━━━┓ * ┃ ┣┓ * ┃ ┏┛ * ┗┓┓┏━┳┓┏┛ * ┃┫┫ ┃┫┫ * ┗┻┛ ┗┻┛ * ━━━━ bug with the more protecting ━━━ * <p/> * Created by PangHaHa12138 on 2017/6/3. */ public class Loading7 extends Activity { private LoadingDialog dialog; private Handler mHandler = new Handler() { public void dispatchMessage(android.os.Message msg) { if (dialog != null && dialog.isShowing()) { dialog.dismiss(); } }; }; @Override protected void onCreate( Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.loading7); } public void onClick(View v) { switch (v.getId()) { case R.id.btn1: dialog = new LoadingDialog(this, R.layout.view_tips_loading); dialog.setCancelable(false); dialog.setCanceledOnTouchOutside(false); dialog.show(); new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(3000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } mHandler.sendEmptyMessage(1); } }).start(); break; case R.id.btn2: dialog = new LoadingDialog(this, R.layout.view_tips_loading2); dialog.setCancelable(false); dialog.setCanceledOnTouchOutside(false); dialog.show(); new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(3000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } mHandler.sendEmptyMessage(1); } }).start(); break; } } }9.圆形进度条
布局;
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" xmlns:app="http://schemas.android.com/apk/res-auto"> <RelativeLayout android:background="@drawable/pic_bg" android:layout_width="match_parent" android:layout_height="230dp"> <com.panghaha.it.loading.View.PercentCircle android:id="@+id/percentCircle" android:layout_centerInParent="true" android:layout_width="200dp" android:layout_height="200dp" app:radius="250" app:circleBackground="#00000000" app:ringColor="#ffffff" app:textColor="#ffffff" /> <ImageView android:layout_centerInParent="true" android:layout_width="220dp" android:layout_height="220dp" android:src="@drawable/ring"/> </RelativeLayout> <RelativeLayout android:layout_marginTop="250dp" android:layout_width="match_parent" android:layout_height="230dp"> <com.panghaha.it.loading.View.PercentCircle android:id="@+id/percentCircle2" android:layout_centerInParent="true" android:layout_width="220dp" android:layout_height="220dp" app:radius="200" app:circleBackground="#37C000" app:ringColor="#3a7eec" app:textColor="#ffffff" /> </RelativeLayout> </RelativeLayout>
view
package com.panghaha.it.loading.View; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.RectF; import android.util.AttributeSet; import android.view.View; import com.panghaha.it.loading.R; import com.panghaha.it.loading.utils.PxUtils; /**一个圆形百分比进度 View * 用于展示简易的图标 * Created by Administrator on 2015/12/16. */ public class CirclePercentView extends View { //圆的半径 private float mRadius; //色带的宽度 private float mStripeWidth; //总体大小 private int mHeight; private int mWidth; //动画位置百分比进度 private int mCurPercent; //实际百分比进度 private int mPercent; //圆心坐标 private float x; private float y; //要画的弧度 private int mEndAngle; //小圆的颜色 private int mSmallColor; //大圆颜色 private int mBigColor; //中心百分比文字大小 private float mCenterTextSize; public CirclePercentView(Context context) { this(context, null); } public CirclePercentView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public CirclePercentView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CirclePercentView, defStyleAttr, 0); mStripeWidth = a.getDimension(R.styleable.CirclePercentView_stripeWidth, PxUtils.dpToPx(30, context)); mCurPercent = a.getInteger(R.styleable.CirclePercentView_percent, 0); mSmallColor = a.getColor(R.styleable.CirclePercentView_smallColor,0xffafb4db); mBigColor = a.getColor(R.styleable.CirclePercentView_bigColor,0xff6950a1); mCenterTextSize = a.getDimensionPixelSize(R.styleable.CirclePercentView_centerTextSize,PxUtils.spToPx(20,context)); mRadius = a.getDimensionPixelSize(R.styleable.CirclePercentView_radiuss,PxUtils.dpToPx(100,context)); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { //获取测量模式 int widthMode = MeasureSpec.getMode(widthMeasureSpec); int heightMode = MeasureSpec.getMode(heightMeasureSpec); //获取测量大小 int widthSize = MeasureSpec.getSize(widthMeasureSpec); int heightSize = MeasureSpec.getSize(heightMeasureSpec); if (widthMode == MeasureSpec.EXACTLY && heightMode == MeasureSpec.EXACTLY) { mRadius = widthSize / 2; x = widthSize / 2; y = heightSize / 2; mWidth = widthSize; mHeight = heightSize; } if(widthMode == MeasureSpec.AT_MOST&&heightMode ==MeasureSpec.AT_MOST){ mWidth = (int) (mRadius*2); mHeight = (int) (mRadius*2); x = mRadius; y = mRadius; } setMeasuredDimension(mWidth,mHeight); } @Override protected void onDraw(Canvas canvas) { mEndAngle = (int) (mCurPercent * 3.6); //绘制大圆 Paint bigCirclePaint = new Paint(); bigCirclePaint.setAntiAlias(true); bigCirclePaint.setColor(mBigColor); canvas.drawCircle(x, y, mRadius, bigCirclePaint); //饼状图 Paint sectorPaint = new Paint(); sectorPaint.setColor(mSmallColor); sectorPaint.setAntiAlias(true); RectF rect = new RectF(0, 0, mWidth, mHeight); canvas.drawArc(rect, 270, mEndAngle, true, sectorPaint); //绘制小圆,颜色透明 Paint smallCirclePaint = new Paint(); smallCirclePaint.setAntiAlias(true); smallCirclePaint.setColor(mBigColor); canvas.drawCircle(x, y, mRadius - mStripeWidth, smallCirclePaint); //绘制文本 Paint textPaint = new Paint(); String text = mCurPercent + "%"; textPaint.setTextSize(mCenterTextSize); float textLength = textPaint.measureText(text); textPaint.setColor(Color.WHITE); canvas.drawText(text, x - textLength/2, y, textPaint); } //外部设置百分比数 public void setPercent(int percent) { if (percent > 100) { throw new IllegalArgumentException("percent must less than 100!"); } setCurPercent(percent); } //内部设置百分比 用于动画效果 private void setCurPercent(int percent) { mPercent = percent; new Thread(new Runnable() { @Override public void run() { int sleepTime = 1; for(int i =0;i<mPercent;i++){ if(i%20 == 0){ sleepTime+=2; } try { Thread.sleep(sleepTime); } catch (InterruptedException e) { e.printStackTrace(); } mCurPercent = i; CirclePercentView.this.postInvalidate(); } } }).start(); } }
percentCircle = (PercentCircle) findViewById(R.id.percentCircle); percentCircle2 = (PercentCircle) findViewById(R.id.percentCircle2); percentCircle.setTargetPercent(65); percentCircle2.setTargetPercent(88);10.开源指示器库的使用
AVLoadingIndicatorView
布局
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" xmlns:app="http://schemas.android.com/apk/res-auto" android:background="#FF6666"> <com.wang.avi.AVLoadingIndicatorView android:id="@+id/avi" android:layout_centerInParent="true" android:layout_width="wrap_content" android:layout_height="wrap_content" style="@style/AVLoadingIndicatorView.Large" android:visibility="visible" app:indicatorName="PacmanIndicator" /> <LinearLayout android:layout_alignParentBottom="true" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="wrap_content"> <Button android:text="show" android:id="@+id/show" android:layout_marginLeft="5dp" android:layout_marginRight="5dp" android:layout_width="0dp" android:layout_weight="1" android:layout_height="wrap_content" /> <Button android:id="@+id/hide" android:text="hide" android:layout_marginLeft="5dp" android:layout_marginRight="5dp" android:layout_width="0dp" android:layout_weight="1" android:layout_height="wrap_content" /> </LinearLayout> </RelativeLayout>代码;
已经封装的非常好了,调用show展示,hide隐藏
show = (Button) findViewById(R.id.show); hide = (Button) findViewById(R.id.hide); avLoadingIndicatorView = (AVLoadingIndicatorView) findViewById(R.id.avi); show.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { avLoadingIndicatorView.show(); } }); hide.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { avLoadingIndicatorView.hide(); } });
这个库的地址 https://github.com/81813780/AVLoadingIndicatorView
这是对应指示器的名字 从上到下对应的
第一行 "BallPulseIndicator","BallGridPulseIndicator","BallClipRotateIndicator","BallClipRotatePulseIndicator",
第二行 "SquareSpinIndicator","BallClipRotateMultipleIndicator","BallPulseRiseIndicator","BallRotateIndicator",
第三行 "CubeTransitionIndicator","BallZigZagIndicator","BallZigZagDeflectIndicator","BallTrianglePathIndicator",
第四行 "BallScaleIndicator","LineScaleIndicator","LineScalePartyIndicator","BallScaleMultipleIndicator",
第五行 "BallPulseSyncIndicator","BallBeatIndicator","LineScalePulseOutIndicator","LineScalePulseOutRapidIndicator",
第六行 "BallScaleRippleIndicator","BallScaleRippleMultipleIndicator","BallSpinFadeLoaderIndicator","LineSpinFadeLoaderIndicator",
第七行 "TriangleSkewSpinIndicator","PacmanIndicator","BallGridBeatIndicator","SemiCircleSpinIndicator",
最后一个 "com.wang.avi.sample.MyCustomIndicator"
感谢 :守望屁股 进度条 https://github.com/AnderWeb/discreteSeekBar
气泡进度条2 https://github.com/AnderWeb/discreteSeekBar
气泡1进度条 https://github.com/woxingxiao/BubbleSeekBar
加载指示器 https://github.com/81813780/AVLoadingIndicatorView
最后 感谢阅读 demo下载
https://github.com/PangHaHa12138/Loading