4

如果導航標題佈局包含onClick(在xml中),onClick事件崩潰應用程序,則從新發布的Android支持設計庫中使用NavigationView。 OnClick可以通過編程方式通過view.onClickListener(而不是xml)添加,然後單擊工作正常。但出於某種原因,只要使用xml onClick,就會出現錯誤。NavigationView onClick from xml導致錯誤

這是我的主要佈局:

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

UPDATE

NavigationView可以使用標準菜單資源文件,但如果使用菜單XML資源中的onClick,則會出現類似的問題。根據Menu Resource reference,屬性將覆蓋正常回調。這通常工作正常,但與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時,錯誤消失。

UPDATE

我使用了 「官方」 demo project爲Android設計庫測試XML的onClick。相同的結果:將onClick(在xml中)添加到NavigationView的菜單或標題會導致應用程序崩潰。所以這似乎是NavigationView的一個bug。

解決了v23.1

谷歌發佈a fix在支持庫v23.1這些XML的onClick錯誤。

+0

你 – Elltz

+0

是的,我使用的片段和viewpager使用片段。 – hungryghost

+0

舒服,所以在的onclick XML不會在活動的工作,因爲,因爲頭視圖住在一個片段類,是否有意義先生? – Elltz

回答

2

證實,這是在支持庫中的錯誤。

顯然它與ContextThemeWrapper有關,並且根據此bug report,支持庫22.1中存在該問題。

所以,簡單的答案是:

不要使用XML的onClick與NavigationView(或其他一些組件,如EditText上),直到它的固定。

解決方法:

集點擊監聽器代碼。對於NavigationView,請使用 setNavigationItemSelectedListener()

UPDATE:此bug已奔固定

您現在可以使用XML的onClick在支持庫23.1(bug report)。我已經驗證它在我的應用程序中有效。但是,在v23.1中,NavView似乎還有其他(更新的)XML問題(見下文),儘管現在已經解決了這個特定的onClick錯誤。

爲了完整性:

似乎有經由XML充氣NavigationView頭時是另一個bug(有關?)。儘管XML onClick現在可以工作,但使用XML app:headerLayout會在23.1上產生錯誤。由於通貨膨脹問題,您需要在代碼中使用NavigationView.inflateHeaderView()方法。在23.1加入這個新的方法,顯然,前一個XML充氣現在分成(或者也許他們棄用app:headerLayout沒有告訴任何人?)。更多信息詳見here

+0

我已經在setNavigationItemSelected ..()上實現了switch case。打開各種片段。它適用於手機佈局,但在雙面佈局時,相同的代碼不起作用。默認情況下被觸發。這意味着MenuItem的ID已更改。 – Y2K

0

你可以在代碼中編寫你的方法而不用XML提及它。在代碼中,您只需使用代碼

public void methodName() 
{ 
// 
} 

View v = findViewById(R.id.view_id); 
v.setOnClickListener(new View.OnClickListener() { 
       @Override 
       public void onClick(View v) { 
methodName(); 
} 
}); 
+0

我知道我可以添加一個onClickListener,這就是我已經在解決這個問題。我想知道爲什麼XML onClick不起作用。我認爲這可能是一個新的支持庫的錯誤。 – hungryghost

+1

@hungryghost說實話,我從來沒有進入過它,只要它的編碼方式看起來更漂亮,而且它只是起作用。但我會密切關注這篇文章,以防萬一我找到一些有趣的東西 – Vendetta8247

+0

編碼工作正常,很容易。但是在我的特定實現中,我實際上會做更復雜的佈局交換等等,而onClick會讓它稍微簡單一些。但是,這真的很重要。對於我來說,我只是對這個錯誤感到驚訝。我不知道爲什麼它不起作用。另外,我應該修改我的問題,使其更清楚我所要求的。我有一種感覺,我會得到更多的「只使用OnClickLIstener」的答案,除非我更明確! – hungryghost

-1

NavigationView具有用於菜單項的OnNavigationItemSelectedListener。

例如

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

+0

對不起,我認爲你誤解了這個問題。我不問如何在代碼中添加點擊偵聽器。我的問題是爲什麼xml onClick出現錯誤。我很確定這是庫中的一個錯誤。 – hungryghost

1

你好:我的解決方案是從NavigationView佈局如下刪除

app:headerLayout="@layout/drawer_header" 

<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====="); 
    } 
}); 

這個作品爲了我。

+0

對不起。正如我在原始文章中所說的,我們顯然可以在Java中添加onClick。缺點是onClick不能從XML工作。無論如何,自從Google發佈了一個錯誤修復程序以來,這一點已經沒有意義了。查看我更新的帖子以獲取信息。 – hungryghost

+0

我看到谷歌固定的bug,我使用支持庫23.1,但是,它不能添加onClick,除非你使用'navigationView.inflateHeaderView(R.layout.nav_header);' 加載視圖。 via xml無法在NavigationView中爲headerView設置onClick。 – Summer

+0

這似乎是另一個通過XML膨脹NavigationView標題的bug。我有與v23.1相同的問題,但XML'onClick'現在工作正常(我已經在我的應用程序驗證)。只是現在XML'app:headerLayout'被破壞了,所以你不得不在代碼中使用'inflateHeaderView()'。這個方法剛剛在23.1中添加了,所以看起來他們在實現中破壞了一些東西。前進一步,退一步。我上週搜索了關於這個XML'app:headerLayout'問題的信息,但是沒有找到任何東西。也許你想發佈一個新的問題呢? – hungryghost