2012-10-31 4 views
23

Desidero avere il margine predefinito per EditText di 10dp. Pertanto, nel mio file styles.xml Ho creato la seguente:Android - i margini specificati nello stile personalizzato non hanno effetto

<resources xmlns:android="http://schemas.android.com/apk/res/android"> 

    <style name="MyTheme" parent="android:style/Theme.NoTitleBar"> 
     <item name="android:editTextStyle">@style/edit_text_default</item> 
    </style> 

    <style name="edit_text_default" parent="android:style/Widget.EditText"> 
     <item name="android:layout_margin">10dp</item> 
    </style> 

</resources> 

Poi nel AndroidManifest.xml, ho impostato il tema delle applicazioni a quella che ho definito:

<application 
    android:icon="@drawable/ic_launcher" 
    android:label="@string/app_name" 
    android:theme="@style/MyTheme" > 
... 

Il "No Title Bar "l'aspetto del tema sta funzionando. Tuttavia, il margine predefinito per EditText non lo è, continua a riempire il genitore. Ecco la mia vista tabella:

<TableLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:background="#FFFFFF" > 
    <TableRow> 
     <EditText android:hint="@string/last_name" /> 
    </TableRow> 
    <TableRow> 
     <EditText android:hint="@string/first_name" /> 
    </TableRow> 
</TableLayout> 

risposta

48

Risposta breve: Se si specifica layout_margin in uno stile personalizzato, questo stile deve essere esplicitamente applicato ad ogni singolo vista che si desidera avere il margine specificato (come si vede nel codice di esempio qui sotto). Includere questo stile in un tema e applicarlo alla tua applicazione o un'attività non funzionerà.

<TableLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:background="#FFFFFF" > 
    <TableRow> 
     <EditText android:hint="@string/last_name" style="@style/edit_text_default" /> 
    </TableRow> 
    <TableRow> 
     <EditText android:hint="@string/first_name" style="@style/edit_text_default" /> 
    </TableRow> 
</TableLayout> 

Spiegazione: attributi che iniziano con layout_ sono LayoutParams, o una delle sue sottoclassi (per esempio MarginLayoutParams). LayoutParams vengono utilizzati dalle viste per comunicare al genitore ViewGroup in che modo devono essere disposti. Ogni classe ViewGroup implementa una classe nidificata che estende ViewGroup.LayoutParams. Pertanto, LayoutParams sono specifici per il tipo di ViewGroup. Ciò significa che mentre uno TableLayout e uno LinearLayout possono entrambi avere layout_margin come uno di esso è LayoutParams, sono considerati attributi completamente diversi.

Quindi layout_margin non è solo un attributo generale che può essere applicato ovunque. Deve essere applicato nel contesto di un ViewGroup che lo definisce specificamente come argomento valido. Una vista deve essere consapevole del tipo della sua madre ViewGroup quando si applica LayoutParams.

Specificare layout_margin in uno stile, incluso quello stile in un tema, e tentare di applicare quel tema a un'applicazione/attività comporterà la caduta degli attributi di layout, perché nessun genitore di ViewGroup è stato ancora specificato e quindi gli argomenti sono non valido. Tuttavia, l'applicazione dello stile a una vista EditText che è stata definita con un TableLayout funziona, poiché è noto il genitore ViewGroup (TableLayout).

Fonti:

documentazione Android su Layout Parameters.

Risposta data a this question dall'ingegnere di framework Android e dall'utente StackOverflow adamp.

Inoltre, rispondere a this question da StackOverflow utente inazaruk.

+4

W ... T ... F ?? perché? perché? PERCHÉ?!?! ... per favore perdonami ... Sto perdendo la testa con tutte le stranezze dello sviluppo Android. – pbarranis

+0

Questa risposta è in qualche modo insoddisfacente - i margini di layout non sono ancora applicati anche quando il ViewGroup padre e la Vista figlio si trovano nello stesso file xml di layout. In questo caso l'inflattore * conosce * il tipo concreto del ViewGroup padre (perché lo ha semplicemente gonfiato) e conosce anche lo stile da applicare (perché vengono applicati altri attributi di stile). –

1

Non si utilizza il nome del tema corretto nel Manifest. Provare a cambiare a:

<application 
    android:icon="@drawable/ic_launcher" 
    android:label="@string/app_name" 
    android:theme="@style/MyTheme" > 
+0

Siamo spiacenti, quello era un refuso nel post da parte mia. Sono uguali nel mio progetto attuale. Buon suggerimento però:/ – Groppe

0

Nel caso in cui sia utile per gli altri, mi piacerebbe portare lo the answer by Oliv to another SO question qui. Stavo cercando di aggiungere margini a tutti i pulsanti e ho trovato che layout_margin non funziona.

Il tema:

<style name="FooThemeStyle" parent="Base.Theme.AppCompat"> 
    <item name="android:buttonStyle">@style/FooButton</item> 
    <item name="buttonStyle">@style/FooButton</item> 
</style> 

Lo stile tasto:

<style name="FooButton" parent="Widget.AppCompat.Button"> 
    <item name="android:background">@drawable/button_background</item> 
</style> 

Ecco button_background.xml dove the answer by Oliv to another SO question viene utilizzato per impostare il margine per 2DP::

<?xml version="1.0" encoding="utf-8"?> 
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> 
    <item 
     android:bottom="2dp" 
     android:left="2dp" 
     android:right="2dp" 
     android:top="2dp"> 
     <selector xmlns:android="http://schemas.android.com/apk/res/android"> 
      ... 
     </selector> 
    </item> 
</layer-list>