4

Использование NavigationView из недавно выпущенной библиотеки дизайна поддержки Android, если макет заголовка навигации включает в себя onClick (в xml), событие onClick аварийно завершает работу. 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 можно использовать стандартные файлы меню ресурсов , но есть аналогичная проблема, если использовать onClick из меню XML-ресурса. Согласно 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

Я проверил XML OnClick с помощью "официальной" demo project для дизайна библиотеки Android. Те же результаты: добавление onClick (в xml) в меню или заголовок NavigationView приводит к сбою приложения. Таким образом, это выглядит как ошибка с NavigationView.

ПОСТАНОВИЛИ В v23.1

Google выпустила a fix для этих XML ошибок OnClick в v23.1 Поддержка библиотеки.

+0

Вы используете фрагменты – Elltz

+0

Да, я использую фрагменты и просмотрщик. – hungryghost

+0

хорошо, поэтому onclick в xml не будет работать в активности, потому что, поскольку заголовок выглядит в классе фрагментов, имеет ли смысл сэр? – Elltz

ответ

2

Подтверждено, это ошибка в библиотеке поддержки ,

По-видимому это связано с ContextThemeWrapper, и в соответствии с этим bug report проблема существует в Библиотеке поддержки 22.1.

Итак, короткий ответ:

Не используйте XML OnClick с NavigationView (или некоторыми другими компонентами, такими как EditText), пока это не зафиксировано.

Обход:

Set нажмите слушателей в коде. Для NavigationView используйте setNavigationItemSelectedListener().

UPDATE: Эта ошибка бен фиксированной

Теперь вы можете использовать XML OnClick в поддержку Library 23.1 (bug report). Я подтвердил, что он работает в моем приложении. Но, похоже, другие (новые) проблемы XML с NavView в v23.1 (см. Ниже), хотя эта конкретная ошибка onClick теперь исправлена.

Для полноты:

Там, кажется, еще одна ошибка при раздувании заголовок NavigationView через XML (связанные?). Использование XML app:headerLayout приводит к ошибкам с 23.1, хотя XML onClick теперь работает. Из-за этой проблемы с инфляцией вам нужно будет использовать метод NavigationView.inflateHeaderView() в коде. Этот новый метод был добавлен в 23.1, и, по-видимому, предыдущий раздутие XML теперь сломан (или, может быть, они устарели app:headerLayout, не сказав никому?). Подробная информация подробно here.

+0

Я применил случай переключения на setNavigationItemSelected ..(). для открытия различных фрагментов. Он хорошо работает для макета телефона, но по двухпозиционной схеме тот же код не работает. запускается случай по умолчанию. что означает, что идентификаторы для MenuItem изменились. – 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

Кодирование работает отлично и достаточно просто. Но в моей конкретной реализации я собираюсь сделать более сложную замену макетов и т. Д., А XML onClick сделает ее немного легче. Но это действительно так. Для меня я просто удивлен этой ошибкой. Я понятия не имею, почему это не сработает. Кроме того, я должен, вероятно, изменить свой вопрос, чтобы сделать его более ясным, что я прошу. У меня есть чувство, что я получу намного больше «просто использую OnClickLIstener», если я не буду более явным! – hungryghost

-1

Навигационное устройство имеет 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"); 
    } 
}); 

Reference для моего 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

Привет: мое решение удалить

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

это работает для меня.

+0

Извините. Как я уже сказал в своем оригинальном посте, мы, очевидно, можем добавить onClick в Java. Ошибка в том, что onClick не работал с XML. Во всяком случае, этот момент сейчас спорный, поскольку Google выпустил исправление ошибки. См. Мое обновленное сообщение для информации. – hungryghost

+0

я увидел ошибку, Google фиксированной, я использую Support Library 23,1, но это не может добавить OnClick, если вы используете 'navigationView.inflateHeaderView (R.layout.nav_header);' загрузить вид. через xml не может установить onClick в NavigationView для headerView. – Summer

+0

Это, похоже, еще одна ошибка с раздуванием заголовка NavigationView через XML. У меня была та же проблема с v23.1, но теперь XML 'onClick' отлично работает (я проверял в своем приложении). Дело в том, что теперь XML 'app: headerLayout' сломан, поэтому вы вынуждены использовать' inflateHeaderView() 'в коде. Этот метод был просто добавлен в 23.1, так что похоже, что они что-то сломали в реализации. Один шаг вперед, один шаг назад. Я искал информацию об этой проблеме XML 'app: headerLayout' на прошлой неделе, но ничего не нашел. Может быть, вы хотите опубликовать новый вопрос? – hungryghost