0

Ich benutze Datenbindung, und sieht aus wie Tab-Element wird Null von Databinding zurückgegeben (aber nicht GameTypes), ist das normal? Andere Ansichten funktionieren einwandfrei, sodass die Implementierung der Datenbindung kein Problem darstellt. Hier ist ein Teil der Layoutdatei.Datenbindung, die null zurückgibt. Es ist normal?

  <android.support.design.widget.TabLayout 
      android:id="@+id/gameTypes" 
      android:layout_width="0dp" 
      android:layout_height="48dp" 
      android:background="@android:color/white" 
      > 

      <android.support.design.widget.TabItem 
       android:id="@+id/football" 
       android:layout_width="match_parent" 
       android:layout_height="wrap_content" 
       android:tag="football" 
       android:text="Football" 
      /> 

      <android.support.design.widget.TabItem 
       android:id="@+id/basketball" 
       android:layout_width="match_parent" 
       android:layout_height="wrap_content" 
       android:tag="basketball" 
       android:text="Basketball"/> 


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

Hier ist Code, den ich versuche, ausgewählte Registerkarte zu finden;

private Boolean isSelectedTab(TabItem item, TabLayout.Tab tab) { 
    if (tab.getTag().equals(item.getTag())) 
     return true; 
    return false; 
    } 

Fehler ist; Element ist null, das ist databinding.basketball. Ich denke, sollte nicht null sein, da es TabItem ist.

Danke.

+0

Ich empfehle, dass Sie Ihre Frage bearbeiten und zeigen, wo/wie Sie Ihre 'isSelectedTab()' Methode aufrufen. Zeigen Sie insbesondere, wo/wie Sie den 'item' Wert erhalten. – CommonsWare

+0

Aktualisiert @CommonsWare – MmtBkn

Antwort

1

Ihr Code passt nicht zu Ihrem XML-Code. Das ist wahrscheinlich ein Problem. Aber möglicherweise stoßen Sie auf ein Problem, das wir mit TabLayouts und Databinding hatten.

Die Ursache scheint zu sein, dass TabLayout TabItem in XML verwendet, aber es zur Laufzeit in eine Tab konvertiert. Dadurch werden die internen Mapping-Databinding-Methoden zum Erstellen ihrer Referenzen durcheinander gebracht. In unserem Fall wurde unsere TabItem Instanz von dem falschen Objekt geworfen. In Ihrem Fall hört sich das so an, als wäre es einfach ein Null-Objekt.

In beiden Fällen scheint es, dass Sie TabLayout mit Datenbindung nicht zuverlässig verwenden können. Wir haben am Ende ein benutzerdefiniertes View erstellt, das nur ein TabLayout umschließt und dann Daten manuell an es bindet, indem es auf seine Tab Elemente direkt zugreift.

Zum Beispiel kann ein Layout mit einem TabLayout:

<layout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:app="http://schemas.android.com/apk/res-auto"> 

<data> 
    <variable name="viewModel" type="com.app.ViewModel" /> 
</data> 

<android.support.design.widget.TabLayout 
    android:layout_width="match_parent" 
    android:layout_height="56dp" 
    android:background="@color/white" 
    app:onTabSelectedListener="@{viewModel.onTabSelectedListener}"> 

    <android.support.design.widget.TabItem 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:layout="@layout/custom_tab_layout"> 

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

    <android.support.design.widget.TabItem 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:layout="@layout/custom_tab_layout"> 

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

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

Und dann einer benutzerdefinierten Ansicht, die Wraps, dass:

public class CustomTabLayout extends FrameLayout { 
    private CustomTabLayoutBinding mBinding; 

    public CustomTabLayout(@NonNull Context context) { 
     this(context, null); 
    } 

    public CustomTabLayout(@NonNull Context context, @Nullable AttributeSet attrs) { 
     this(context, attrs, 0); 
    } 

    public CustomTabLayout(@NonNull Context context, @Nullable AttributeSet attrs, @AttrRes int defStyleAttr) { 
     super(context, attrs, defStyleAttr); 

     LayoutInflater inflater = LayoutInflater.from(context); 
     View tabLayout = inflater.inflate(R.layout.custom_tab_layout, this, false); 
     addView(tabLayout); 

     if (!isInEditMode()) { 
      mBinding = CustomTabLayoutBinding.bind(tabLayout); 
     } 
    } 

    public void setViewModel(@Nullable ViewModel viewModel) { 
     mBinding.setViewModel(viewModel); 

     if (viewModel != null) { 
      updateTabAtIndex(viewModel.getFirstTabViewModel(), 0, viewModel.getSelectedIndex()); 
      updateTabAtIndex(viewModel.getSecondTabViewModel(), 1, viewModel.getSelectedIndex()); 
     } 
    } 

    private void updateTabAtIndex(TabViewModel tabViewModel, int index, int selectedIndex) { 
     TabLayout.Tab tab = mBinding.tabLayout.getTabAt(index); 
     if (tab == null) { 
      return; 
     } 

     View customView = tab.getCustomView(); 
     if (customView == null) { 
      return; 
     } 

     if (index == selectedIndex) { 
      tab.select(); 
     } 

     TextView textView = (TextView) customView.findViewById(R.id.title); 
     textView.setText(tabViewModel.getTitleText()); 

     TextView subTitleTV = (TextView) customView.findViewById(R.id.subtitle); 
     subTitleTV.setText(tabViewModel.getSubTitleText()); 
    } 
} 

dann im Layout, dass Sie eine TabLayout benötigen, Verwenden Sie stattdessen Ihre benutzerdefinierte Ansicht:

<com.app.CustomTabLayout 
     android:id="@+id/custom_tab_layout" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:elevation="@dimen/default_toolbar_elevation" 
     app:viewModel="@{viewModel.getTabsViewModel}" /> 

Wir verwenden MVVM hier, aber hoffentlich erhalten Sie das Wesentliche: Indem Sie eine öffentliche setViewModel (oder setMyData oder was auch immer) -Methode zur Verfügung stellen, können Sie Databinding weiterhin nutzen, wo Sie das benutzerdefinierte Registerkartenlayout verwenden, aber dann die Attribute manuell einstellen auf der Tab Objekte in der TabLayout.

Hoffe, dass hilft!

+0

Ich habe Variablen umbenannt, also geht es um falsches Refactoring. Ich glaube, Sie haben eine Ansicht geschrieben, die 'Tab Layout' und nicht' Table Layout' umschließt. Gibt es ein Beispiel, das ich mir anschauen kann? Ich weiß nicht, wie ich das machen soll. – MmtBkn

+1

Ja, gemeint 'TabLayout' - behoben und aktualisieren Sie die Antwort mit einigen Beispielen, wie wir es tun. – dominicoder

0

Artikel sind databinding.itemBasketball

nicht nach Ihrem Code-Schnipsel. Ihr Code-Snippet zeigt an, dass Sie isSelectedTab(b.itemFootballTypes, tab) aufrufen. Es gibt nichts in Ihrem Layout XML itemFootballTypes in Ihrer Frage. Es gibt jedoch eine Registerkarte itemFootball.

+0

Entschuldigung es war über Refactoring, und nicht die Ursache des Problems. – MmtBkn

Verwandte Themen