Вопрос по seekbar, android – Как настроить ход прорисовки Android SeekBar программно

11

У меня проблема с программной настройкой прорисовки прогресса SeekBar. Когда я устанавливаю его в XML-файл, все работает нормально.

<code><SeekBar
 android:id="@+id/sb"
 android:layout_width="fill_parent"
 android:layout_height="wrap_content"
 .....
 android:progressDrawable="@drawable/seek_bar"/>
</code>

set from .xml

Но у меня есть проблема, когда я пытаюсь установить его из кода следующим образом:

<code>seekBar.setProgressDrawable(getResources().getDrawable(R.drawable.seek_bar));
</code>

Фоновое рисование затем занимает всю строку поиска, и я больше не могу изменять ход выполнения позже - большой палец перемещается, но прорисовываемый прогресс все еще заполняет всю панель поиска. Кроме того, seekbar теряет свои закругленные углы. Кажется, что прогресс рисования находится на верхней части панели поиска.

when set in code

Я попробовал решение, представленное наAndroid ProgressBar не обновляет прогресс просмотра / рисования, но это не работает для меня.

Ваш Ответ

4   ответа
9

Ответ, приведенный выше, предназначен для использования xml, но на тот случай, если кто-то захочет сделать это программно, у меня есть его ниже.

public class SeekBarBackgroundDrawable extends Drawable {

private Paint mPaint = new Paint();
private float dy;

public SeekBarBackgroundDrawable(Context ctx) {
    mPaint.setColor(Color.WHITE);
    dy = ctx.getResources().getDimension(R.dimen.one_dp);
}

@Override
public void draw(Canvas canvas) {
    canvas.drawRect(getBounds().left,getBounds().centerY()-dy/2,getBounds().right,getBounds().centerY()+dy/2,mPaint);
}

@Override
public void setAlpha(int i) {
    mPaint.setAlpha(i);
}

@Override
public void setColorFilter(ColorFilter colorFilter) {

}

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

}

Выше класс для фона панели поиска (та часть, которая всегда существует в процессе рисования прогресса)

public class SeekBarProgressDrawable extends ClipDrawable {

private Paint mPaint = new Paint();
private float dy;
private Rect mRect;


public SeekBarProgressDrawable(Drawable drawable, int gravity, int orientation, Context ctx) {
    super(drawable, gravity, orientation);
    mPaint.setColor(Color.WHITE);
    dy = ctx.getResources().getDimension(R.dimen.two_dp);
}

@Override
public void draw(Canvas canvas) {
    if (mRect==null) {
        mRect = new Rect(getBounds().left, (int)(getBounds().centerY() - dy / 2), getBounds().right, (int)(getBounds().centerY() + dy / 2));
        setBounds(mRect);
    }

    super.draw(canvas);
}


@Override
public void setAlpha(int i) {
    mPaint.setAlpha(i);
}

@Override
public void setColorFilter(ColorFilter colorFilter) {

}

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

}

Выше - прогресс, который можно нарисовать. Обратите внимание, что это клип для рисования. Крутая часть здесь - я устанавливаю границы, чтобы быть тем, что я хочу, наряду с цветом. Это позволяет точно настраивать ваш чертеж.

//Custom background drawable allows you to draw how you want it to look if needed
    SeekBarBackgroundDrawable backgroundDrawable = new SeekBarBackgroundDrawable(mContext);
    ColorDrawable progressDrawable = new ColorDrawable(Color.BLUE);
    //Custom seek bar progress drawable. Also allows you to modify appearance.
    SeekBarProgressDrawable clipProgressDrawable = new SeekBarProgressDrawable(progressDrawable,Gravity.LEFT,ClipDrawable.HORIZONTAL,mContext);
    Drawable[] drawables = new Drawable[]{backgroundDrawable,clipProgressDrawable};

    //Create layer drawables with android pre-defined ids
    LayerDrawable layerDrawable = new LayerDrawable(drawables);
    layerDrawable.setId(0,android.R.id.background);
    layerDrawable.setId(1,android.R.id.progress);

    //Set to seek bar
    seekBar.setProgressDrawable(layerDrawable);

Приведенный выше код использует пользовательские элементы рисования для редактирования панели поиска. Моя основная причина для этого заключается в том, что я буду редактировать внешний вид фона, который можно нарисовать, чтобы он имел «метки». (хотя еще не реализовано). Вы не можете сделать это с помощью отрисовки, определенной в xml (по крайней мере, не легко).

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

Я опробовал ваше решение, но вы можете отрегулировать его так, чтобы углы были закруглены? Еще более сложным является то, что его нужно округлить слева, но не справа (если это не полная шкала прогресса), хотя я не знаю, как это на самом деле работает.
Если вы ссылаетесь на фон для рисования, то можете. вместо canvas.drawRect внутри SeeBarBackgroundDrawable.draw () используйте canvas.drawRoundRect для рисования левой стороны. Затем сделайте еще один canvas.drawRect, чтобы нарисовать правую половину, которая перекрывает скругленную правую сторону круглого Rect. Это даст вам прямоугольник с закругленными краями на левой стороне и острыми краями на правой стороне.
6

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

Я просто догадываюсь здесь, но попробуйте потом установить отступ

 getResources().getDrawable(R.drawable.seek_bar) // once
 seekBar.setProgressDrawable(getResources().getDrawable(R.drawable.seek_bar)); //twice
 seekBar.setPadding(int,int,int,int)

и также не может повредить, чтобы сделать его недействительным.

 seekBar.postInvalidate()

Очень хакерский и мне это не нравится, но это решило нечто подобное для меня раньше

Только что попробовал, и это не решило проблему :( Milos Pesic
22

Я решил проблему, используя форму .xml в качестве фона для моего SeekBar. Полное решение SeekBar, которое можно использовать с помощью метода setProgressDrawable (), должно выглядеть следующим образом:

//seek_bar.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item
    android:id="@android:id/background"
    android:drawable="@drawable/seek_bar_background"/>
<item android:id="@android:id/progress"
    android:drawable="@drawable/seek_bar_progress" />
</layer-list>

//seek_bar_background.xml
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >

<gradient
    android:angle="270"
    android:startColor="#8a8c8f"
    android:endColor="#58595b" />

<corners android:radius="5dip" />

</shape>

//seek_bar_progress.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item
    android:id="@android:id/background"
    android:drawable="@drawable/seek_bar_background"/>
<item android:id="@android:id/progress">
    <clip android:drawable="@drawable/seek_bar_progress_fill" />
</item>

</layer-list>

//seek_bar_progress_fill.xml
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >

<gradient
    android:startColor="#b3d27e"       
    android:endColor="#93c044"
    android:angle="270"
 />
 <corners android:radius="5dip" />  

</shape>

В коде вы можете использовать его так:

progressBar.setProgressDrawable(getResources().getDrawable(R.drawable.seek_bar));
Отличное решение!
0

Вы можете использовать Android: maxHeight в вашем XML, чтобы ограничить высоту фона

<SeekBar
    android:id="@+id/original_volume"
    android:layout_width="120dp"
    android:layout_height="wrap_content"
    android:maxHeight="2dp"/>

и он не будет зажимать большой палец

Похожие вопросы