2015-05-26 12 views
6

ho un layout in cui includo lo stesso sub-layout più volte, ognuna con un ruolo diverso:uso di più <include /> tag nel layout con butterknife

<LinearLayout 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="horizontal"> 

    <include 
     android:id="@+id/settings_eco_seekarc" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     layout="@layout/settings_arc" /> 

    <include 
     android:id="@+id/settings_comfort_seekarc" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     layout="@layout/settings_arc" /> 
</LinearLayout> 

Funziona se trovo il punto di vista in questo modo:

View eco = root.findViewById(R.id.settings_eco_seekarc); 
mEcoSeekArc = (SeekArc) eco.findViewById(R.id.settings_seekarc); 
mEcoLeaf = (ImageView) eco.findViewById(R.id.settings_leaf_img); 
mEcoText = (TextView) eco.findViewById(R.id.settings_text); 
View cmf = root.findViewById(R.id.settings_comfort_seekarc); 
mComfortSeekArc = (SeekArc) cmf.findViewById(R.id.settings_seekarc); 
mComfortLeaf = (ImageView) cmf.findViewById(R.id.settings_leaf_img); 
mComfortText = (TextView) cmf.findViewById(R.id.settings_text); 

sto introducendo butterknife nel mio progetto ora, e speravo che potrei semplicemente annotare ogni vista (la seguente, ovviamente, non funziona, e posso capire perché) e iniettare in un secondo momento utilizzando ogni incluso il layout radice:

@InjectView(R.id.settings_seekarc) 
SeekArc mEcoSeekArc; 
@InjectView(R.id.settings_leaf_img) 
ImageView mEcoLeaf; 
@InjectView(R.id.settings_text) 
TextView mEcoText; 
@InjectView(R.id.settings_seekarc) 
SeekArc mComfortSeekArc; 
@InjectView(R.id.settings_leaf_img) 
ImageView mComfortLeaf; 
@InjectView(R.id.settings_text) 
TextView mComfortText; 

//then later... 
View eco = root.findViewById(R.id.settings_eco_seekarc); 
ButterKnife.inject(this, eco); 
View cmf = root.findViewById(R.id.settings_comfort_seekarc); 
ButterKnife.inject(this, cmf); 

Farlo in questo modo, però, mi porta a questo errore alla seconda iniezione:

Error:(81, 13) error: Attempt to use @InjectView for an already injected ID 2131493185 on 'mEcoSeekArc'.

La mia domanda è: esiste un modo per utilizzare butterknife in questo scenario?

risposta

8

si potrebbe usare un certo tipo di sub-contenitore come questo:

public static class SettingsArcLayout { 
    @InjectView(R.id.settings_text) public TextView mEcoText; 
    @InjectView(R.id.settings_leaf_img) public ImageView mComfortLeaf; 
    // etc... 
} 

allora lo avete

SettingsArcLayout layout1 = new SettingsArcLayout(); 
SettingsArcLayout layout2 = new SettingsArcLayout(); 

e poi:

ButterKnife.inject(this); // inject eco and cmf 
ButterKnife.inject(layout1, eco); 
ButterKnife.inject(layout2, cmf); 

e throught questa classe è possibile utilizzare:

layout1.mEcoText.setText(... etc 
+0

in questo modo sconfigge lo scopo di utilizzare il tag , anche se ... – Stephan

+0

Sono d'accordo che non è così ideale e automatico come dovrebbe essere, sto solo trovando una soluzione per i vostri problemi. Ma stai ancora scrivendo meno codice, più codice modulare e puoi ancora usare il plug-in ButterKnifeZelezny (https://github.com/avast/android-butterknife-zelezny) per generare automaticamente questo sotto-contenitore. – Budius

1

L'idea della mia risposta è la stessa proposta da Budius, l'ho trovata in un problema correlato su ButterKnife github repo. Autore originale è TomazMartins

Il MainActivity:

public MainActivity extends AppCompatActivity { 
    // 1. First, we declare the layout that was included as a View objects. 
    @BindView(R.id.layout_1) View layout_1; 
    @BindView(R.id.layout_2) View layout_2; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     // 2. In here, we bind the included layouts 
     ButterKnife.bind(this); 

     // 4. Then, we create objects of the type of the IncludedLayout. 
     //  In this example the layout reuse the same layout twice, so, there are two 
     //  IncludedLayouts. 
     IncludedLayout includedLayout_1 = new IncludedLayout(); 
     IncludedLayout includedLayout_2 = new IncludedLayout(); 

     // 5. We bind the elements of the included layouts. 
     ButerKnife.bind(includedLayout_1, layout_1); 
     ButerKnife.bind(includedLayout_2, layout_2); 

     // 6. And, finally, we use them. 
     includedLayout_1.displayed_text.setText( "Hello"); 
     includedLayout_2.displayed_text.setText( "Hey!"); 
    } 

    // 3. We create a static class that will be an container of the elements 
    //  of the included layout. In here we declare the components that 
    //  hold this. In this example, there is only one TextView. 
    static class IncludedLayout { 
     @BindView(R.id.displayed_text) TextView displayed_text; 
    } 
} 

L'XML del MainAcitvity:

<!--...--> 
<LinearLayout 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:orientation="vertical" > 

     <include android:id="@+id/layout_1" layout="@layout/included_layout" /> 
     <include android:id="@+id/layout_2" layout="@layout/included_layout" /> 
</LinearLayout> 
<!--...--> 

L'XML del layout incluso:

<LinearLayout 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:orientation="vertical"> 

    <TextView 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:id="@+id/displayed_text"/> 
</LinearLayout> 

Questo è tutto!

Quando l'ho eseguito, sebbene l'ID fosse lo stesso, poiché l'ho riutilizzato, il testo nel TextView era diverso.

Problemi correlati