将 Butterknife 与 BaseActivity/Child 活动和 MaterialDrawer 结合使用

Using Butterknife with BaseActivity/Child Activities and MaterialDrawer

我在使用通过 BaseActivity 实现的多个活动(不使用片段)实现 MaterialDrawer(库 MikePenz)时遇到问题。此外,使用 ButterKnife 绑定视图。

在 SO 中找到相关问题并一一尝试,但在我的情况下它不起作用,因为它们中的大多数使用带片段的标准导航抽屉或者它们与 ButterKnife 无关。

代码:

MainActivity class

public class MainActivity extends AppCompatActivity {

    @BindView(R.id.toolbar)
    Toolbar toolbar;

    private List<TestModel> destinations;
    private DestinationAdapter mAdapter;
    ProgressDialog progressDialog;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);
        setSupportActionBar(toolbar);
        navManagement();
    }
}

activity_main布局

<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/maincontainer"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.tvs.ui.MainActivity">

    <android.support.design.widget.AppBarLayout
        android:id="@+id/appbar"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:theme="@style/AppTheme.AppBarOverlay"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        >

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/AppTheme.PopupOverlay"
             />

    </android.support.design.widget.AppBarLayout>

</android.support.constraint.ConstraintLayout>

StoreActivity

public class StoresActivity extends MainActivity {

    @BindView(R.id.searchEditText)
    EditText mSearchEditText; // errorRequired view 'searchEditText' with ID 2131558557 for field 'mSearchEditText' was not found
    @BindView(R.id.storesRecyclerView)
    RecyclerView recyclerView; // here too

    private List<TestModel> stores;
    private StoreAdapter mAdapter;

    //endregion
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_stores);
        ButterKnife.bind(this);

        loadRecyclerView();
        testData();

    }
    }

activity_store布局

<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <EditText
        android:id="@+id/searchEditText"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        />

    <android.support.v7.widget.RecyclerView
        android:id="@+id/storesRecyclerView"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        android:scrollbars="vertical">

    </android.support.v7.widget.RecyclerView>

</android.support.constraint.ConstraintLayout>

我知道错误的原因是当 Layout 膨胀时调用 MainActivity 中的 ButterKnife.Bind 但继承的 Activity 中的 Views 没有膨胀。导航抽屉加载但在单击项目时失败是显而易见的原因。我不能使用 FrameLayout,因为我使用的是 MaterialDrawer 库,它没有(或者我不知道)要膨胀的视图。

我尝试了多种方法来广泛搜索 SO1SO2 Git Git2 Link 但没有成功。

非常感谢任何帮助。提前致谢。

MaterialDrawer 会增加布局的视图。默认情况下,它会将 DrawerLayout 添加到 activity 的根目录中,并再次将其他内容(这是您的主要布局)作为子内容添加到其中。

做出此决定是为了让 Drawer 在您的应用程序中实现变得超级简单,而无需更改任何特殊内容。

Butterknife 将在您调用 bind 方法时绑定视图。 MaterialDrawer 的所有视图都在您调用时绑定 .build(),但由于 MaterialDrawer 的视图在内部绑定,因此您不必担心这些。

感谢@mikepenz 的回复。

张贴它,因为它可能会对某人有所帮助

已通过在 Base 中创建抽象方法解决此问题Activity

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(getLayoutResourceId());

        ButterKnife.bind(this); 
        setSupportActionBar(toolbar);
        navManagement();

    }
    protected abstract int getLayoutResourceId();

混凝土Activity

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    //setContentView(R.layout.activity_stores); not required
    ButterKnife.bind(this); 

    loadRecyclerView();
    testData();

}

@Override
protected int getLayoutResourceId() {
    return R.layout.activity_stores;
}

请注意,我没有在具体 Activity 中使用 ButterKnife.Bind,而是使用了 @Nullable 字段。但目前在基础活动和实施活动中都具有约束力。

要完成@user2695433 的回答,您可以更进一步:处理所有 butterknife init 并在 BaseActivity 中关闭,这样您就不会忘记释放资源!如果一些新开发人员加入您的团队并且不知道 butterknife 是如何工作的,这将非常有用。在这里:

--------在BaseActivity中--------

protected Unbinder binder;
protected abstract int getLayoutResourceId();
...

  @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(getLayoutResourceId());
        binder = ButterKnife.bind(this);
    }

@Override
protected void onDestroy() {
    super.onDestroy();
    binder.unbind(); //release ressource
}

-----在ConcreteActivity中------------

@BindView(R.id.title)
    TextView title; // butterknife stuff

@Override
    protected int getLayoutResourceId() { //define which Id
        return R.layout.activity_main;
    }
 @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
  }