效果:
findViewById<FlickerProgressBar>(R.id.flicker_view).apply {
//设置动画模式(0:左侧进入,1:右侧进入)
setFlickerAnimMode(0)
//设置滑块是否可用,是否显示
setIndicatorScrollEnable(true, View.VISIBLE)
post{
setProgress(60)
startAnim()
}
//设置动画模式(0:左侧进入,1:右侧进入)
// setFlickerAnimMode(0)
// //设置指示线位置0-100,受最大最小有效值(可滑动位置)范围限制
// setIndicatorProgress(60)
// //设置最小滑块可滑动位置0-100
// setMinScrollProgress(20)
// //设置最大滑块可滑动位置0-100
// setMaxScrollProgress(80)
//设置当前进度0-100,需要在控件加载并绘制完成时调用
// setProgress(60)
// //执行动画
// startAnim()
// //停止动画
// stopAnim()
// //获取当前指示线位置,参数为真实指到10次幂(1:progress * 10, 2:progeress * 100)
// getIndicatorProgress(1)
// //设置指示线位置,不受最大最小有效值(可滑动位置)范围限制
// setIndicatorProgressForce(90)
// //设置滑块是否可用,是否显示
// setIndicatorScrollEnable(true, View.VISIBLE)
}.setOnInticatorScrollListener(object : FlickerProgressBar.OnInticatorScrollListener {
override fun onIndicatorUpListener(progress: Int) {
textView.setText(String.format("目标值:%d%%", progress))
}
override fun excuteOnListener(progress: Int) {
//滑动后,不再滑动3秒后结果
}
})
findViewById<FlickerProgressBar>(R.id.flicker_right_view).apply {
//设置动画模式(0:左侧进入,1:右侧进入)
setFlickerAnimMode(1)
//设置滑块是否可用,是否显示
setIndicatorScrollEnable(true, View.VISIBLE)
postDelayed({
setProgress(70)
startAnim()
}, 0)
}.setOnInticatorScrollListener(object : FlickerProgressBar.OnInticatorScrollListener {
override fun onIndicatorUpListener(progress: Int) {
textView.setText(String.format("目标值:%d%%", progress))
}
override fun excuteOnListener(progress: Int) {
//滑动后,不再滑动3秒后结果
}
})
IndicatorScrollView
package com.example.flickerprogressbar;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
public class IndicatorScrollView extends View {
private Bitmap indicatorBitmap;
private float moveX;
private Paint indicatorPaint;
private float mMinLeft;
private float mMaxLeft;
private OnInticationScrollListener onInticationScrollListener;
private boolean mSrollEnable;
private int indicatorBitmapSize = dp2px(10);
private int mFlickerAnimMode = 0;
private int mIndicatorLineWidth = dp2px(1);
//<editor-fold desc="像素密度">
private static float density = Resources.getSystem().getDisplayMetrics().density;
/**
* 根据手机的分辨率从 dp 的单位 转成为 px(像素)
* @param dpValue 虚拟像素
* @return 像素
*/
public static int dp2px(float dpValue) {
return (int) (0.5f + dpValue * density);
}
/**
* 根据手机的分辨率从 px(像素) 的单位 转成为 dp
* @param pxValue 像素
* @return 虚拟像素
*/
public static float px2dp(int pxValue) {
return (pxValue / density);
}
public IndicatorScrollView(Context context) {
super(context);
initIndicatorBimap();
}
public IndicatorScrollView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
initIndicatorBimap();
}
private void initIndicatorBimap() {
indicatorPaint = new Paint();
indicatorBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher_round);
int width = indicatorBitmap.getWidth();
int height = indicatorBitmap.getHeight();
// 设置想要的大小
int newWidth = indicatorBitmapSize;
int newHeight = indicatorBitmapSize;
// 计算缩放比例
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
// 取得想要缩放的matrix参数
Matrix matrix = new Matrix();
matrix.postScale(scaleWidth, scaleHeight);
// 得到新的图片
indicatorBitmap = Bitmap.createBitmap(indicatorBitmap, 0, 0, width, height, matrix, true);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawBitmap(indicatorBitmap, moveX+(indicatorBitmapSize)/2, 0, indicatorPaint);
}
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
return super.dispatchTouchEvent(event);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if(!mSrollEnable) return false;
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
break;
case MotionEvent.ACTION_MOVE:
moveX = Math.min(Math.max(event.getX(), mMinLeft), mMaxLeft);
if(onInticationScrollListener != null){
onInticationScrollListener.onInticationScrollListener(moveX - (indicatorBitmapSize-mIndicatorLineWidth)/2);
}
invalidate();
break;
case MotionEvent.ACTION_UP:
break;
case MotionEvent.ACTION_CANCEL:
break;
}
return true;
}
public void setMinLeftX(float left) {
mMinLeft = left;
}
public void setMaxLeftX(float right) {
mMaxLeft = right;
}
public void setIndicatorLeftX(float progressXValue){
if(mFlickerAnimMode == 0){
moveX = Math.max(progressXValue, mMinLeft);
}else {
moveX = Math.min(progressXValue, mMaxLeft);
}
if(onInticationScrollListener != null){
onInticationScrollListener.onInticationScrollListener(progressXValue - (indicatorBitmapSize-mIndicatorLineWidth)/2);
}
invalidate();
}
public void setIndicatorLeftXForce(float progressXValue){
moveX = progressXValue;
if(onInticationScrollListener != null){
onInticationScrollListener.onInticationScrollListener(progressXValue - (indicatorBitmapSize-mIndicatorLineWidth)/2);
}
invalidate();
}
public void setOnScrollListener() {
}
public void setScrollEnable(boolean enable) {
mSrollEnable = enable;
}
public void setIndicatorLineWidth(int width) {
mIndicatorLineWidth = width;
}
interface OnInticationScrollListener{
void onInticationScrollListener(float left);
}
public void setOnInticationScrollListener(OnInticationScrollListener onInticationScrollListener) {
this.onInticationScrollListener = onInticationScrollListener;
}
public void setFlickerAnimMode(int flickerAnimMode) {
this.mFlickerAnimMode = flickerAnimMode;
}
}
FlickerProgressBar
package com.example.flickerprogressbar;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.TranslateAnimation;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
public class FlickerProgressBar extends LinearLayout {
private int baseProgressWidth = dp2px(170);
private int baseProgressHigth = dp2px(41);
private View flickerProgressView;
private ImageView fliker_iv;
private ImageView progress_view;
private View indicator_line;
private View fliker_iv_layout;
private IndicatorScrollView indicatorScrollView;
private int mProgress;
private float mMaxProgress = 100;
private int mIndicatorScrollViewHeight = dp2px(20);
private long mAnimDuration = 1700;
private int mWidth;
private int mHeight;
private int mProgressViewWight;
private int mProgressXValue;
private View progress_bar_layout;
private int mProgressViewLeft;
private boolean isNeedToResetAnim;
/**
*
*/
private int mFlickerAnimMode = 0;
private int mIndicatorLineColor;
private Drawable mIndicatorLineDrawable;
private Drawable mDefaultProgressDrawable;
private Drawable mLowProgressDrawable;
private Drawable mMediumPowerProgressDrawable;
private int mLowProgressValue;
private int mMediumPowerValue;
private OnInticatorScrollListener onInticatorScrollListener;
private static int mExcuteTimerDown = 2;
private long mLastHandlerTime = 0;
private int mIndicatorProgress;
private int mMinScrollProgress = 0;
private int mMaxScrollProgress = 100;
private int mMinIndicatorProgress = 0;
//<editor-fold desc="像素密度">
private static float density = Resources.getSystem().getDisplayMetrics().density;
/**
* 根据手机的分辨率从 dp 的单位 转成为 px(像素)
* @param dpValue 虚拟像素
* @return 像素
*/
public static int dp2px(float dpValue) {
return (int) (0.5f + dpValue * density);
}
/**
* 根据手机的分辨率从 px(像素) 的单位 转成为 dp
* @param pxValue 像素
* @return 虚拟像素
*/
public static float px2dp(int pxValue) {
return (pxValue / density);
}
private Handler mHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
mExcuteTimerDown -=1;
if(mExcuteTimerDown > 0){
mHandler.sendEmptyMessageDelayed(0, 1000);
}else {
if(onInticatorScrollListener != null){
onInticatorScrollListener.excuteOnListener(mIndicatorProgress);
}
}
}
};
private boolean mSrollEnable = true;
private int mIndicatorLineWidth;
public FlickerProgressBar(Context context) {
super(context);
initView();
}
public FlickerProgressBar(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
initAttrs(attrs);
initView();
}
public FlickerProgressBar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initAttrs(attrs);
initView();
}
private void initAttrs(AttributeSet attrs) {
TypedArray ta = getContext().obtainStyledAttributes(attrs, R.styleable.FlickerProgressBar);
try {
mIndicatorLineColor = ta.getColor(R.styleable.FlickerProgressBar_indicatorLineColor, Color.parseColor("#80FFFFFF"));
mIndicatorLineDrawable = ta.getDrawable(R.styleable.FlickerProgressBar_indicatorLineDrawable);
mDefaultProgressDrawable = ta.getDrawable(R.styleable.FlickerProgressBar_progressDrawable);
mLowProgressDrawable = ta.getDrawable(R.styleable.FlickerProgressBar_lowProgressDrawable);
mMediumPowerProgressDrawable = ta.getDrawable(R.styleable.FlickerProgressBar_mediumProgressDrawable);
mLowProgressValue = ta.getColor(R.styleable.FlickerProgressBar_lowProgressValue, 8);
mMediumPowerValue = ta.getColor(R.styleable.FlickerProgressBar_mediumProgressValue, 20);
if(mDefaultProgressDrawable == null){
mDefaultProgressDrawable = getDefaultProgressDrawable();
mLowProgressDrawable = getDefaultProgressDrawable();
mMediumPowerProgressDrawable = getDefaultProgressDrawable();
}
mFlickerAnimMode = ta.getColor(R.styleable.FlickerProgressBar_flickerMode, 0);
} finally {
ta.recycle();
}
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
mHandler.removeCallbacksAndMessages(null);
}
private void initView() {
setOrientation(VERTICAL);
setGravity(Gravity.CENTER_HORIZONTAL);
addView(initFlickerProgressBar());
addView(initScrollView());
}
@Override protected void onFinishInflate() {
super.onFinishInflate();
setIndicatorProgressForce(mProgress);
mProgressViewWight = progress_bar_layout.getWidth();
mProgressViewLeft = progress_bar_layout.getLeft();
if(mFlickerAnimMode == 0){
indicatorScrollView.setMinLeftX(getProgressXValue(mMinScrollProgress) + mProgressViewLeft);
indicatorScrollView.setMaxLeftX(mProgressViewWight + mProgressViewLeft);
}else {
indicatorScrollView.setMinLeftX(getProgressXValue(mMinScrollProgress) + mProgressViewLeft);
indicatorScrollView.setMaxLeftX(getProgressXValue(mMinScrollProgress) + mProgressViewLeft);
}
indicator_line.post(() -> {
mIndicatorLineWidth = indicator_line.getWidth();
indicatorScrollView.setIndicatorLineWidth(mIndicatorLineWidth);
});
}
private View initScrollView() {
indicatorScrollView = new IndicatorScrollView(getContext());
indicatorScrollView.setFlickerAnimMode(mFlickerAnimMode);
indicatorScrollView.setOnInticationScrollListener(new IndicatorScrollView.OnInticationScrollListener() {
@Override
public void onInticationScrollListener(float left) {
if(indicator_line != null){
if(mFlickerAnimMode == 0){
indicator_line.setTranslationX(left);
}else {
indicator_line.setTranslationX(left);
}
}
int denominator = mProgressViewWight - mIndicatorLineWidth/2;
if(mFlickerAnimMode == 0){
mIndicatorProgress = Math.max(Math.min((int)(((left / denominator)+0.005) * 100), 100), mMinScrollProgress);
}else {
mIndicatorProgress = Math.min(Math.max((int)(((left / denominator)+0.005) * 100), mMinScrollProgress), mMaxScrollProgress);
}
if(onInticatorScrollListener != null){
onInticatorScrollListener.onIndicatorUpListener(mIndicatorProgress);
}
}
});
return indicatorScrollView;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
initFlickerProgressBarSize(getMeasuredWidth() - mIndicatorScrollViewHeight, getMeasuredHeight() - mIndicatorScrollViewHeight);
initIndicationScrollViewSize(getMeasuredWidth(), mIndicatorScrollViewHeight);
}
View initFlickerProgressBar(){
flickerProgressView = LayoutInflater.from(getContext()).inflate(R.layout.layout_flicker_progress, this, false);
fliker_iv = flickerProgressView.findViewById(R.id.fliker_iv);
progress_view = flickerProgressView.findViewById(R.id.progress_view);
progress_bar_layout = flickerProgressView.findViewById(R.id.progress_bar_layout);
indicator_line = flickerProgressView.findViewById(R.id.indicator_line);
fliker_iv_layout = flickerProgressView.findViewById(R.id.fliker_iv_layout);
fliker_iv_layout.setVisibility(View.INVISIBLE);
progress_view.setBackground(mDefaultProgressDrawable);
if(mIndicatorLineDrawable != null){
indicator_line.setBackground(mIndicatorLineDrawable);
}else {
indicator_line.setBackgroundColor(mIndicatorLineColor);
}
if(mFlickerAnimMode == 0){
fliker_iv.setImageResource(R.drawable.ic_flicker_left);
}else {
fliker_iv.setImageResource(R.drawable.ic_flicker_right);
}
return flickerProgressView;
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mWidth = w;
mHeight = h;
}
private void initFlickerProgressBarSize(int progressViewWight, int progressViewHeight) {
ViewGroup.LayoutParams layoutParams = flickerProgressView.getLayoutParams();
if(layoutParams != null){
layoutParams.height = progressViewHeight;
layoutParams.width = progressViewWight;
flickerProgressView.setLayoutParams(layoutParams);
}else {
layoutParams = new LayoutParams(progressViewWight, progressViewHeight);
flickerProgressView.setLayoutParams(layoutParams);
}
}
private void initIndicationScrollViewSize(int w, int h) {
ViewGroup.LayoutParams layoutParams = indicatorScrollView.getLayoutParams();
if(layoutParams != null){
layoutParams.width = w;
layoutParams.height = h;
indicatorScrollView.setLayoutParams(layoutParams);
}else {
layoutParams = new LayoutParams(w, h);
indicatorScrollView.setLayoutParams(layoutParams);
}
}
public void setProgress(int progress){
mProgressViewWight = progress_bar_layout.getWidth();
mProgressViewLeft = progress_bar_layout.getLeft();
mProgress = Math.max(progress, 0);
mProgressXValue = getProgressXValue(progress);
ViewGroup.LayoutParams layoutParams = fliker_iv_layout.getLayoutParams();
if(layoutParams != null){
layoutParams.width = mProgressXValue;
layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT;
}else {
layoutParams = new FrameLayout.LayoutParams(getProgressXValue(progress), FrameLayout.LayoutParams.MATCH_PARENT);
}
fliker_iv_layout.setLayoutParams(layoutParams);
progress_view.setLayoutParams(layoutParams);
updateProgressColor(progress);
if(indicatorScrollView != null){
if(mFlickerAnimMode == 0){
indicatorScrollView.setMinLeftX(Math.max(mProgressXValue, getProgressXValue(mMinScrollProgress)) + mProgressViewLeft);
indicatorScrollView.setMaxLeftX(mProgressViewWight + mProgressViewLeft);
}else {
indicatorScrollView.setMinLeftX(getProgressXValue(mMinScrollProgress) + mProgressViewLeft);
indicatorScrollView.setMaxLeftX(Math.max(mProgressXValue, getProgressXValue(mMinScrollProgress)) + mProgressViewLeft);
}
}
isNeedToResetAnim = true;
}
private void updateProgressColor(int progress){
if(progress_view != null){
if(progress <= mLowProgressValue){
progress_view.setImageDrawable(mLowProgressDrawable);
}else if(progress <= mMediumPowerValue){
progress_view.setImageDrawable(mMediumPowerProgressDrawable);
}else {
progress_view.setImageDrawable(mDefaultProgressDrawable);
}
}
}
public void setIndicatorProgress(int progress){
progress_bar_layout.post(new Runnable() {
@Override
public void run() {
mIndicatorLineWidth = indicator_line.getWidth();
mProgressViewWight = progress_bar_layout.getWidth();
mProgressViewLeft = progress_bar_layout.getLeft();
indicatorScrollView.setIndicatorLineWidth(mIndicatorLineWidth);
indicatorScrollView.setIndicatorLeftX(getProgressXValue(progress) + mProgressViewLeft);
}
});
}
public void setIndicatorProgressForce(int progress){
progress_bar_layout.post(new Runnable() {
@Override
public void run() {
mIndicatorLineWidth = indicator_line.getWidth();
mProgressViewWight = progress_bar_layout.getWidth();
mProgressViewLeft = progress_bar_layout.getLeft();
indicatorScrollView.setIndicatorLineWidth(mIndicatorLineWidth);
indicatorScrollView.setIndicatorLeftXForce(getProgressXValue(progress) + mProgressViewLeft);
}
});
}
public int getProgressXValue(int progress){
return (int) (progress / mMaxProgress * mProgressViewWight);
}
Drawable getDefaultProgressDrawable(){
int[] colors = {Color.YELLOW, Color.GREEN, Color.BLUE};
GradientDrawable gradientDrawable = new GradientDrawable();
gradientDrawable.setShape(GradientDrawable.RECTANGLE);
gradientDrawable.setColors(colors); //添加颜色组
gradientDrawable.setGradientType(GradientDrawable.LINEAR_GRADIENT);//设置线性渐变
gradientDrawable.setOrientation(GradientDrawable.Orientation.RIGHT_LEFT);//设置渐变方向
gradientDrawable.setCornerRadius(dp2px(2));
// gradientDrawable.setCornerRadii(new float[]{dp2px(2),dp2px(2), 0, 0, 0, 0, dp2px(2), dp2px(2)});
gradientDrawable.setCornerRadius(2);
return gradientDrawable;
}
public void setIndicatorScrollEnable(boolean enable, int visibility){
mSrollEnable = enable;
if(indicator_line != null){
indicator_line.setVisibility(visibility);
}
if(indicatorScrollView != null){
indicatorScrollView.setVisibility(visibility);
indicatorScrollView.setScrollEnable(enable);
}
}
public void startAnim(){
if(fliker_iv_layout != null) fliker_iv_layout.setVisibility(View.VISIBLE);
if(mFlickerAnimMode == 0){
resetAnim(dp2px(-41), mProgressXValue);
}else {
resetAnim(mProgressXValue, dp2px(-41));
}
}
public void stopAnim(){
if(fliker_iv != null && fliker_iv.getAnimation() != null){
fliker_iv.getAnimation().cancel();
fliker_iv_layout.setVisibility(View.INVISIBLE);
}
}
void resetAnim(float fromXValue, float toXValue){
TranslateAnimation translateAnimation = new TranslateAnimation(Animation.ABSOLUTE, fromXValue, Animation.ABSOLUTE, toXValue, Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 0);
translateAnimation.setFillBefore(true);
translateAnimation.setRepeatCount(-1);
translateAnimation.setDuration(mAnimDuration);
fliker_iv.setAnimation(translateAnimation);
fliker_iv.getAnimation().setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
Log.d("FlickerProgressBar", "onAnimationStart");
}
@Override
public void onAnimationEnd(Animation animation) {
Log.d("FlickerProgressBar", "onAnimationEnd");
}
@Override
public void onAnimationRepeat(Animation animation) {
Log.d("FlickerProgressBar", "onAnimationRepeat");
if(isNeedToResetAnim){
animation.cancel();
isNeedToResetAnim = false;
startAnim();
}
}
});
fliker_iv.getAnimation().start();
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return true;
}
public void setFlickerAnimMode(int flickerAnimMode) {
this.mFlickerAnimMode = flickerAnimMode;
if(mFlickerAnimMode == 0){
setMinScrollProgress(50);
setMinIndicatorProgress(50);
fliker_iv.setImageResource(R.drawable.ic_flicker_left);
}else {
setMinScrollProgress(20);
setMinIndicatorProgress(20);
fliker_iv.setImageResource(R.drawable.ic_flicker_right);
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if(!mSrollEnable || (mFlickerAnimMode == 1 && mProgress < mMinIndicatorProgress)) {
return false;
}
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
mHandler.removeMessages(0);
getParent().requestDisallowInterceptTouchEvent(true);
break;
case MotionEvent.ACTION_UP:
if(System.currentTimeMillis() - mLastHandlerTime > 1000){
mLastHandlerTime = System.currentTimeMillis();
mHandler.sendEmptyMessageDelayed(0, 1000);
}
break;
}
indicatorScrollView.onTouchEvent(event);
return true;
}
public void setMinScrollProgress(int progress) {
this.mMinScrollProgress = progress;
setIndicatorProgressForce(progress);
}
public void setMaxScrollProgress(int progress) {
this.mMaxScrollProgress = progress;
}
public int getmMinIndicatorProgress() {
return mMinIndicatorProgress;
}
public void setMinIndicatorProgress(int mMinIndicatorProgress) {
this.mMinIndicatorProgress = mMinIndicatorProgress;
}
public double getIndicatorProgress(int ratio) {
return mIndicatorProgress * Math.pow(10, ratio);
}
public interface OnInticatorScrollListener {
void onIndicatorUpListener(int progress);
void excuteOnListener(int progress);
}
public void setOnInticatorScrollListener(OnInticatorScrollListener onInticatorScrollListener) {
this.onInticatorScrollListener = onInticatorScrollListener;
}
}
layout_flicker_progress.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/charge_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="@drawable/ic_flicker_view_bg">
<android.support.constraint.Guideline
android:id="@+id/top_guideline"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintGuide_percent="0.1463"
android:orientation="horizontal"/>
<android.support.constraint.Guideline
android:id="@+id/bottom_guideline"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintGuide_percent="0.8536"
android:orientation="horizontal"/>
<android.support.constraint.Guideline
android:id="@+id/left_guideline"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintGuide_percent="0.02352"
android:orientation="vertical"/>
<android.support.constraint.Guideline
android:id="@+id/right_guideline"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintGuide_percent="0.9470"
android:orientation="vertical"/>
<FrameLayout
android:id="@+id/progress_bar_layout"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@+id/bottom_guideline"
app:layout_constraintEnd_toStartOf="@+id/right_guideline"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="@+id/left_guideline"
app:layout_constraintTop_toBottomOf="@+id/top_guideline">
<ImageView
android:id="@+id/progress_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:background="@drawable/ic_progress_bg"
/>
</FrameLayout>
<View
android:id="@+id/indicator_line"
android:layout_width="1dp"
android:layout_height="0dp"
android:background="#80FFFFFF"
app:layout_constraintBottom_toTopOf="@+id/bottom_guideline"
app:layout_constraintEnd_toStartOf="@+id/right_guideline"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="@+id/left_guideline"
app:layout_constraintTop_toBottomOf="@+id/top_guideline" />
<FrameLayout
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@+id/bottom_guideline"
app:layout_constraintTop_toBottomOf="@+id/top_guideline"
app:layout_constraintEnd_toStartOf="@+id/right_guideline"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="@+id/left_guideline">
<FrameLayout
android:id="@+id/fliker_iv_layout"
android:layout_width="wrap_content"
android:layout_height="match_parent"
>
<ImageView
android:id="@+id/fliker_iv"
android:layout_width="41dp"
android:layout_height="match_parent"
android:scaleType="fitXY"
android:src="@drawable/ic_flicker_left" />
</FrameLayout>
</FrameLayout>
</android.support.constraint.ConstraintLayout>
bg_low_progress.xml
<?xml version="1.0" encoding="utf-8"?>
<shape android:shape="rectangle"
xmlns:android="http://schemas.android.com/apk/res/android">
<gradient
android:startColor="#9A0035"
android:endColor="#FF266F"/>
<corners android:radius="1dp" />
</shape>
bg_medium_progress.xml
<?xml version="1.0" encoding="utf-8"?>
<shape android:shape="rectangle"
xmlns:android="http://schemas.android.com/apk/res/android">
<gradient
android:startColor="#BE771B"
android:endColor="#FFB34B"/>
<corners android:radius="1dp" />
</shape>
bg_progress.xml
<?xml version="1.0" encoding="utf-8"?>
<shape android:shape="rectangle"
xmlns:android="http://schemas.android.com/apk/res/android">
<gradient
android:startColor="#05c29c"
android:endColor="#0CE3CB"/>
<corners android:radius="1dp" />
</shape>
ic_flicker_left.xml
<?xml version="1.0" encoding="utf-8"?>
<shape android:shape="rectangle"
xmlns:android="http://schemas.android.com/apk/res/android">
<gradient
android:startColor="#00000000"
android:endColor="#ffffff"/>
</shape>
ic_flicker_right.xml
<?xml version="1.0" encoding="utf-8"?>
<shape android:shape="rectangle"
xmlns:android="http://schemas.android.com/apk/res/android">
<gradient
android:startColor="#ffffff"
android:endColor="#00000000"/>
</shape>
ic_flicker_view_bg.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#80000000"/>
<stroke
android:width="1dp"
android:color="#80ffffff" />
<corners android:radius="1dp" />
</shape>
ic_progress_bg.xml
<?xml version="1.0" encoding="utf-8"?>
<shape android:shape="rectangle"
xmlns:android="http://schemas.android.com/apk/res/android">
<gradient
android:startColor="#05c29c"
android:endColor="#0CE3CB"/>
<corners android:radius="1dp" />
</shape>
attrs.xml
<declare-styleable name="FlickerProgressBar">
<attr name="indicatorLineColor" format="color"/>
<attr name="indicatorLineDrawable" format="integer"/>
<attr name="progressDrawable" format="integer"/>
<attr name="lowProgressDrawable" format="integer"/>
<attr name="mediumProgressDrawable" format="integer"/>
<attr name="lowProgressValue" format="integer"/>
<attr name="mediumProgressValue" format="integer"/>
<attr name="flickerMode" format="integer">
<enum name="fromLeft" value="0"/>
<enum name="fromRight" value="1"/>
</attr>
</declare-styleable>