【发布时间】:2016-08-20 03:26:31
【问题描述】:
【问题讨论】:
-
你能得到解决方案吗,如果有请分享一下。
标签: java android progress-bar android-progressbar
【问题讨论】:
标签: java android progress-bar android-progressbar
假设你的圆圈指标都在一个设定的间隔(相距相同的距离),在我看来,以下似乎是最合乎逻辑的解决方案
您可能需要调整视图中的填充以确保您的圈子有空间。以下是您需要的简要说明:
public class TickedProgressBarView extends ProgressBar {
private static final float DEFAULT_INTERVAL = 25f;
private float INDICATOR_RADIUS;
private Paint mTickPaint;
private float mInterval; //%
public TickedProgressBarView(Context context) {
super(context);
initPainters(context, null); //because draw is called a lot of times, don't want to do loads of allocations in onDraw
}
public TickedProgressBarView(Context context, AttributeSet attrs) {
super(context, attrs);
initPainters(context, attrs);
}
public TickedProgressBarView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initPainters(context, attrs);
}
private void initPainters(Context context, @Nullable AttributeSet attrs) {
if (attrs != null) {
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TickedProgressBarView, 0, 0);
mInterval = a.getFloat(R.styleable.TickedProgressBarView_tickInterval, DEFAULT_INTERVAL);
} else {
mInterval = DEFAULT_INTERVAL;
}
//5 on the line below is HALF how many Dp wide you want the circles - ie a 10 Dp circle results from this
INDICATOR_RADIUS = 5 * getResources().getDisplayMetrics().density + 0.5f;
mTickPaint = new Paint();
mTickPaint.setColor(ContextCompat.getColor(getContext(), R.color.my_color));
mTickPaint.setStyle(Paint.Style.FILL);
mTickPaint.setStrokeCap(Paint.Cap.ROUND);
}
public void setTickInterval(float intervalPercentage) {
mInterval = intervalPercentage;
invalidate();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mInterval > 0f) {
final float midHeight = canvas.getHeight() / 2f;
final int end = canvas.getWidth();
final int intervalPx = (int) ((end / 100f) * mInterval);
int nextInterval = intervalPx;
while (nextInterval <= end) {
canvas.drawCircle(nextInterval, midHeight, INDICATOR_RADIUS, mTickPaint);
nextInterval += intervalPx;
}
}
}
}
attrs.xml
<declare-styleable name="TickedProgressBarView">
<attr name="tickInterval" format="float" />
</declare-styleable>
attr 声明允许您使用来自 xml 的视图
<!-- draw a circle every 10% along the bar -->
<com.my.packge.TickedProgressBarView
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tickInterval="10.0"
/>
【讨论】:
您需要为进度条创建自定义 xml 布局,并在 Runnable 或使用 AsyncTask 中进行计算
【讨论】:
最好使用custom view 来实现这一点。要设置进度,您可以定义如下所示的设置器,它使视图无效并调用 onDraw()。
public class CustomProgressBar extends View {
// constructors etc...
void setProgress(int progress) {
if (progress < 0 || progress > 100) {
throw new IllegalArgumentException("Progress must be between 0-100!");
}
this.progress = progress.
invalidate(); // tell view to redraw itself
}
}
下一步是绘制表示进度的视图部分和表示剩余工作的部分。
final Paint progressPaint = new Paint();
progressPaint.setColor(Color.RED); // could draw a bitmap or whatever, this is a simple example
@Override protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR); // clear previous contents
float progressW = getWidth() * (progress / 100);
float remainingW = getWidth() - progressPortion;
canvas.drawRect(0, 0, progressW, getHeight(), progressPaint);
canvas.drawRect(progressW, 0, remainingW, getHeight(), remainingPaint);
}
最后,您可以计算圆形指示器的位置,在 onDraw() 中将它们绘制到画布上。
final float radius = 5;
final float circleCount = 6;
float unit = getWidth() / circleCount;
float offset = 0;
for (int i=0; i<6; i++) {
canvas.drawCircle(offset + (radius / 2), getHeight() / 2, radius, circlePaint);
}
如果您需要有条件地显示指标,您可以简单地在 onDraw() 方法中添加一个检查,以查看进度是否超过某个阈值。
【讨论】:
试试这个-
你的带有进度条的 xml-
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android:id="@+id/progress_frame" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingEnd="16dp"
android:layout_marginTop="10dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingStart="16dp">
<ProgressBar
android:id="@+id/flight_progress"
style="@style/flght.progress.style"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginBottom="10dp"
android:layout_marginTop="10dp"
android:max="100"
android:visibility="visible"/>
<LinearLayout android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:orientation="horizontal">
<LinearLayout android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content">
<ImageView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right|end"
android:src="@drawable/blue_circle"/>
</LinearLayout>
<LinearLayout android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content">
<ImageView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right|end"
android:src="@drawable/blue_circle"/>
</LinearLayout>
<LinearLayout android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content">
<ImageView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right|end"
android:src="@drawable/blue_circle"/>
</LinearLayout>
<LinearLayout android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content">
<ImageView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right|end"
android:src="@drawable/blue_circle"/>
</LinearLayout>
<LinearLayout android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content">
<ImageView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right|end"
android:src="@drawable/blue_circle"/>
</LinearLayout>
<ImageView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right|end"
android:src="@drawable/blue_circle"/>
</LinearLayout>
</RelativeLayout>
将此添加到 styles.xml-
<style name="flght.progress.style" parent="android:Widget.ProgressBar.Horizontal">
<item name="android:indeterminateOnly">false</item>
<item name="android:progressDrawable">@drawable/flight_cylinder_progress_bar</item>
<item name="android:minHeight">8dip</item>
<item name="android:maxHeight">24dip</item>
<item name="android:minWidth">20dip</item>
<item name="android:maxWidth">80dip</item>
</style>
接下来将这个flight_cylinder_progress_bar添加到drawable文件夹中-
<?xml version="1.0" encoding="UTF-8"?>
<layer-list
xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@android:id/background">
<shape>
<corners
android:radius="5dip"/>
<gradient
android:angle="270"
android:centerColor="#ffdddddd"
android:centerY="0.50"
android:endColor="#ffdddddd"
android:startColor="#ffdddddd"/>
</shape>
</item>
<item
android:id="@android:id/secondaryProgress">
<clip>
<shape>
<corners
android:radius="5dip"/>
<gradient
android:angle="90"
android:endColor="@color/orange_dark"
android:startColor="@color/my_orange"/>
</shape>
</clip>
</item>
<item
android:id="@android:id/progress">
<clip>
<shape>
<corners
android:radius="5dip"/>
<gradient
android:angle="90"
android:endColor="@color/my_orange"
android:startColor="@color/orange_dark"/>
</shape>
</clip>
</item>
</layer-list>
最后是 drawable 文件夹中的 blue_circle.xml -
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid android:color="@color/goibibo_blue"/>
<size android:width="10dp"
android:height="10dp"/>
</shape>
以上是输出。您现在可以简单地调整颜色。
【讨论】: