2013-07-30 11 views
5

Devo disegnare una linea 3dp per rappresentare un completamento di livello in un gioco di quizz.Come creare o modificare a livello di codice un drawable fatto di linee di colori diversi

Questa riga deve essere di 2 colori. Ad esempio, se l'utente ha completato il 40% del livello, la linea sarà rossa per il primo 40% della linea, mentre il restante 60% sarà grigio.

sono riuscito a farlo con un disegnabile:

<?xml version="1.0" encoding="utf-8"?> 
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> 
    <item> 
     <shape android:shape="line" > 
      <size android:height="3dp" android:width="40dp"/> 
      <stroke 
       android:width="1dp" 
       android:color="#FFFC10" /> 
     </shape> 
    </item> 
    <item android:left="40dp"> 
     <shape android:shape="line" > 
      <size android:height="3dp" android:width="60dp" /> 
      <stroke 
       android:width="1dp" 
       android:color="#DDDDDD" /> 
     </shape> 
    </item> 
</layer-list> 

E poi ho lo mostro con un ImageView:

<ImageView 
       android:id="@+id/row_completion_bar" 
       android:src="@drawable/completion_bar" 
       android:layout_width="100dp" 
       android:layout_height="3dp" /> 

... ma ora, devo ovviamente essere in grado di modificare questa razione del 40%/60% a seconda del completamento dell'utente actuel.

Prima domanda: qual è il modo migliore per farlo? Cambia il drawable in fase di runtime? o creare un nuovo drawable in fase di esecuzione in Java?

Seconda domanda: come si fa? Ho provato entrambi i modi (ricreare questo drawable nel codice Java/alterare il drawable XML in fase di esecuzione) e non ci sono riuscita :-(

Qualsiasi aiuto sarà molto apprezzato.

+0

vorrei creare un Drawable personalizzato come questa classe LineDrawable estende Drawable {.... – pskink

+0

Grazie per la tua risposta. Come lo faresti esattamente? –

+0

basta sostituire i metodi astratti tutti di Drawable - draw (tela), in particolare – pskink

risposta

13

quindi questo è un costume che si può Drawable utilizzare:

class LineDrawable extends Drawable { 
    private Paint mPaint; 

    public LineDrawable() { 
     mPaint = new Paint(); 
     mPaint.setStrokeWidth(3); 
    } 

    @Override 
    public void draw(Canvas canvas) { 
     int lvl = getLevel(); 
     Rect b = getBounds(); 
     float x = b.width() * lvl/10000.0f; 
     float y = (b.height() - mPaint.getStrokeWidth())/2; 
     mPaint.setColor(0xffff0000); 
     canvas.drawLine(0, y, x, y, mPaint); 
     mPaint.setColor(0xff00ff00); 
     canvas.drawLine(x, y, b.width(), y, mPaint); 
    } 

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

    @Override 
    public void setAlpha(int alpha) { 
    } 

    @Override 
    public void setColorFilter(ColorFilter cf) { 
    } 

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

e il codice di prova:.

View v = new View(this); 
final LineDrawable d = new LineDrawable(); 
d.setLevel(4000); 
v.setBackgroundDrawable(d); 
setContentView(v); 
OnTouchListener l = new OnTouchListener() { 
    @Override 
    public boolean onTouch(View v, MotionEvent event) { 
     int lvl = (int) (10000 * event.getX()/v.getWidth()); 
     d.setLevel(lvl); 
     return true; 
    } 
}; 
v.setOnTouchListener(l); 
+0

Grazie mille! Avete qualche idea su quale sia il modo più efficiente: questo, o la mia soluzione con ImageViews? –

0

ho trovato un modo per farlo non so se è il modo più efficiente, ma qui è:

Ho usato un RelativeLayout per sovrapporre ImageViews con il colore di sfondo.

in layout.xml:

<RelativeLayout style="@style/CompletionBar"> 

<ImageView 
    android:id="@+id/row_completion_bar_0" 
    style="@style/CompletionBar0" /> 

<ImageView 
    android:id="@+id/row_completion_bar_1" 
    style="@style/CompletionBar1" />  

</RelativeLayout> 

in styles.xml:

<!-- Completion Bar (Relative Layout) --> 
<style name="CompletionBar"> 
    <item name="android:layout_width">wrap_content</item> 
    <item name="android:layout_height">wrap_content</item> 
</style> 

<!-- Completion Bar 0 (ImageView) --> 
<style name="CompletionBar0"> 
    <item name="android:layout_width">100dp</item> 
    <item name="android:layout_height">2dp</item> 
    <item name="android:background">#CCCCCC</item> 
</style> 

<!-- Completion Bar 1 (ImageView) --> 
<style name="CompletionBar1"> 
    <item name="android:layout_width">40dp</item> 
    <item name="android:layout_height">2dp</item> 
    <item name="android:background">#555555</item> 
</style> 

nel file di java:

ImageView cb1 = (ImageView)row.findViewById(R.id.row_completion_bar_1); 
cb1.getLayoutParams().width = 40; /* Value in pixels, must convert to dp */ 
2

ne dite di usare una barra di avanzamento? Lo stile dei marcatori done e to-do può essere impostato in modo programmatico o tramite file xml. Il tuo codice sarà anche più leggibile/manutenibile perché utilizzerai il widget giusto per il lavoro. Il layout conterrà:

<ProgressBar 
    android:id="@+id/progressBar" 
    android:layout_height="3dip" 
    android:layout_width="match_parent" 
    android:progressDrawable="@drawable/progress_bar" /> 

È possibile aggiornare la barra dal codice utilizzando ad esempio:

ProgressBar bar = (ProgressBar)findViewById(R.id.progressBar); 
bar.setProgress(40); 

Questo esempio sostituisce lo stile della barra (come indicato dall'attributo progressDrawable), utilizzando una res /drawable/progress_bar.xml file - contenuto di seguito.Questo ha un tocco in più come sfumature sfumate e angoli arrotondati; regolare come meglio credi:

<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="#ff5a5d5a" 
     android:centerY="0.5" 
     android:endColor="#ff747674" 
     android:startColor="#ff9d9e9d" /> 
    </shape> 
    </item> 
    <item android:id="@android:id/progress"> 
    <clip> 
     <shape> 
     <corners android:radius="5dip" /> 
      <gradient 
      android:angle="0" 
      android:endColor="#ff009900" 
      android:startColor="#ff000099" /> 
     </shape> 
    </clip> 
    </item> 
</layer-list> 

credito a http://www.tiemenschut.com/how-to-customize-android-progress-bars/, che dà molto più dettagliato su come personalizzare le barre di avanzamento.

0

Questo frammento funzionerà per tutte le API

Utilizzare questa:

Drawable drawable = editText.getBackground(); 
drawable.setColorFilter(editTextColor, PorterDuff.Mode.SRC_ATOP); 
if(Build.VERSION.SDK_INT > 16) { 
    editText.setBackground(drawable); 
}else{ 
    editText.setBackgroundDrawable(drawable); 
} 
Problemi correlati