2015-05-26 1 views
6

У меня есть макет, где я включаю те же суб-макет несколько раз, каждый из которых с другой ролью:использования нескольких <include /> тегов в макете с ножом для масла

<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> 

Это работает, если я нахожу точку в этом путь:

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); 

Я представляю в моем нож для масла проекта, и я надеялся, что я мог бы просто аннотировать каждый вид (следующий, очевидно, не работает, и я могу понять, почему) и ввести их позже с помощью каждого включенного в схему корень:

@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); 

Делая это таким образом, хотя, приводит меня к этой ошибке на второй инъекции:

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

Мой вопрос: есть ли способ использовать нож для масла в этом случае?

ответ

8

вы могли бы использовать некоторый тип суб-контейнера, как это:

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

то есть его

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

, а затем:

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

и Повсеместно этого класса вы можете использование:

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

Таким образом, это походит на поражение цели использования тега , хотя ... – Stephan

+0

Я согласен, что это не так идеально и автоматически, как должно быть, я просто нахожу обходные проблемы. Но вы все еще пишете меньше кода, более модульный код, и вы все равно можете использовать плагин ButterKnifeZelezny (https://github.com/avast/android-butterknife-zelezny) для автоматического создания этого подконтейнера. – Budius

1

Идея моего ответа та же, что и Будиус, я нашел ее в связанной с этим проблеме на github repo ButterKnife. Оригинал Автор является TomazMartins

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; 
    } 
} 

XML, в 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> 
<!--...--> 

XML, из Включенные Layout:

<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> 

Вот оно!

Когда я запустил его, хотя идентификатор был таким же, потому что я его повторно использовал, текст в TextView был другим.