radzio / android-data-binding-recyclerview

Using Recyclerview with the new Android Data Binding framework
Apache License 2.0
564 stars 97 forks source link

NullPointerException #16

Open eric-grab opened 6 years ago

eric-grab commented 6 years ago

Do you know what I'm missing?

12-01 15:37:35.858 7994-7994/tech.ericntd.githubsearch E/AndroidRuntime: FATAL EXCEPTION: main
                                                                         Process: tech.ericntd.githubsearch, PID: 7994
                                                                         java.lang.NullPointerException: Attempt to invoke interface method 'int net.droidlabs.mvvm.recyclerview.adapter.binder.ItemBinder.getLayoutRes(java.lang.Object)' on a null object reference
                                                                             at net.droidlabs.mvvm.recyclerview.adapter.BindingRecyclerViewAdapter.getItemViewType(BindingRecyclerViewAdapter.java:105)
                                                                             at android.support.v7.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:5631)

MainActivity.java:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("https://api.github.com")
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        GitHubRepository repository = new GitHubRepository(retrofit.create(GitHubApi.class));
        final SearchViewModel searchViewModel = new SearchViewModel(repository);

        final ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout
                .activity_main);
        binding.setVm(searchViewModel);

        // set up views
        binding.etSearchQuery.setOnEditorActionListener(new TextView.OnEditorActionListener() {
            @Override
            public boolean onEditorAction(TextView v,
                                          int actionId,
                                          KeyEvent event) {
                if (actionId == EditorInfo.IME_ACTION_SEARCH) {
                    searchViewModel.searchGitHubRepos(binding.etSearchQuery.getText().toString());
                    return true;
                }
                return false;
            }
        });
    }

    public ItemBinder<SearchResultViewModel> itemViewBinder() {
        return new CompositeItemBinder<SearchResultViewModel>(
                new SearchResultBinder(BR.searchResult, R.layout.rv_item_repo)
        );
    }
}

activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<layout 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">

    <data>

        <variable
            name="vm"
            type="tech.ericntd.githubsearch.search.SearchViewModel" />

        <variable
            name="view"
            type="tech.ericntd.githubsearch.search.MainActivity" />

    </data>

    <android.support.constraint.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context="tech.ericntd.githubsearch.search.MainActivity">

        <EditText
            android:id="@+id/et_search_query"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:imeOptions="actionSearch"
            android:inputType="text"
            android:maxLines="1"
            android:singleLine="true" />

        <android.support.v7.widget.RecyclerView
            android:id="@+id/rv_repos"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:items="@{vm.searchResults}"
            app:itemViewBinder="@{view.itemViewBinder}"
            app:layoutManager="android.support.v7.widget.LinearLayoutManager"
            app:layout_constraintTop_toBottomOf="@id/et_search_query" />

    </android.support.constraint.ConstraintLayout>
</layout>

SearchResultViewModel.java:

public class SearchResultViewModel extends BaseObservable {
    private final SearchResult searchResult;

    public SearchResultViewModel(SearchResult searchResult) {
        this.searchResult = searchResult;
    }

    @Bindable
    public String getName() {
        return searchResult.getName();
    }
}

SearchResultBinder:

public class SearchResultBinder extends ConditionalDataBinder<SearchResultViewModel> {
    public SearchResultBinder(int bindingVariable,
                              int layoutId) {
        super(bindingVariable, layoutId);
    }

    @Override
    public boolean canHandle(SearchResultViewModel model) {
        return true;
    }
}

rv_item_repo.xml:

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">

    <data>

        <variable
            name="searchResult"
            type="tech.ericntd.githubsearch.search.SearchResultViewModel" />

    </data>

    <android.support.constraint.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="16dp">

        <android.support.v7.widget.AppCompatTextView
            android:id="@+id/tv_repo_name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{searchResult.name}" />

    </android.support.constraint.ConstraintLayout>
</layout>
huebeiro commented 6 years ago

I'm having the same issue. I even tried to use both the ItemBinderBase or my own ItemBinder, but that doesn't seem to be the issue.

huebeiro commented 6 years ago

I've compared my files with the ones in the repository and there is a line in the UsersView.java: binding.setView(this); Adding it to my activity solved the issue. This line is not present on in "How to start" steps in the main repo page: https://github.com/radzio/android-data-binding-recyclerview#modify-your-activity But you can see it on the UsersView file: https://github.com/radzio/android-data-binding-recyclerview/blob/master/app/src/main/java/net/droidlabs/mvvmdemo/view/UsersView.java

huebeiro commented 6 years ago

I cannot believe it. Exactly 7 months later I'm having the very same issue for the very same mistake. The first Google result lead to me finding the solution in my own answer.