将 Butterknife 与 BaseActivity/Child 活动和 MaterialDrawer 一起使用
Posted
技术标签:
【中文标题】将 Butterknife 与 BaseActivity/Child 活动和 MaterialDrawer 一起使用【英文标题】:Using Butterknife with BaseActivity/Child Activities and MaterialDrawer 【发布时间】:2017-08-03 17:22:52 【问题描述】:我在使用 BaseActivity 实现的多个活动(不使用片段)实现 MaterialDrawer(库 MikePenz)时遇到问题。此外,使用 ButterKnife 绑定视图。
在 SO 中找到相关问题并一一尝试,但在我的情况下它不起作用,因为它们中的大多数使用带有 Fragments 的标准导航抽屉,或者它们与 ButterKnife 无关。
代码:
MainActivity 类
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_
android:layout_
tools:context="com.tvs.ui.MainActivity">
<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
android:layout_
android:layout_
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_
android:layout_
android:background="?attr/colorPrimary"
app:popupTheme="@style/AppTheme.PopupOverlay"
/>
</android.support.design.widget.AppBarLayout>
</android.support.constraint.ConstraintLayout>
商店活动
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_
android:layout_>
<EditText
android:id="@+id/searchEditText"
android:layout_
android:layout_
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
/>
<android.support.v7.widget.RecyclerView
android:id="@+id/storesRecyclerView"
android:layout_
android:layout_
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:scrollbars="vertical">
</android.support.v7.widget.RecyclerView>
</android.support.constraint.ConstraintLayout>
我知道错误的原因是 MainActivity 中的 ButterKnife.Bind 在 Layout 膨胀但 Views 在继承的 Activities 中未膨胀时被调用。导航抽屉加载但在单击项目时它失败是显而易见的原因。我不能使用 FrameLayout,因为我使用的 MaterialDrawer 库没有(或者我不知道)有要膨胀的视图。
我尝试了几种广泛搜索 SO 的方法,例如 SO1SO2 Git Git2 Link 但没有成功。
非常感谢任何帮助。提前致谢。
【问题讨论】:
【参考方案1】:感谢@mikepenz 的回复。
发布它,因为它可能对某人有帮助
问题已通过在 BaseActivity 中创建抽象方法得到解决
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(getLayoutResourceId());
ButterKnife.bind(this);
setSupportActionBar(toolbar);
navManagement();
protected abstract int getLayoutResourceId();
具体活动
@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;
请注意,我没有在具体活动中使用 ButterKnife.Bind,而是使用了 @Nullable 字段。但目前在基础活动和实施活动中都具有约束力。
【讨论】:
activity_main 是在哪里声明的? @LOG_TAG 请检查问题,activity_main 布局以及代码是否存在。 我在上面的代码 BaseActivity 中询问您声明 setContentView(getLayoutResourceId());由于您没有调用 setContentView(R.layout.activity_main); 从您加载 activity_main 的位置;在 BaseActivity(上面的代码)中是否有任何可用的完整要点? 问题已通过在 BaseActivity 中创建抽象方法得到解决,但您在哪里声明 setContentView(R.layout.activity_main); 在基本活动中? @LOG_TAG 是的,通过在 MainActivity 中创建一个抽象方法 protected abstract int getLayoutResourceId();【参考方案2】:MaterialDrawer
会将视图膨胀到您的布局中。默认情况下,它会将DrawerLayout
添加到您的活动的根目录中,并再次将其他内容(这是您的主布局)添加为子项。
做出这个决定是为了让在您的应用程序中实现Drawer
变得超级简单,而无需更改任何特殊内容。
Butterknife 将在您调用 bind
方法时绑定视图。
MaterialDrawer 的所有视图在您调用 .build()
时都已绑定,但由于 MaterialDrawer 的视图已在内部绑定,因此您不必担心这些。
【讨论】:
感谢您的友好回复。您能否根据我的代码提出建议,如果需要从 BaseActivity 使用我需要做什么? 您并没有真正提到问题所在:D 哦,对不起,迈克。我在 BaseActivity 中使用 MaterialDrawer 并继承了子活动(代码已发布)但抽屉未加载或崩溃 如果我在单个 Activity 中使用 MaterialDrawer,它会加载但是如果我将 MaterialDrawer 代码移动到 BaseActivity 并继承到单个 Activity,它不会加载。我需要与 setContentView 做些什么? 您能否从您的 baseActivity 和扩展此 BaseActivity 的 Activity 中发布代码?我需要看看你是如何启动抽屉的【参考方案3】:要完成@user2695433 的回答,您可以走得更远一点:处理所有butterknife init 并在BaseActivity 中关闭,这样您就不会忘记释放资源!如果您的团队中有一些新开发人员不知道黄油刀是如何工作的,这将非常有用。这里是:
--------在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);
【讨论】:
以上是关于将 Butterknife 与 BaseActivity/Child 活动和 MaterialDrawer 一起使用的主要内容,如果未能解决你的问题,请参考以下文章
ButterKnife的安装与使用以及ButterKnife右键不显示的大坑
(2016.5.26更新8.0.1失效问题)Android Studio上使用Butterknife注解框架与插件Android Butterknife Zelezny
Android进阶之光学习记录——注解与依赖注入框架ButterKnife的尝试