2012-05-10 11 views
10

Ho un problema con l'impostazione programmatica del progresso del drawable di SeekBar. Quando lo imposto nel file .xml tutto funziona correttamente.Come impostare progressivamente il progresso di Android SeekBar disegnabile

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

set from .xml

Ma, ho un problema quando si tenta di impostare da codice come questo:

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

Sfondo drawable poi prende l'intera barra di ricerca, e io non sono in grado di modificare il progresso in qualsiasi momento successivo - il pollice si sposta ma il drawable del progresso riempie ancora l'intera barra di ricerca. Inoltre, la barra di ricerca perde gli angoli arrotondati. Sembra che il progresso drawable sia in cima alla barra di ricerca.

when set in code

Ho provato la soluzione fornita su android progressBar does not update progress view/drawable, ma non funziona per me.

aiuto apprezzato,

Milos

risposta

22

ho risolto il problema utilizzando la forma .xml come sfondo per il mio SeekBar. La soluzione SeekBar completo che può essere utilizzato tramite setProgressDrawable() metodo dovrebbe essere simile a questo:

//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> 

Nel codice, è possibile utilizzare in questo modo:

progressBar.setProgressDrawable(getResources().getDrawable(R.drawable.seek_bar)); 
+0

Ottima soluzione! – jbc25

6

Ho avuto problemi cambiando cercare e barre di avanzamento dal codice prima. Una volta ho dovuto caricare il drawable due volte prima che diventasse efficace. Penso che fosse legato al padding dopo aver cambiato l'immagine.

Sto solo indovinando qui, ma provare a impostare l'imbottitura in seguito con

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

e, inoltre, non poteva male a invalidarla.

seekBar.postInvalidate() 

molto hacky e non mi piace, ma è risolto qualcosa di simile per me prima

+1

Appena provato, e non risolve il problema :( –

9

La risposta di cui sopra è per usando xml, ma nel caso qualcuno volesse farlo a livello di programmazione lo ho qui sotto.

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

}

suddetta classe è per lo sfondo della SeekBar (la parte che esiste sempre sotto la drawable progresso)

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

}

Sopra è drawable progresso. Si noti che è una clip drawable. La parte interessante qui è che sto impostando i limiti per essere quello che voglio, insieme al colore. Ciò consente una personalizzazione fine del tuo drawable.

//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); 

Sopra il codice utilizza i drawable personalizzati per modificare la barra di ricerca. Il mio motivo principale per farlo è che modificherò l'aspetto del background drawable, quindi ha "notches" (anche se non ancora implementato). Non puoi farlo con un drawable definito xml (almeno non facilmente).

Un'altra cosa che ho notato è che questo processo impedisce al SeekBar di diventare largo come il pollice estraibile. Imposta i limiti dei drawable in modo che non arrivino mai alti.

+0

Ho provato la soluzione, ma è possibile regolarla in modo che gli angoli siano arrotondati? Ancora più complicato è necessario arrotondare a sinistra, ma non a destra (a meno che non si tratti di una barra di avanzamento completa), anche se non so come funzioni effettivamente – user1122069

+0

Se ti riferisci allo sfondo drawable, sì puoi. invece di canvas.drawRect all'interno di SeeBarBackgroundDrawable.draw(), usa canvas.drawRoundRect per disegnare il lato sinistro, quindi fai un altro canvas.drawRect per disegnare la metà del lato destro che si sovrappone al lato destro arrotondato del round Rect. Questo ti darà un rettangolo con i bordi arrotondati sul lato sinistro e spigoli vivi sul lato destro. – Danuofr

Problemi correlati