Quando devi mostrare immagini statiche nella tua app, puoi utilizzare la classe Drawable
e le relative sottoclassi per disegnare forme e
in formato Docker. Drawable
è un'astrazione generale per
qualcosa che può essere disegnato. Le varie sottoclassi aiutano con le immagini
ed estenderli per definire oggetti disegnabili personalizzati
che si comportano in modi unici.
Esistono due modi per definire e creare un'istanza per un Drawable
oltre all'utilizzo dei costruttori della classe:
- Aumenta il livello di una risorsa immagine (un file bitmap) salvata nel tuo progetto.
- Aumenta il livello di una risorsa XML che definisce le proprietà drawable.
Nota: Potresti invece preferire l'utilizzo di un drawable vettoriale, che definisce un'immagine con un insieme di punti, linee e curve, oltre alle informazioni sui colori associate. Consente di utilizzare drawable vettoriali da adattare a dimensioni diverse senza compromettere la qualità. Per ulteriori informazioni, vedi Vettore panoramica degli elementi drawable.
Creazione di drawable da immagini risorse
Puoi aggiungere elementi grafici alla tua app facendo riferimento a un file immagine dal tuo le risorse del tuo progetto. I tipi di file supportati sono PNG (opzione preferita), JPG (accettabile), e GIF (sconsigliato). Icone di app, loghi e altri elementi grafici, ad esempio quelli utilizzati nei giochi, sono più adatte a questa tecnica.
Per utilizzare una risorsa immagine, aggiungi il tuo file a res/drawable/
del tuo progetto. Una volta avviato il progetto, puoi fare riferimento all'immagine
risorsa dal codice o dal layout XML. In ogni caso, si fa riferimento all'utilizzo di un
l'ID risorsa, ovvero il nome del file senza estensione del tipo di file. Per
Ad esempio, fai riferimento a my_image.png
come my_image
.
Nota: le risorse immagine inserite nella sezione
La directory res/drawable/
può essere ottimizzata automaticamente con
compressione senza perdita di immagini da parte dello strumento aapt
durante la creazione
e il processo di sviluppo. Ad esempio, un'immagine PNG a colori reali che non richiede più di 256 colori.
può essere convertito in un file PNG a 8 bit con una tavolozza dei colori. Questo determina un'immagine
di pari qualità, ma che richiede meno memoria. Di conseguenza, i file binari delle immagini
inserito in questa directory può cambiare in fase di build. Se intendi leggere un
l'immagine come bitstream per convertirla in una bitmap, inserisci le immagini nel
res/raw/
, in cui lo strumento aapt
non
modifiche.
Il seguente snippet di codice mostra come creare un ImageView
che utilizza
crea un'immagine da una risorsa disegnabile e la aggiunge al layout:
Kotlin
private lateinit var constraintLayout: ConstraintLayout override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // Instantiate an ImageView and define its properties val i = ImageView(this).apply { setImageResource(R.drawable.my_image) contentDescription = resources.getString(R.string.my_image_desc) // set the ImageView bounds to match the Drawable's dimensions adjustViewBounds = true layoutParams = ViewGroup.LayoutParams( ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT) } // Create a ConstraintLayout in which to add the ImageView constraintLayout = ConstraintLayout(this).apply { // Add the ImageView to the layout. addView(i) } // Set the layout as the content view. setContentView(constraintLayout) }
Java
ConstraintLayout constraintLayout; protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Create a ConstraintLayout in which to add the ImageView constraintLayout = new ConstraintLayout(this); // Instantiate an ImageView and define its properties ImageView i = new ImageView(this); i.setImageResource(R.drawable.my_image); i.setContentDescription(getResources().getString(R.string.my_image_desc)); // set the ImageView bounds to match the Drawable's dimensions i.setAdjustViewBounds(true); i.setLayoutParams(new ViewGroup.LayoutParams( ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)); // Add the ImageView to the layout and set the layout as the content view. constraintLayout.addView(i); setContentView(constraintLayout); }
In altri casi, è possibile che tu voglia gestire la risorsa immagine come oggetto Drawable
, come illustrato di seguito
esempio:
Kotlin
val myImage: Drawable = ResourcesCompat.getDrawable(context.resources, R.drawable.my_image, null)
Java
Resources res = context.getResources(); Drawable myImage = ResourcesCompat.getDrawable(res, R.drawable.my_image, null);
Avviso: ogni risorsa unica nel progetto
può mantenere un solo stato, indipendentemente dal numero di oggetti
di creare un'istanza. Ad esempio, se crei un'istanza di due oggetti Drawable
dalla stessa risorsa immagine e
modificare una proprietà (ad esempio alfa) per un oggetto, questa operazione influisce anche
l'altra. Quando si gestiscono più istanze di una risorsa immagine,
di trasformare direttamente l'oggetto Drawable
,
adolescente
animazione.
Lo snippet XML di seguito mostra come aggiungere una risorsa disegnabile a un ImageView
nel layout XML:
<ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/my_image" android:contentDescription="@string/my_image_desc" />
Per ulteriori informazioni sull'utilizzo delle risorse di progetto, consulta Risorse e asset.
Nota: quando utilizzi le risorse immagine come origine dei drawable, assicurati che le immagini siano di dimensioni appropriate per le diverse densità di pixel. Se le immagini non sono corrette, ma verranno ridimensionate per adattarsi, il che può causare la presenza di artefatti nei disegni. Per ulteriori informazioni, leggi Supportare diverse densità dei pixel.
Creazione di drawable da risorse XML
Se è presente Drawable
da creare, che inizialmente non dipende dalle variabili definite
un codice o un'interazione dell'utente, poi è consigliabile definire il valore Drawable
in XML. Uniforme
se prevedi che Drawable
modifichi le sue proprietà durante l'interazione dell'utente
con la tua app, ti consigliamo di definire l'oggetto in XML, poiché puoi modificare le proprietà dopo
è stata creata un'istanza dell'oggetto.
Dopo aver definito il valore Drawable
in XML, salva il file nel
directory res/drawable/
del tuo progetto. L'esempio seguente mostra il file XML
definisce un
TransitionDrawable
risorsa, che eredita da Drawable
:
<!-- res/drawable/expand_collapse.xml --> <transition xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@drawable/image_expand"/> <item android:drawable="@drawable/image_collapse"/> </transition>
Quindi, recupera e crea un'istanza dell'oggetto chiamando
Resources#getDrawable()
e passando l'ID risorsa del file XML. Qualsiasi
Drawable
sottoclasse
che supporta il metodo inflate()
può essere definito in XML e creata un'istanza
dalla tua app.
Ogni classe drawable che supporta l'inflazione XML utilizza attributi XML specifici
che aiutano a definire le proprietà dell'oggetto. Il codice seguente crea un'istanza
TransitionDrawable
e la imposta come contenuto
Oggetto ImageView
:
Kotlin
val transition= ResourcesCompat.getDrawable( context.resources, R.drawable.expand_collapse, null ) as TransitionDrawable val image: ImageView = findViewById(R.id.toggle_image) image.setImageDrawable(transition) // Description of the initial state that the drawable represents. image.contentDescription = resources.getString(R.string.collapsed) // Then you can call the TransitionDrawable object's methods. transition.startTransition(1000) // After the transition is complete, change the image's content description // to reflect the new state.
Java
Resources res = context.getResources(); TransitionDrawable transition = (TransitionDrawable) ResourcesCompat.getDrawable(res, R.drawable.expand_collapse, null); ImageView image = (ImageView) findViewById(R.id.toggle_image); image.setImageDrawable(transition); // Description of the initial state that the drawable represents. image.setContentDescription(getResources().getString(R.string.collapsed)); // Then you can call the TransitionDrawable object's methods. transition.startTransition(1000); // After the transition is complete, change the image's content description // to reflect the new state.
Per ulteriori informazioni sugli attributi XML supportati, consulta le classi elencati sopra.
Disegna forme
Un oggetto ShapeDrawable
può essere una buona soluzione
quando vuoi disegnare dinamicamente un grafico bidimensionale. Puoi
disegnare in modo programmatico forme primitive su un oggetto ShapeDrawable
e applicare gli stili necessari alla tua app.
ShapeDrawable
è una sottoclasse di Drawable
. Per questo motivo, puoi utilizzare
ShapeDrawable
ovunque è previsto un Drawable
. Per
Ad esempio, puoi utilizzare un oggetto ShapeDrawable
per impostare lo sfondo
di una vista passandola al metodo setBackgroundDrawable()
della vista. Puoi anche tracciare la forma come
visualizzazione personalizzata e aggiungerla a un layout nella tua app.
Poiché ShapeDrawable
ha il proprio metodo draw()
, puoi creare un
sottoclasse di View
che disegna ShapeDrawable
durante l'evento onDraw()
, come mostrato
il seguente esempio di codice:
Kotlin
class CustomDrawableView(context: Context) : View(context) { private val drawable: ShapeDrawable = run { val x = 10 val y = 10 val width = 300 val height = 50 contentDescription = context.resources.getString(R.string.my_view_desc) ShapeDrawable(OvalShape()).apply { // If the color isn't set, the shape uses black as the default. paint.color = 0xff74AC23.toInt() // If the bounds aren't set, the shape can't be drawn. setBounds(x, y, x + width, y + height) } } override fun onDraw(canvas: Canvas) { drawable.draw(canvas) } }
Java
public class CustomDrawableView extends View { private ShapeDrawable drawable; public CustomDrawableView(Context context) { super(context); int x = 10; int y = 10; int width = 300; int height = 50; setContentDescription(context.getResources().getString( R.string.my_view_desc)); drawable = new ShapeDrawable(new OvalShape()); // If the color isn't set, the shape uses black as the default. drawable.getPaint().setColor(0xff74AC23); // If the bounds aren't set, the shape can't be drawn. drawable.setBounds(x, y, x + width, y + height); } protected void onDraw(Canvas canvas) { drawable.draw(canvas); } }
Puoi utilizzare la classe CustomDrawableView
nell'esempio di codice
in alto, proprio come faresti con qualsiasi altra visualizzazione personalizzata. Ad esempio, puoi
aggiungerlo in modo programmatico a un'attività nella tua app, come illustrato di seguito
esempio:
Kotlin
private lateinit var customDrawableView: CustomDrawableView override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) customDrawableView = CustomDrawableView(this) setContentView(customDrawableView) }
Java
CustomDrawableView customDrawableView; protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); customDrawableView = new CustomDrawableView(this); setContentView(customDrawableView); }
Se invece vuoi utilizzare la visualizzazione personalizzata nel layout XML,
La classe CustomDrawableView
deve sostituire il costruttore View(Context, AttributeSet)
, che viene chiamato quando la classe viene
gonfiato da XML. L'esempio seguente mostra come dichiarare
CustomDrawableView
nel layout XML:
<com.example.shapedrawable.CustomDrawableView android:layout_width="fill_parent" android:layout_height="wrap_content" />
La classe ShapeDrawable
, come molte altre
tipi di risorsa drawable nel pacchetto android.graphics.drawable
, consente di
definire varie proprietà dell'oggetto usando metodi pubblici. Alcuni esempi
che puoi regolare includono trasparenza alfa, filtro colore
dither, opacità e colore.
Puoi anche definire forme disegnabili primitive utilizzando le risorse XML. Per ulteriori informazioni informazioni, consulta Forma disegnabile in Tipi di risorse disegnabili.
Drawable NinePatch
Un elemento grafico di NinePatchDrawable
è un
un'immagine bitmap estensibile che puoi utilizzare come sfondo di una vista. Android
ridimensiona automaticamente l'immagine per adattarla ai contenuti della visualizzazione. Un
l'utilizzo di un'immagine NinePatch è lo sfondo usato dai sistemi Android
pulsanti: i pulsanti devono allungarsi per adattarsi a stringhe di varie lunghezze. R
La grafica NinePatch è un'immagine PNG standard che include un bordo aggiuntivo di 1 pixel.
Deve essere salvato con l'estensione 9.png
nel
directory res/drawable/
del tuo progetto.
Utilizza il bordo per definire le aree estensibili e statiche dell'immagine. Per indicare una sezione estensibile disegna una (o più) larghezza di 1 pixel le linee nere nella parte sinistra e superiore del bordo (gli altri pixel del bordo) deve essere completamente trasparente o bianca). Puoi avere tutte le sezioni estensibili come desideri. La dimensione relativa delle sezioni estensibili rimane la stessa, la sezione più ampia rimane sempre la più grande.
Puoi anche definire una sezione disegnabile facoltativa dell'immagine (in pratica,
le linee di spaziatura interna) disegnando una linea a destra e una linea in basso. Se
L'oggetto View
imposta come sfondo l'immagine NinePatch
e quindi specifica il testo della visualizzazione, si estende in modo che tutto il testo
occupa solo l'area designata dalla riga a destra e dalla riga inferiore (se inclusa).
Se le righe di spaziatura non sono incluse, Android utilizza le righe di sinistra e superiore per
per definire l'area disegnabile.
Per chiarire la differenza tra le righe, la riga di sinistra e quella superiore definiscono quali pixel dell'immagine possono essere replicati per allungare dell'immagine. Le righe inferiore e destra definiscono l'area relativa all'interno dell'immagine che i contenuti della vista possono occupare.
La Figura 1 mostra un esempio di grafica NinePatch utilizzata per definire un pulsante:
![Immagine di un'area estensibile
e spaziatura interna](https://developer.android.com/static/images/ninepatch_raw.png?hl=it)
Figura 1: esempio di grafica di NinePatch che definisce un pulsante
Questa grafica di NinePatch definisce un'area estensibile con entrambi i lati linee e l'area disegnabile con le linee inferiore e destra. Nell'immagine in alto, le linee grigie tratteggiate identificano le regioni dell'immagine che vengono replicate per allungare l'immagine. Il rettangolo rosa nell'immagine in basso identifica la regione in cui sono consentiti i contenuti della visualizzazione. Se i contenuti non sono rientrano in questa regione, l'immagine viene allungata per adattarle.
Lo strumento Disegna 9 patch offre un modo estremamente pratico per creare immagini NinePatch, utilizzando una editor. Genera anche avvisi se l'area che hai definito per l'elemento estensibile rischia di produrre artefatti di disegno causati dal pixel la replica dei dati.
Il seguente codice XML di layout di esempio mostra come aggiungere una grafica NinePatch
con un paio di pulsanti. L'immagine di NinePatch è salvata in
res/drawable/my_button_background.9.png
.
<Button android:id="@+id/tiny" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_centerInParent="true" android:text="Tiny" android:textSize="8sp" android:background="@drawable/my_button_background"/> <Button android:id="@+id/big" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_centerInParent="true" android:text="Biiiiiiig text!" android:textSize="30sp" android:background="@drawable/my_button_background"/>
Tieni presente che layout_width
e layout_height
sono impostati su wrap_content
per adattare correttamente il pulsante
intorno al testo.
La figura 2 mostra i due pulsanti visualizzati dall'immagine XML e NinePatch come mostrato sopra. Nota come la larghezza e l'altezza del pulsante variano con il testo. e l'immagine di sfondo si allunga per adattarla.
![Immagine di una
pulsanti di dimensioni normali](https://developer.android.com/static/images/ninepatch_examples.png?hl=it)
Figura 2: pulsanti visualizzati utilizzando un file XML risorsa e grafica NinePatch
Drawable personalizzati
Se vuoi creare dei disegni personalizzati, puoi farlo estendendo la classe Drawable
(o una delle sue sottoclassi).
Il metodo più importante da implementare è draw(Canvas)
perché fornisce l'oggetto Canvas
che devi utilizzare per fornire
le istruzioni per il disegno.
Il seguente codice mostra una sottoclasse semplice di Drawable
che disegna un cerchio:
Kotlin
class MyDrawable : Drawable() { private val redPaint: Paint = Paint().apply { setARGB(255, 255, 0, 0) } override fun draw(canvas: Canvas) { // Get the drawable's bounds val width: Int = bounds.width() val height: Int = bounds.height() val radius: Float = Math.min(width, height).toFloat() / 2f // Draw a red circle in the center canvas.drawCircle((width / 2).toFloat(), (height / 2).toFloat(), radius, redPaint) } override fun setAlpha(alpha: Int) { // This method is required } override fun setColorFilter(colorFilter: ColorFilter?) { // This method is required } override fun getOpacity(): Int = // Must be PixelFormat.UNKNOWN, TRANSLUCENT, TRANSPARENT, or OPAQUE PixelFormat.OPAQUE }
Java
public class MyDrawable extends Drawable { private final Paint redPaint; public MyDrawable() { // Set up color and text size redPaint = new Paint(); redPaint.setARGB(255, 255, 0, 0); } @Override public void draw(Canvas canvas) { // Get the drawable's bounds int width = getBounds().width(); int height = getBounds().height(); float radius = Math.min(width, height) / 2; // Draw a red circle in the center canvas.drawCircle(width/2, height/2, radius, redPaint); } @Override public void setAlpha(int alpha) { // This method is required } @Override public void setColorFilter(ColorFilter colorFilter) { // This method is required } @Override public int getOpacity() { // Must be PixelFormat.UNKNOWN, TRANSLUCENT, TRANSPARENT, or OPAQUE return PixelFormat.OPAQUE; } }
Puoi quindi aggiungere il disegno in qualsiasi punto, ad esempio in un
ImageView
come mostrato qui:
Kotlin
val myDrawing = MyDrawable() val image: ImageView = findViewById(R.id.imageView) image.setImageDrawable(myDrawing) image.contentDescription = resources.getString(R.string.my_image_desc)
Java
MyDrawable mydrawing = new MyDrawable(); ImageView image = findViewById(R.id.imageView); image.setImageDrawable(mydrawing); image.setContentDescription(getResources().getString(R.string.my_image_desc));
Su Android 7.0 (livello API 24) e versioni successive, puoi anche definire le istanze del tuo drawable personalizzato con XML, nei modi seguenti:
- Utilizzare il nome completo della classe come nome dell'elemento XML. Per questo approccio,
la classe drawable deve essere una classe pubblica di primo livello:
<com.myapp.MyDrawable xmlns:android="http://schemas.android.com/apk/res/android" android:color="#ffff0000" />
- Utilizzare
drawable
come nome del tag XML e specificare la classe completa nome dell'attributo class. Questo approccio può essere utilizzato sia per le classi pubbliche di primo livello classi interne statiche pubbliche:<drawable xmlns:android="http://schemas.android.com/apk/res/android" class="com.myapp.MyTopLevelClass$MyDrawable" android:color="#ffff0000" />
Aggiungi tinta ai disegni
Con Android 5.0 (livello API 21) e versioni successive, puoi colorare bitmap e nove patch definite come
alfabetiche. Puoi tingersi con risorse colore o attributi tematici che si risolvono in colore
di risorse (ad esempio, ?android:attr/colorPrimary
). In genere, sono creati da te
una sola volta e colorarli automaticamente
per abbinarli al tema scelto.
Puoi applicare una tinta a BitmapDrawable
, NinePatchDrawable
o VectorDrawable
con il metodo setTint()
. Puoi
imposta anche il colore e la modalità di tinta nei tuoi layout con android:tint
e
Attributi android:tintMode
.
Estrarre colori in evidenza da un'immagine
Android Support Library include la classe Palette
, che consente di estrarre colori in evidenza da un'immagine.
Puoi caricare i drawables come Bitmap
e passarli a Palette
per accedere ai relativi colori.
Per ulteriori informazioni, consulta la sezione Selezione dei colori con
l'API Palette.