2012-05-10 3 views
10

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

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

set from .xml

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

seekBar.setProgressDrawable(getResources().getDrawable(R.drawable.seek_bar)); 

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

when set in code

Я попробовал решение, предложенное на android progressBar does not update progress view/drawable, но она не работает для меня.

Помощь оценили,

Милош

ответ

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

Отличное решение! – jbc25

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() 

Очень Hacky, и я не люблю его, но он решил что-то подобное для меня, прежде чем

+1

Просто попробовал, и это не решило проблему :( –

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; 
} 

}

Над класса для фона SeekBar (та часть, которая всегда существует при ходе Drawable)

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, определяемого drawable (по крайней мере, не так легко).

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

+0

Я опробовал ваше решение, но вы можете его отрегулировать так, чтобы углы округлялись? Еще более сложным является его округление слева, но не справа (если он не является полным индикатором выполнения), хотя я не знаю, как это работает. – user1122069

+0

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

Смежные вопросы