使用ButterKnife

时间:2015-05-26 12:37:55

标签: android 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>

如果我以这种方式找到视图,它会起作用:

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

我现在正在我的项目中介绍ButterKnife,我希望我可以简单地注释每个视图(以下显然不起作用,我可以看到原因)并稍后使用每个包含的布局根注入它们:

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

但是,这样做会导致我在第二次注射时出现此错误:

  

错误:(81,13)错误:尝试使用@InjectView   在&#39; mEcoSeekArc&#39;上注明了ID 2131493185。

我的问题是:在这种情况下有没有办法使用ButterKnife?

2 个答案:

答案 0 :(得分:9)

您可以使用某种类型的子容器:

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

答案 1 :(得分:2)

我的回答的想法与Budius提出的相同,我在ButterKnife的github repo的相关问题中找到了它。原作者是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;
    }
}

MainAcitvity的XML:

<!--...-->
<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:

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

那就是它!

当我运行它时,虽然id是相同的,因为我重复使用它,TextView中的文本是不同的。