Drawable Progress Bar не подходит - PullRequest
       73

Drawable Progress Bar не подходит

0 голосов
/ 11 января 2019

Я пытаюсь реализовать следующий индикатор выполнения: enter image description here

и результат, который я получаю: enter image description here

Проблема здесь в том, что линии не помещаются в индикатор выполнения, поскольку это ясно в левой и правой части изображения. Причина в том, что я использую высоту и ширину индикатора выполнения для рисования линий, но индикатор выполнения имеет угловой радиус, который не учитывается при получении высоты и ширины. '

Я попытался добавить отступы в строку progrss, но я не хочу пустого места, как показано на первом изображении выше.

Вот мои основные занятия:

ProgressDrawable.java

class ProgressDrawable extends Drawable {
private static final int NUM_LINES = 60;

private Paint mPaint = new Paint();
private ProgressBar progressBar;

public ProgressDrawable(Context context, ProgressBar progressBar){
    super();
    init(context);

    this.progressBar = progressBar;
}

@Override
protected boolean onLevelChange(int level) {
    invalidateSelf();
    return true;
}

@Override
public void draw(Canvas canvas) {
    float width = progressBar.getWidth();
    float height = progressBar.getHeight();
    for (int i = 0; i < NUM_LINES; i++) {
        float startX = width * i / NUM_LINES;
        float stopX = startX + 2f * width / NUM_LINES;
        //mPaint.setColor((i + 1) * 10000 / NUM_LINES <= getLevel()? 0xff888888 : 0xCACACA);
        mPaint.setShader((i + 1) * 10000 / NUM_LINES <= getLevel()? new LinearGradient(0, 0, 0, height, Color.parseColor("#77F5FF"), Color.parseColor("#31AFF5"), Shader.TileMode.MIRROR) : new LinearGradient(0, 0, 0, height, Color.parseColor("#D9D9D9"), Color.parseColor("#D9D9D9"), Shader.TileMode.MIRROR));
        canvas.drawLine(startX, height, stopX, 0, mPaint);
    }
}

@Override
public void setAlpha(int alpha) {
}

@Override
public void setColorFilter(ColorFilter cf) {
}

@Override
public int getOpacity() {
    return PixelFormat.TRANSLUCENT;
}

private void init(Context context)
{
    Resources resources = context.getResources();
    mPaint = new Paint();
    mPaint.setAntiAlias(true);
    mPaint.setStrokeWidth(resources.getDimension(R.dimen.vertical_divider_width));
}
}

MainActivity.java

public class MainActivity extends AppCompatActivity {

LinearLayout mainLayout;
ProgressBar pb;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mainLayout = findViewById(R.id.mainLayout);

    LinearLayout ll = new LinearLayout(this);
    ll.setOrientation(LinearLayout.VERTICAL);

    mainLayout.addView(ll);

    pb = findViewById(R.id.progressBar);
    Drawable d = new ProgressDrawable(this, pb);
    pb.setProgressDrawable(d);

    SeekBar.OnSeekBarChangeListener l = new SeekBar.OnSeekBarChangeListener() {
        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {
        }

        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {
        }

        @Override
        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
            int newProgress = pb.getMax() * progress / seekBar.getMax();
            Log.d(MainActivity.class.getSimpleName(), "onProgressChanged " + newProgress);
            pb.setProgress(newProgress);
        }
    };

    startProgress();
}
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/mainLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity" android:orientation="vertical" android:gravity="center">

<ProgressBar
        android:id="@+id/progressBar"
        android:layout_width="600dp"
        android:layout_height="50dp"
        android:max="60"
        style="?android:attr/progressBarStyleHorizontal"
        android:background="@drawable/rounded_layout"/>
</LinearLayout>

rounded_layout.xml

<shape xmlns:android="http://schemas.android.com/apk/res/android"
   android:shape="rectangle">
   <solid android:color="#D9D9D9"/>
   <corners android:radius="15dp" />
</shape>

Любая помощь будет высоко оценена.

Заранее спасибо.

1 Ответ

0 голосов
/ 11 января 2019

Спасибо за ответ @ 0X0nousugar на этот вопрос .

Обрезка холста была правильной, но моя главная ошибка в том, что я рисовал линии холстом, округленная форма индикатора выполнения выполняется в формате XML. Мое решение состояло в том, чтобы удалить файл roundnded_layout.xml в качестве фона строки предварительного рисунка, нарисовать обрезанный прямоугольник, а затем обязательно нарисовать линии внутри него.

Ниже приведен фрагмент кода:

@Override
public void draw(Canvas canvas) {
    mPaint = new Paint();
    mPaint.setAntiAlias(true);
    // get the height and width of the progress bar
    float width = progressBar.getWidth();
    float height = progressBar.getHeight();
    Path rectPath = new Path();
    RectF rect = new RectF(0, 0, 0,0);
    // set the size of the rectangle to the size of the progress bar
    rect.set(0, 0, width, height);
    // set the corner radius (mine is 15) to have a rounded rectangle
    rectPath.addRoundRect(rect, 15, 15, Path.Direction.CW);
    // set the color for the rectangle
    mPaint.setColor(Color.parseColor("#D9D9D9"));
    // clip and draw the rectangle
    canvas.clipPath(rectPath);
    canvas.drawRect(rect, mPaint);
    // a loop to create the lines inside the rectangle, one at a time
    for (int i = 0; i < NUM_LINES; i++) {
        float startX = width * i / NUM_LINES;
        float stopX = startX + 2f * width / NUM_LINES;
        mPaint.setShader((i + 1) * 10000 / NUM_LINES <= getLevel()? 
                         new LinearGradient(0, 0, 0, height, 
                         Color.parseColor("#77F5FF"), Color.parseColor("#31AFF5"), 
                         Shader.TileMode.MIRROR) : new LinearGradient(0, 0, 0, 
                         height, Color.parseColor("#D9D9D9"), 
                         Color.parseColor("#D9D9D9"), Shader.TileMode.MIRROR));
                         canvas.drawLine(startX, height, stopX, 0, mPaint);
    }
}

Примечание. Убедитесь, что все линии нарисованы в прямоугольнике.

...