2016-04-21 14 views
6

Sto provando a creare il seguente disegno nella mia app.Come creare una forma di 'cerchio trasparente all'interno di un rettangolo' in XML in Android?

design Mockup
(https://photos.google.com/share/AF1QipPhCGTgf9zi7MetWJYm0NQ14c3wqzjqnEwxsajCFHEjqzt5R29qYvIjZ2C71q7EnQ?key=WUZKSXA1WVVwSlI2LVdTQy1IRjdUdzVuQlpCY0Rn)

sua una sovrapposizione in cima al principale dell'interfaccia utente. Cercando di crearlo usando un layout sulla parte superiore dell'interfaccia utente principale con lo sfondo come una forma traslucida creata in XML. Tuttavia, anche dopo aver letto più post, non sono in grado di capirlo.

Ho provato il seguente approccio, ma non ha funzionato. Crea una forma ad anello con tratto 200dp e impostala come sorgente per una vista di scena, quindi imposta lo scaletipo su centerCrop ma la forma non viene ridimensionata come fa una bitmap.

Forma XML:

<?xml version="1.0" encoding="utf-8"?> 
<shape xmlns:android="http://schemas.android.com/apk/res/android" 
    android:innerRadius="0dp" 
    android:shape="ring" 
    android:thicknessRatio="2" 
    android:useLevel="false" > 

    <solid android:color="@android:color/transparent" /> 

    <stroke 
     android:width="200dp" 
     android:color="#80000000" /> 
</shape> 

disposizione Overlay:

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent"> 

    <ImageView 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:src="@drawable/onboarding_background" 
     android:scaleType="centerCrop"/> 

</RelativeLayout> 

Eventuali indicazioni su come fare questo o codice sarebbe veramente utile.

+1

In altre parole, si desidera un 'buco circolare al centro di un rettangolo semitrasparente a schermo intero' –

+0

Si potrebbe facilmente utilizzare un vettore per questo (è un'altra soluzione, nel caso xml non è obbligatorio) –

+0

Si desidera fare qualcosa come Radius Around Point Map giusto? https://developers.google.com/android/reference/com/google/android/gms/maps/model/Circle#developer-guide spero che sia utile! Potrebbe essere duplicato di http://stackoverflow.com/questions/13991301/android-maps-api-v2-draw-circle –

risposta

10

Recentemente ho suonato con qualcosa di simile e l'ho adattato per voi. Tutta la magia sta accadendo nel OnDraw:

public class FocusView extends View { 
    private Paint mTransparentPaint; 
    private Paint mSemiBlackPaint; 
    private Path mPath = new Path(); 

    public FocusView(Context context) { 
    super(context); 
    initPaints(); 
    } 

    public FocusView(Context context, AttributeSet attrs) { 
    super(context, attrs); 
    initPaints(); 
    } 

    public FocusView(Context context, AttributeSet attrs, int defStyleAttr) { 
    super(context, attrs, defStyleAttr); 
    initPaints(); 
    } 

    private void initPaints() { 
    mTransparentPaint = new Paint(); 
    mTransparentPaint.setColor(Color.TRANSPARENT); 
    mTransparentPaint.setStrokeWidth(10); 

    mSemiBlackPaint = new Paint(); 
    mSemiBlackPaint.setColor(Color.TRANSPARENT); 
    mSemiBlackPaint.setStrokeWidth(10); 
    } 

    @Override 
    protected void onDraw(Canvas canvas) { 
    super.onDraw(canvas); 

    mPath.reset(); 

    mPath.addCircle(canvas.getWidth()/2, canvas.getHeight()/2, 550, Path.Direction.CW); 
    mPath.setFillType(Path.FillType.INVERSE_EVEN_ODD); 

    canvas.drawCircle(canvas.getWidth()/2, canvas.getHeight()/2, 550, mTransparentPaint); 

    canvas.drawPath(mPath, mSemiBlackPaint); 
    canvas.clipPath(mPath); 
    canvas.drawColor(Color.parseColor("#A6000000")); 
    } 
} 

Il trucco è quello di creare un percorso (il cerchio trasparente) in modo da poter impostare il metodo di disegno del percorso di essere "al di fuori del percorso", invece di "dentro il sentiero". Finalmente possiamo semplicemente ritagliare la tela su quel percorso e riempire il colore nero.

Per te, ti basta cambiare il colore Color.BLACK e modificare il raggio desiderato.

EDIT: Oh e semplicemente aggiungere a livello di codice: FocusView view = new FocusView(context) your_layout.addView(view)

O per XML:

<package_path_to_.FocusView 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" /> 

EDIT2: Ho appena visto che si voleva questo per l'onboarding della vostra applicazione. Potresti considerare di dare un'occhiata a https://github.com/iammert/MaterialIntroView quindi

+1

hey @nicolas, ringrazio molto per la risposta! .. Questa soluzione ha funzionato perfettamente per me (dopo alcune modifiche al codice). Posso modificare il tuo codice dalla risposta per mostrare la soluzione esatta? – abhiank

+0

Scusa se ero via. Ma sì, sentiti libero di apportare le modifiche necessarie per soddisfare pienamente la tua domanda! – NSimon

+0

senza problemi ... Ho modificato il codice. Grazie ancora per l'aiuto :) – abhiank

1

È possibile utilizzare PorterDuffXferMode e visualizzazione personalizzata per quello.

buon esempio di diverse modalità previste a questa immagine (vedi A Out B): AlphaCompositing

L'idea è di creare visualizzazione personalizzata, con rettangolo nero opaco e cerchio su di esso. Quando applichi PorterDuffXferMode.SRC_OUT, "cancellerà" il cerchio dal rettangolo, così avrai risultato quello che vuoi.

Nella vista personalizzata è necessario sovrascrivere il metodo dispatchDraw (Canvas canvas) e disegnare la bitmap risultante sulla cornice.

Quindi puoi inserire MapView e la tua vista personalizzata in FrameLayout e goderti il ​​risultato.

Problemi correlati