使用新发布的Android支持设计库中的NavigationView,如果导航页眉布局包含onClick(在xml中),onClick事件会崩溃应用程序。可以通过view.onClickListener
(而不是xml)以编程方式添加OnClick,然后单击可以正常工作。但由于某些原因,每当使用xml onClick时,都会出现错误。
这是我的主要布局:
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/mainActivityLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<RelativeLayout
android:id="@+id/mainContentFrame"
android:layout_width="match_parent"
android:layout_height="match_parent">
...
</RelativeLayout>
<android.support.design.widget.NavigationView
android:id="@+id/drawerNavView"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="@layout/drawer_header"
app:menu="@menu/drawer_menu">
</android.support.design.widget.NavigationView>
</android.support.v4.widget.DrawerLayout>
在我的活动中,我的菜单项点击(添加navView.setNavigationItemSelectedListener()
)工作正常。问题是单击标题时:
drawer_header.xml:
...
<View
android:id="@+id/testButton"
android:layout_width="match_parent"
android:layout_height="60dp"
android:onClick="testButtonClick"/>
...
产生以下错误:
java.lang.IllegalStateException: Could not find a method testButtonClick(View)
in the activity class android.view.ContextThemeWrapper for onClick handler
on view class android.view.View with id 'testButton'
更新
NavigationView可以使用标准的Menu资源文件,但是如果从菜单XML资源使用onClick,则存在类似的问题。根据{{3}},android:onClick
属性会覆盖正常的回调。这通常可以正常工作,但是在NavigationView中有菜单项,它没有。相反,它崩溃了这个错误:
java.lang.RuntimeException: Unable to start activity ComponentInfo{...}:
android.view.InflateException: Binary XML file line #34:
Error inflating class android.support.design.widget.NavigationView
当我删除XML onClick时,错误就消失了。
更新
我使用Android设计库的“官方”Menu Resource reference测试了xml onClick。相同的结果:将onClick(在xml中)添加到NavigationView的菜单或标题会导致应用程序崩溃。所以这似乎是NavigationView的一个错误。
第v23.1号决议
Google针对Support Library v23.1中的这些XML onClick错误发布了demo project。
答案 0 :(得分:2)
确认,这是支持库中的一个错误。
显然它与ContextThemeWrapper
有关,根据此bug report,问题库22.1中存在问题。
所以,简短的回答是:
不要在NavigationView(或其他一些组件,如EditText)上使用XML onClick,直到它被修复。
解决方法:强>
在代码中设置单击侦听器。对于NavigationView,请使用 setNavigationItemSelectedListener()
。
更新:此错误已修复
现在,您可以在支持库23.1(bug report)中使用XML onClick。我已经验证它可以在我的应用中运行。但是在v23.1中看起来似乎存在其他(更新的)XML问题(见下文),即使这个特定的onClick错误现在已经修复。
完整性:
通过XML扩展NavigationView标头时似乎还有另一个(相关的?)错误。即使XML onClick现在有效,使用XML app:headerLayout
也会产生23.1的错误。由于这个通胀问题,您需要在代码中使用NavigationView.inflateHeaderView()
方法。这个新方法是在23.1中添加的,显然,之前的XML扩充现在已经被破坏了(或者他们可能会在不告诉任何人的情况下弃用app:headerLayout
)。更多详情here。
答案 1 :(得分:1)
嗨:我的解决方案是删除
app:headerLayout="@layout/drawer_header"
从您的NavigationView布局,如下所示:
<android.support.design.widget.NavigationView
android:id="@+id/drawerNavView"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:menu="@menu/drawer_menu">
</android.support.design.widget.NavigationView>
然后在您的活动中使用以下内容或查看控制器
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
View headerView= navigationView.inflateHeaderView(R.layout.nav_header);
TextView tvName = (TextView) headerView.findViewById(R.id.id_nav_header_uname);
tvName.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
L.d("=======tv click=====");
}
});
这适合我。
答案 2 :(得分:0)
您可以在代码中编写方法,而无需在XML中提及它。在代码中,您只需使用代码
public void methodName()
{
//
}
View v = findViewById(R.id.view_id);
v.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
methodName();
}
});
答案 3 :(得分:-1)
NavigationView具有菜单项的OnNavigationItemSelectedListener。
e.g。
navigationView.setNavigationItemSelectedListener(new SelectedNavigationItemListener());
private class SelectedNavigationItemListener implements NavigationView.OnNavigationItemSelectedListener {
@Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
switch (menuItem.getItemId()){
case id1:
break;
}
Log.d("MENU ITEM", menuItem.getTitle().toString());
return false;
}
}
对于标题,你可以做这样的事情,例如
navigationView = (NavigationView) findViewById(R.id.navigation_view);
View header = navigationView.inflateHeaderView(R.layout.drawer_header);
RelativeLayout drawerHeader = (RelativeLayout) header.findViewById(R.id.drawerHeader);
drawerHeader.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d("CLICKED HEADER", "Header Clicked");
}
});
我的HeaderLayout参考:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/drawerHeader"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="12dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/app_name"
android:textSize="16sp" />