I have a layout where I include the same sub-layout multiple times, each one with a different role:
<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>
It works if I find the views in this way:
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);
I am introducing ButterKnife in my project now, and I hoped I could simply annotate each view (the following obviously doesn't work, and I can see why) and inject them later using each included layout root:
@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);
Doing it in this way, though, leads me to this error at the second injection:
Error:(81, 13) error: Attempt to use @InjectView for an already injected ID 2131493185 on 'mEcoSeekArc'.
My question is: is there a way to use ButterKnife in this scenario?
you could use some type of sub-container like this:
public static class SettingsArcLayout {
@InjectView(R.id.settings_text) public TextView mEcoText;
@InjectView(R.id.settings_leaf_img) public ImageView mComfortLeaf;
// etc...
}
then you have it
SettingsArcLayout layout1 = new SettingsArcLayout();
SettingsArcLayout layout2 = new SettingsArcLayout();
and then:
ButterKnife.inject(this); // inject eco and cmf
ButterKnife.inject(layout1, eco);
ButterKnife.inject(layout2, cmf);
and throught this class you can use:
layout1.mEcoText.setText(... etc
The idea of my answer is the same as Budius proposed, I found it in a related issue on ButterKnife's github repo. Original Author is TomazMartins
The 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;
}
}
The XML of the 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>
<!--...-->
The XML of the Included 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>
That's it!
When i ran it, although the id was the same, because I reused it, the text in the TextView was different.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With