databinding recyclerview adapter received null list from livedataAndroid - Create a very large ListView based on a SQL CursorLoadmanager onLoadFinished not calledCan someone show me a simple working implementation of PagerSlidingTabStrip?How to implement endless list with RecyclerView?View.SurfaceView, why its member, mSurfaceHolder, returns null from getSurface()?How to update RecyclerView Adapter Data?How to communicate between FragmentActivity and Fragment?Search Firestore query don't show data in RecycleViewMultiple Adapters or One Adapter for different lists and objects - Code PerformanceHow to observe LiveData in RecyclerView adapter in MVVM architecture?
Asked to Not Use Transactions and to Use A Workaround to Simulate One
Other than good shoes and a stick, what are some ways to preserve your knees on long hikes?
Amortized Loans seem to benefit the bank more than the customer
How To Make Earth's Oceans as Brackish as Lyr's
Can Brexit be undone in an emergency?
Are lay articles good enough to be the main source of information for PhD research?
Very lazy puppy
How to give my students a straightedge instead of a ruler
Beauville-Laszlo for schemes
In what sequence should an advanced civilization teach technology to medieval society to maximize rate of adoption?
Transit visa to Hong Kong
Are there any “Third Order” acronyms used in space exploration?
Where is it? - The Google Earth Challenge Ep. 4
Is there a theorem in Real analysis similar to Cauchy's theorem in Complex analysis?
Is my sink P-trap too low?
Which version of the Pigeonhole principle is correct? One is far stronger than the other
Should I inform my future product owner that there are big chances that a team member will leave the company soon?
Latex matrix formatting
What does the Free Recovery sign (UK) actually mean?
What did the first ever Hunger Games look like?
Wouldn't Kreacher have been able to escape even without following an order?
Floating Point XOR
Is there a generally agreed upon solution to Bradley's Infinite Regress without appeal to Paraconsistent Logic?
Random restarts for unsatisfiable problems
databinding recyclerview adapter received null list from livedata
Android - Create a very large ListView based on a SQL CursorLoadmanager onLoadFinished not calledCan someone show me a simple working implementation of PagerSlidingTabStrip?How to implement endless list with RecyclerView?View.SurfaceView, why its member, mSurfaceHolder, returns null from getSurface()?How to update RecyclerView Adapter Data?How to communicate between FragmentActivity and Fragment?Search Firestore query don't show data in RecycleViewMultiple Adapters or One Adapter for different lists and objects - Code PerformanceHow to observe LiveData in RecyclerView adapter in MVVM architecture?
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;
I want to feed the recyclerview with a list of elements and livedata. I used data binding adapter and when I want to send data to adapter the list return null from livedata. the whole code are below.
thanks
I debugged the code and I saw when the data came from the AppDbHelper.java to HomeViewmodel.java and set to the live data the bindingadapter didn't change. thus, although the livedata is not null, the arraylist at databinding adapter(heartRateResultsModels) is null and made the app crashed.
1.fragment_home.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="viewModel"
type="ir.basamadazmanovin.heartrate.ui.main.home.HomeViewModel" />
</data>
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/swipe_refresh_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:refreshing="@viewModel.isLoading">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.main.home.HomeFragment">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/fragment_home_recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:adapter="@viewModel.heartRateResultsLiveData"
tools:listitem="@layout/row_fragment_home" />
</FrameLayout>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</layout>
2.BaseFragment.java
public abstract class BaseFragment<T extends ViewDataBinding, V extends BaseViewModel> extends Fragment
protected FragmentNavigation mFragmentNavigation;
private BaseActivity mActivity;
private View mRootView;
private T mViewDataBinding;
private V mViewModel;
public abstract int getBindingVariable();
public abstract
@LayoutRes
int getLayoutId();
public abstract V getViewModel();
@Override
public void onAttach(Context context)
super.onAttach(context);
if (context instanceof BaseActivity)
BaseActivity activity = (BaseActivity) context;
this.mActivity = activity;
activity.onFragmentAttached();
if (context instanceof FragmentNavigation)
mFragmentNavigation = (FragmentNavigation) context;
else
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
@Override
public void onCreate(@Nullable Bundle savedInstanceState)
performDependencyInjection();
super.onCreate(savedInstanceState);
mViewModel = getViewModel();
setHasOptionsMenu(false);
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
mViewDataBinding = DataBindingUtil.inflate(inflater, getLayoutId(), container, false);
mRootView = mViewDataBinding.getRoot();
return mRootView;
public BaseActivity getBaseActivity()
return mActivity;
public T getViewDataBinding()
return mViewDataBinding;
public void hideKeyboard()
if (mActivity != null)
mActivity.hideKeyboard();
public boolean isNetworkConnected()
return mActivity != null && mActivity.isNetworkConnected();
public void openActivityOnTokenExpire()
if (mActivity != null)
mActivity.openActivityOnTokenExpire();
private void performDependencyInjection()
AndroidSupportInjection.inject(this);
public interface Callback
void onFragmentAttached();
void onFragmentDetached(String tag);
3.HomeFragment.java
public class HomeFragment extends BaseFragment<FragmentHomeBinding,HomeViewModel> implements HomeNavigator
FragmentHomeBinding mFragmentHomeBinding;
@Inject
LinearLayoutManager mLayoutManager;
@Inject
HeartRateResultsAdapter mAdapter;
@Inject
ViewModelProviderFactory factory;
private HomeViewModel mHomeViewModel;
public static HomeFragment newInstance()
return new HomeFragment();
@Override
public int getBindingVariable()
return BR.viewModel;
@Override
public int getLayoutId()
return R.layout.fragment_home;
@Override
public HomeViewModel getViewModel()
mHomeViewModel = ViewModelProviders.of(this, factory).get(HomeViewModel.class);
return null;
@Override
public void onCreate(@Nullable Bundle savedInstanceState)
super.onCreate(savedInstanceState);
mHomeViewModel.setNavigator(this);
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState)
super.onViewCreated(view, savedInstanceState);
mFragmentHomeBinding = getViewDataBinding();
setUp();
private void setUp()
mLayoutManager.setOrientation(RecyclerView.VERTICAL);
mFragmentHomeBinding.fragmentHomeRecyclerView.setLayoutManager(mLayoutManager);
mFragmentHomeBinding.fragmentHomeRecyclerView.setItemAnimator(new DefaultItemAnimator());
mFragmentHomeBinding.fragmentHomeRecyclerView.setAdapter(mAdapter);
@Override
public void handleError(Throwable throwable)
4.BaseViewModel.java
public class BaseViewModel<N> extends ViewModel
private final DataManager mDataManager;
private final ObservableBoolean mIsLoading = new ObservableBoolean(false);
private final SchedulerProvider mSchedulerProvider;
private CompositeDisposable mCompositeDisposable;
private WeakReference<N> mNavigator;
public BaseViewModel(DataManager dataManager,
SchedulerProvider schedulerProvider)
this.mDataManager = dataManager;
this.mSchedulerProvider = schedulerProvider;
this.mCompositeDisposable = new CompositeDisposable();
@Override
protected void onCleared()
mCompositeDisposable.dispose();
super.onCleared();
public CompositeDisposable getCompositeDisposable()
return mCompositeDisposable;
public DataManager getDataManager()
return mDataManager;
public ObservableBoolean getIsLoading()
return mIsLoading;
public void setIsLoading(boolean isLoading)
mIsLoading.set(isLoading);
public N getNavigator()
return mNavigator.get();
public void setNavigator(N navigator)
this.mNavigator = new WeakReference<>(navigator);
public SchedulerProvider getSchedulerProvider()
return mSchedulerProvider;
5.HomeViewModel.java
public class HomeViewModel extends BaseViewModel<HomeNavigator>
private MutableLiveData<ArrayList<HeartRateResultsModel>> heartRateResultsLiveData;
public HomeViewModel(DataManager dataManager, SchedulerProvider schedulerProvider)
super(dataManager, schedulerProvider);
heartRateResultsLiveData = new MutableLiveData<>();
fetchRepos();
public void fetchRepos()
setIsLoading(true);
getCompositeDisposable().add(getDataManager()
.getHeartRateResults()
.subscribeOn(getSchedulerProvider().io())
.observeOn(getSchedulerProvider().ui())
.subscribe(heartRateResultsModels ->
heartRateResultsLiveData.setValue(heartRateResultsModels);
setIsLoading(false);
, throwable ->
setIsLoading(false);
getNavigator().handleError(throwable);
));
public LiveData<ArrayList<HeartRateResultsModel>> getHeartRateResultsLiveData()
return heartRateResultsLiveData;
6.BindingUtils.java
public final class BindingUtils
private BindingUtils()
// This class is not publicly instantiable
@BindingAdapter("imageUrl")
public static void setImageUrl(ImageView imageView, String url)
Context context = imageView.getContext();
Glide.with(context).load(url).into(imageView);
@BindingAdapter("onNavigationItemSelected")
public static void setOnNavigationItemSelectedListener(
BottomNavigationView view, OnNavigationItemSelectedListener listener)
view.setOnNavigationItemSelectedListener(listener);
@BindingAdapter("adapter")
public static void addHeartRateResultsItems(RecyclerView recyclerView,
ArrayList<HeartRateResultsModel> heartRateResultsModels)
HeartRateResultsAdapter adapter = (HeartRateResultsAdapter) recyclerView.getAdapter();
if (adapter != null)
adapter.clearItems();
adapter.addItems(heartRateResultsModels);
7.DataManager.java
public interface DataManager extends DbHelper, PreferencesHelper, ApiHelper
8.DbHelper.java
public interface DbHelper
Single<ArrayList<HeartRateResultsModel>> getHeartRateResults();
9.AppDataManager.java
public class AppDataManager implements DataManager
private final ApiHelper mApiHelper;
private final Context mContext;
private final DbHelper mDbHelper;
private final Gson mGson;
private final PreferencesHelper mPreferencesHelper;
@Inject
public AppDataManager(Context context,
DbHelper dbHelper,
PreferencesHelper preferencesHelper,
ApiHelper apiHelper,
Gson gson)
mContext = context;
mDbHelper = dbHelper;
mPreferencesHelper = preferencesHelper;
mApiHelper = apiHelper;
mGson = gson;
@Override
public Single<ArrayList<HeartRateResultsModel>> getHeartRateResults()
return mDbHelper.getHeartRateResults();
10.AppDbHelper.java
@Singleton
public class AppDbHelper implements DbHelper
private final AppDatabase mAppDatabase;
@Inject
public AppDbHelper(AppDatabase appDatabase)
this.mAppDatabase = appDatabase;
@Override
public Single<ArrayList<HeartRateResultsModel>> getHeartRateResults()
return Single.fromCallable(new Callable<ArrayList<HeartRateResultsModel>>()
@Override
public ArrayList<HeartRateResultsModel> call() throws Exception
ArrayList<HeartRateResultsModel> models = new ArrayList<>();
models.add(new HeartRateResultsModel("","1"));
models.add(new HeartRateResultsModel("","2"));
return models;
);
android mvvm android-recyclerview android-databinding android-livedata
add a comment
|
I want to feed the recyclerview with a list of elements and livedata. I used data binding adapter and when I want to send data to adapter the list return null from livedata. the whole code are below.
thanks
I debugged the code and I saw when the data came from the AppDbHelper.java to HomeViewmodel.java and set to the live data the bindingadapter didn't change. thus, although the livedata is not null, the arraylist at databinding adapter(heartRateResultsModels) is null and made the app crashed.
1.fragment_home.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="viewModel"
type="ir.basamadazmanovin.heartrate.ui.main.home.HomeViewModel" />
</data>
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/swipe_refresh_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:refreshing="@viewModel.isLoading">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.main.home.HomeFragment">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/fragment_home_recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:adapter="@viewModel.heartRateResultsLiveData"
tools:listitem="@layout/row_fragment_home" />
</FrameLayout>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</layout>
2.BaseFragment.java
public abstract class BaseFragment<T extends ViewDataBinding, V extends BaseViewModel> extends Fragment
protected FragmentNavigation mFragmentNavigation;
private BaseActivity mActivity;
private View mRootView;
private T mViewDataBinding;
private V mViewModel;
public abstract int getBindingVariable();
public abstract
@LayoutRes
int getLayoutId();
public abstract V getViewModel();
@Override
public void onAttach(Context context)
super.onAttach(context);
if (context instanceof BaseActivity)
BaseActivity activity = (BaseActivity) context;
this.mActivity = activity;
activity.onFragmentAttached();
if (context instanceof FragmentNavigation)
mFragmentNavigation = (FragmentNavigation) context;
else
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
@Override
public void onCreate(@Nullable Bundle savedInstanceState)
performDependencyInjection();
super.onCreate(savedInstanceState);
mViewModel = getViewModel();
setHasOptionsMenu(false);
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
mViewDataBinding = DataBindingUtil.inflate(inflater, getLayoutId(), container, false);
mRootView = mViewDataBinding.getRoot();
return mRootView;
public BaseActivity getBaseActivity()
return mActivity;
public T getViewDataBinding()
return mViewDataBinding;
public void hideKeyboard()
if (mActivity != null)
mActivity.hideKeyboard();
public boolean isNetworkConnected()
return mActivity != null && mActivity.isNetworkConnected();
public void openActivityOnTokenExpire()
if (mActivity != null)
mActivity.openActivityOnTokenExpire();
private void performDependencyInjection()
AndroidSupportInjection.inject(this);
public interface Callback
void onFragmentAttached();
void onFragmentDetached(String tag);
3.HomeFragment.java
public class HomeFragment extends BaseFragment<FragmentHomeBinding,HomeViewModel> implements HomeNavigator
FragmentHomeBinding mFragmentHomeBinding;
@Inject
LinearLayoutManager mLayoutManager;
@Inject
HeartRateResultsAdapter mAdapter;
@Inject
ViewModelProviderFactory factory;
private HomeViewModel mHomeViewModel;
public static HomeFragment newInstance()
return new HomeFragment();
@Override
public int getBindingVariable()
return BR.viewModel;
@Override
public int getLayoutId()
return R.layout.fragment_home;
@Override
public HomeViewModel getViewModel()
mHomeViewModel = ViewModelProviders.of(this, factory).get(HomeViewModel.class);
return null;
@Override
public void onCreate(@Nullable Bundle savedInstanceState)
super.onCreate(savedInstanceState);
mHomeViewModel.setNavigator(this);
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState)
super.onViewCreated(view, savedInstanceState);
mFragmentHomeBinding = getViewDataBinding();
setUp();
private void setUp()
mLayoutManager.setOrientation(RecyclerView.VERTICAL);
mFragmentHomeBinding.fragmentHomeRecyclerView.setLayoutManager(mLayoutManager);
mFragmentHomeBinding.fragmentHomeRecyclerView.setItemAnimator(new DefaultItemAnimator());
mFragmentHomeBinding.fragmentHomeRecyclerView.setAdapter(mAdapter);
@Override
public void handleError(Throwable throwable)
4.BaseViewModel.java
public class BaseViewModel<N> extends ViewModel
private final DataManager mDataManager;
private final ObservableBoolean mIsLoading = new ObservableBoolean(false);
private final SchedulerProvider mSchedulerProvider;
private CompositeDisposable mCompositeDisposable;
private WeakReference<N> mNavigator;
public BaseViewModel(DataManager dataManager,
SchedulerProvider schedulerProvider)
this.mDataManager = dataManager;
this.mSchedulerProvider = schedulerProvider;
this.mCompositeDisposable = new CompositeDisposable();
@Override
protected void onCleared()
mCompositeDisposable.dispose();
super.onCleared();
public CompositeDisposable getCompositeDisposable()
return mCompositeDisposable;
public DataManager getDataManager()
return mDataManager;
public ObservableBoolean getIsLoading()
return mIsLoading;
public void setIsLoading(boolean isLoading)
mIsLoading.set(isLoading);
public N getNavigator()
return mNavigator.get();
public void setNavigator(N navigator)
this.mNavigator = new WeakReference<>(navigator);
public SchedulerProvider getSchedulerProvider()
return mSchedulerProvider;
5.HomeViewModel.java
public class HomeViewModel extends BaseViewModel<HomeNavigator>
private MutableLiveData<ArrayList<HeartRateResultsModel>> heartRateResultsLiveData;
public HomeViewModel(DataManager dataManager, SchedulerProvider schedulerProvider)
super(dataManager, schedulerProvider);
heartRateResultsLiveData = new MutableLiveData<>();
fetchRepos();
public void fetchRepos()
setIsLoading(true);
getCompositeDisposable().add(getDataManager()
.getHeartRateResults()
.subscribeOn(getSchedulerProvider().io())
.observeOn(getSchedulerProvider().ui())
.subscribe(heartRateResultsModels ->
heartRateResultsLiveData.setValue(heartRateResultsModels);
setIsLoading(false);
, throwable ->
setIsLoading(false);
getNavigator().handleError(throwable);
));
public LiveData<ArrayList<HeartRateResultsModel>> getHeartRateResultsLiveData()
return heartRateResultsLiveData;
6.BindingUtils.java
public final class BindingUtils
private BindingUtils()
// This class is not publicly instantiable
@BindingAdapter("imageUrl")
public static void setImageUrl(ImageView imageView, String url)
Context context = imageView.getContext();
Glide.with(context).load(url).into(imageView);
@BindingAdapter("onNavigationItemSelected")
public static void setOnNavigationItemSelectedListener(
BottomNavigationView view, OnNavigationItemSelectedListener listener)
view.setOnNavigationItemSelectedListener(listener);
@BindingAdapter("adapter")
public static void addHeartRateResultsItems(RecyclerView recyclerView,
ArrayList<HeartRateResultsModel> heartRateResultsModels)
HeartRateResultsAdapter adapter = (HeartRateResultsAdapter) recyclerView.getAdapter();
if (adapter != null)
adapter.clearItems();
adapter.addItems(heartRateResultsModels);
7.DataManager.java
public interface DataManager extends DbHelper, PreferencesHelper, ApiHelper
8.DbHelper.java
public interface DbHelper
Single<ArrayList<HeartRateResultsModel>> getHeartRateResults();
9.AppDataManager.java
public class AppDataManager implements DataManager
private final ApiHelper mApiHelper;
private final Context mContext;
private final DbHelper mDbHelper;
private final Gson mGson;
private final PreferencesHelper mPreferencesHelper;
@Inject
public AppDataManager(Context context,
DbHelper dbHelper,
PreferencesHelper preferencesHelper,
ApiHelper apiHelper,
Gson gson)
mContext = context;
mDbHelper = dbHelper;
mPreferencesHelper = preferencesHelper;
mApiHelper = apiHelper;
mGson = gson;
@Override
public Single<ArrayList<HeartRateResultsModel>> getHeartRateResults()
return mDbHelper.getHeartRateResults();
10.AppDbHelper.java
@Singleton
public class AppDbHelper implements DbHelper
private final AppDatabase mAppDatabase;
@Inject
public AppDbHelper(AppDatabase appDatabase)
this.mAppDatabase = appDatabase;
@Override
public Single<ArrayList<HeartRateResultsModel>> getHeartRateResults()
return Single.fromCallable(new Callable<ArrayList<HeartRateResultsModel>>()
@Override
public ArrayList<HeartRateResultsModel> call() throws Exception
ArrayList<HeartRateResultsModel> models = new ArrayList<>();
models.add(new HeartRateResultsModel("","1"));
models.add(new HeartRateResultsModel("","2"));
return models;
);
android mvvm android-recyclerview android-databinding android-livedata
add a comment
|
I want to feed the recyclerview with a list of elements and livedata. I used data binding adapter and when I want to send data to adapter the list return null from livedata. the whole code are below.
thanks
I debugged the code and I saw when the data came from the AppDbHelper.java to HomeViewmodel.java and set to the live data the bindingadapter didn't change. thus, although the livedata is not null, the arraylist at databinding adapter(heartRateResultsModels) is null and made the app crashed.
1.fragment_home.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="viewModel"
type="ir.basamadazmanovin.heartrate.ui.main.home.HomeViewModel" />
</data>
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/swipe_refresh_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:refreshing="@viewModel.isLoading">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.main.home.HomeFragment">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/fragment_home_recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:adapter="@viewModel.heartRateResultsLiveData"
tools:listitem="@layout/row_fragment_home" />
</FrameLayout>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</layout>
2.BaseFragment.java
public abstract class BaseFragment<T extends ViewDataBinding, V extends BaseViewModel> extends Fragment
protected FragmentNavigation mFragmentNavigation;
private BaseActivity mActivity;
private View mRootView;
private T mViewDataBinding;
private V mViewModel;
public abstract int getBindingVariable();
public abstract
@LayoutRes
int getLayoutId();
public abstract V getViewModel();
@Override
public void onAttach(Context context)
super.onAttach(context);
if (context instanceof BaseActivity)
BaseActivity activity = (BaseActivity) context;
this.mActivity = activity;
activity.onFragmentAttached();
if (context instanceof FragmentNavigation)
mFragmentNavigation = (FragmentNavigation) context;
else
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
@Override
public void onCreate(@Nullable Bundle savedInstanceState)
performDependencyInjection();
super.onCreate(savedInstanceState);
mViewModel = getViewModel();
setHasOptionsMenu(false);
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
mViewDataBinding = DataBindingUtil.inflate(inflater, getLayoutId(), container, false);
mRootView = mViewDataBinding.getRoot();
return mRootView;
public BaseActivity getBaseActivity()
return mActivity;
public T getViewDataBinding()
return mViewDataBinding;
public void hideKeyboard()
if (mActivity != null)
mActivity.hideKeyboard();
public boolean isNetworkConnected()
return mActivity != null && mActivity.isNetworkConnected();
public void openActivityOnTokenExpire()
if (mActivity != null)
mActivity.openActivityOnTokenExpire();
private void performDependencyInjection()
AndroidSupportInjection.inject(this);
public interface Callback
void onFragmentAttached();
void onFragmentDetached(String tag);
3.HomeFragment.java
public class HomeFragment extends BaseFragment<FragmentHomeBinding,HomeViewModel> implements HomeNavigator
FragmentHomeBinding mFragmentHomeBinding;
@Inject
LinearLayoutManager mLayoutManager;
@Inject
HeartRateResultsAdapter mAdapter;
@Inject
ViewModelProviderFactory factory;
private HomeViewModel mHomeViewModel;
public static HomeFragment newInstance()
return new HomeFragment();
@Override
public int getBindingVariable()
return BR.viewModel;
@Override
public int getLayoutId()
return R.layout.fragment_home;
@Override
public HomeViewModel getViewModel()
mHomeViewModel = ViewModelProviders.of(this, factory).get(HomeViewModel.class);
return null;
@Override
public void onCreate(@Nullable Bundle savedInstanceState)
super.onCreate(savedInstanceState);
mHomeViewModel.setNavigator(this);
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState)
super.onViewCreated(view, savedInstanceState);
mFragmentHomeBinding = getViewDataBinding();
setUp();
private void setUp()
mLayoutManager.setOrientation(RecyclerView.VERTICAL);
mFragmentHomeBinding.fragmentHomeRecyclerView.setLayoutManager(mLayoutManager);
mFragmentHomeBinding.fragmentHomeRecyclerView.setItemAnimator(new DefaultItemAnimator());
mFragmentHomeBinding.fragmentHomeRecyclerView.setAdapter(mAdapter);
@Override
public void handleError(Throwable throwable)
4.BaseViewModel.java
public class BaseViewModel<N> extends ViewModel
private final DataManager mDataManager;
private final ObservableBoolean mIsLoading = new ObservableBoolean(false);
private final SchedulerProvider mSchedulerProvider;
private CompositeDisposable mCompositeDisposable;
private WeakReference<N> mNavigator;
public BaseViewModel(DataManager dataManager,
SchedulerProvider schedulerProvider)
this.mDataManager = dataManager;
this.mSchedulerProvider = schedulerProvider;
this.mCompositeDisposable = new CompositeDisposable();
@Override
protected void onCleared()
mCompositeDisposable.dispose();
super.onCleared();
public CompositeDisposable getCompositeDisposable()
return mCompositeDisposable;
public DataManager getDataManager()
return mDataManager;
public ObservableBoolean getIsLoading()
return mIsLoading;
public void setIsLoading(boolean isLoading)
mIsLoading.set(isLoading);
public N getNavigator()
return mNavigator.get();
public void setNavigator(N navigator)
this.mNavigator = new WeakReference<>(navigator);
public SchedulerProvider getSchedulerProvider()
return mSchedulerProvider;
5.HomeViewModel.java
public class HomeViewModel extends BaseViewModel<HomeNavigator>
private MutableLiveData<ArrayList<HeartRateResultsModel>> heartRateResultsLiveData;
public HomeViewModel(DataManager dataManager, SchedulerProvider schedulerProvider)
super(dataManager, schedulerProvider);
heartRateResultsLiveData = new MutableLiveData<>();
fetchRepos();
public void fetchRepos()
setIsLoading(true);
getCompositeDisposable().add(getDataManager()
.getHeartRateResults()
.subscribeOn(getSchedulerProvider().io())
.observeOn(getSchedulerProvider().ui())
.subscribe(heartRateResultsModels ->
heartRateResultsLiveData.setValue(heartRateResultsModels);
setIsLoading(false);
, throwable ->
setIsLoading(false);
getNavigator().handleError(throwable);
));
public LiveData<ArrayList<HeartRateResultsModel>> getHeartRateResultsLiveData()
return heartRateResultsLiveData;
6.BindingUtils.java
public final class BindingUtils
private BindingUtils()
// This class is not publicly instantiable
@BindingAdapter("imageUrl")
public static void setImageUrl(ImageView imageView, String url)
Context context = imageView.getContext();
Glide.with(context).load(url).into(imageView);
@BindingAdapter("onNavigationItemSelected")
public static void setOnNavigationItemSelectedListener(
BottomNavigationView view, OnNavigationItemSelectedListener listener)
view.setOnNavigationItemSelectedListener(listener);
@BindingAdapter("adapter")
public static void addHeartRateResultsItems(RecyclerView recyclerView,
ArrayList<HeartRateResultsModel> heartRateResultsModels)
HeartRateResultsAdapter adapter = (HeartRateResultsAdapter) recyclerView.getAdapter();
if (adapter != null)
adapter.clearItems();
adapter.addItems(heartRateResultsModels);
7.DataManager.java
public interface DataManager extends DbHelper, PreferencesHelper, ApiHelper
8.DbHelper.java
public interface DbHelper
Single<ArrayList<HeartRateResultsModel>> getHeartRateResults();
9.AppDataManager.java
public class AppDataManager implements DataManager
private final ApiHelper mApiHelper;
private final Context mContext;
private final DbHelper mDbHelper;
private final Gson mGson;
private final PreferencesHelper mPreferencesHelper;
@Inject
public AppDataManager(Context context,
DbHelper dbHelper,
PreferencesHelper preferencesHelper,
ApiHelper apiHelper,
Gson gson)
mContext = context;
mDbHelper = dbHelper;
mPreferencesHelper = preferencesHelper;
mApiHelper = apiHelper;
mGson = gson;
@Override
public Single<ArrayList<HeartRateResultsModel>> getHeartRateResults()
return mDbHelper.getHeartRateResults();
10.AppDbHelper.java
@Singleton
public class AppDbHelper implements DbHelper
private final AppDatabase mAppDatabase;
@Inject
public AppDbHelper(AppDatabase appDatabase)
this.mAppDatabase = appDatabase;
@Override
public Single<ArrayList<HeartRateResultsModel>> getHeartRateResults()
return Single.fromCallable(new Callable<ArrayList<HeartRateResultsModel>>()
@Override
public ArrayList<HeartRateResultsModel> call() throws Exception
ArrayList<HeartRateResultsModel> models = new ArrayList<>();
models.add(new HeartRateResultsModel("","1"));
models.add(new HeartRateResultsModel("","2"));
return models;
);
android mvvm android-recyclerview android-databinding android-livedata
I want to feed the recyclerview with a list of elements and livedata. I used data binding adapter and when I want to send data to adapter the list return null from livedata. the whole code are below.
thanks
I debugged the code and I saw when the data came from the AppDbHelper.java to HomeViewmodel.java and set to the live data the bindingadapter didn't change. thus, although the livedata is not null, the arraylist at databinding adapter(heartRateResultsModels) is null and made the app crashed.
1.fragment_home.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="viewModel"
type="ir.basamadazmanovin.heartrate.ui.main.home.HomeViewModel" />
</data>
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/swipe_refresh_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:refreshing="@viewModel.isLoading">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.main.home.HomeFragment">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/fragment_home_recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:adapter="@viewModel.heartRateResultsLiveData"
tools:listitem="@layout/row_fragment_home" />
</FrameLayout>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</layout>
2.BaseFragment.java
public abstract class BaseFragment<T extends ViewDataBinding, V extends BaseViewModel> extends Fragment
protected FragmentNavigation mFragmentNavigation;
private BaseActivity mActivity;
private View mRootView;
private T mViewDataBinding;
private V mViewModel;
public abstract int getBindingVariable();
public abstract
@LayoutRes
int getLayoutId();
public abstract V getViewModel();
@Override
public void onAttach(Context context)
super.onAttach(context);
if (context instanceof BaseActivity)
BaseActivity activity = (BaseActivity) context;
this.mActivity = activity;
activity.onFragmentAttached();
if (context instanceof FragmentNavigation)
mFragmentNavigation = (FragmentNavigation) context;
else
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
@Override
public void onCreate(@Nullable Bundle savedInstanceState)
performDependencyInjection();
super.onCreate(savedInstanceState);
mViewModel = getViewModel();
setHasOptionsMenu(false);
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
mViewDataBinding = DataBindingUtil.inflate(inflater, getLayoutId(), container, false);
mRootView = mViewDataBinding.getRoot();
return mRootView;
public BaseActivity getBaseActivity()
return mActivity;
public T getViewDataBinding()
return mViewDataBinding;
public void hideKeyboard()
if (mActivity != null)
mActivity.hideKeyboard();
public boolean isNetworkConnected()
return mActivity != null && mActivity.isNetworkConnected();
public void openActivityOnTokenExpire()
if (mActivity != null)
mActivity.openActivityOnTokenExpire();
private void performDependencyInjection()
AndroidSupportInjection.inject(this);
public interface Callback
void onFragmentAttached();
void onFragmentDetached(String tag);
3.HomeFragment.java
public class HomeFragment extends BaseFragment<FragmentHomeBinding,HomeViewModel> implements HomeNavigator
FragmentHomeBinding mFragmentHomeBinding;
@Inject
LinearLayoutManager mLayoutManager;
@Inject
HeartRateResultsAdapter mAdapter;
@Inject
ViewModelProviderFactory factory;
private HomeViewModel mHomeViewModel;
public static HomeFragment newInstance()
return new HomeFragment();
@Override
public int getBindingVariable()
return BR.viewModel;
@Override
public int getLayoutId()
return R.layout.fragment_home;
@Override
public HomeViewModel getViewModel()
mHomeViewModel = ViewModelProviders.of(this, factory).get(HomeViewModel.class);
return null;
@Override
public void onCreate(@Nullable Bundle savedInstanceState)
super.onCreate(savedInstanceState);
mHomeViewModel.setNavigator(this);
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState)
super.onViewCreated(view, savedInstanceState);
mFragmentHomeBinding = getViewDataBinding();
setUp();
private void setUp()
mLayoutManager.setOrientation(RecyclerView.VERTICAL);
mFragmentHomeBinding.fragmentHomeRecyclerView.setLayoutManager(mLayoutManager);
mFragmentHomeBinding.fragmentHomeRecyclerView.setItemAnimator(new DefaultItemAnimator());
mFragmentHomeBinding.fragmentHomeRecyclerView.setAdapter(mAdapter);
@Override
public void handleError(Throwable throwable)
4.BaseViewModel.java
public class BaseViewModel<N> extends ViewModel
private final DataManager mDataManager;
private final ObservableBoolean mIsLoading = new ObservableBoolean(false);
private final SchedulerProvider mSchedulerProvider;
private CompositeDisposable mCompositeDisposable;
private WeakReference<N> mNavigator;
public BaseViewModel(DataManager dataManager,
SchedulerProvider schedulerProvider)
this.mDataManager = dataManager;
this.mSchedulerProvider = schedulerProvider;
this.mCompositeDisposable = new CompositeDisposable();
@Override
protected void onCleared()
mCompositeDisposable.dispose();
super.onCleared();
public CompositeDisposable getCompositeDisposable()
return mCompositeDisposable;
public DataManager getDataManager()
return mDataManager;
public ObservableBoolean getIsLoading()
return mIsLoading;
public void setIsLoading(boolean isLoading)
mIsLoading.set(isLoading);
public N getNavigator()
return mNavigator.get();
public void setNavigator(N navigator)
this.mNavigator = new WeakReference<>(navigator);
public SchedulerProvider getSchedulerProvider()
return mSchedulerProvider;
5.HomeViewModel.java
public class HomeViewModel extends BaseViewModel<HomeNavigator>
private MutableLiveData<ArrayList<HeartRateResultsModel>> heartRateResultsLiveData;
public HomeViewModel(DataManager dataManager, SchedulerProvider schedulerProvider)
super(dataManager, schedulerProvider);
heartRateResultsLiveData = new MutableLiveData<>();
fetchRepos();
public void fetchRepos()
setIsLoading(true);
getCompositeDisposable().add(getDataManager()
.getHeartRateResults()
.subscribeOn(getSchedulerProvider().io())
.observeOn(getSchedulerProvider().ui())
.subscribe(heartRateResultsModels ->
heartRateResultsLiveData.setValue(heartRateResultsModels);
setIsLoading(false);
, throwable ->
setIsLoading(false);
getNavigator().handleError(throwable);
));
public LiveData<ArrayList<HeartRateResultsModel>> getHeartRateResultsLiveData()
return heartRateResultsLiveData;
6.BindingUtils.java
public final class BindingUtils
private BindingUtils()
// This class is not publicly instantiable
@BindingAdapter("imageUrl")
public static void setImageUrl(ImageView imageView, String url)
Context context = imageView.getContext();
Glide.with(context).load(url).into(imageView);
@BindingAdapter("onNavigationItemSelected")
public static void setOnNavigationItemSelectedListener(
BottomNavigationView view, OnNavigationItemSelectedListener listener)
view.setOnNavigationItemSelectedListener(listener);
@BindingAdapter("adapter")
public static void addHeartRateResultsItems(RecyclerView recyclerView,
ArrayList<HeartRateResultsModel> heartRateResultsModels)
HeartRateResultsAdapter adapter = (HeartRateResultsAdapter) recyclerView.getAdapter();
if (adapter != null)
adapter.clearItems();
adapter.addItems(heartRateResultsModels);
7.DataManager.java
public interface DataManager extends DbHelper, PreferencesHelper, ApiHelper
8.DbHelper.java
public interface DbHelper
Single<ArrayList<HeartRateResultsModel>> getHeartRateResults();
9.AppDataManager.java
public class AppDataManager implements DataManager
private final ApiHelper mApiHelper;
private final Context mContext;
private final DbHelper mDbHelper;
private final Gson mGson;
private final PreferencesHelper mPreferencesHelper;
@Inject
public AppDataManager(Context context,
DbHelper dbHelper,
PreferencesHelper preferencesHelper,
ApiHelper apiHelper,
Gson gson)
mContext = context;
mDbHelper = dbHelper;
mPreferencesHelper = preferencesHelper;
mApiHelper = apiHelper;
mGson = gson;
@Override
public Single<ArrayList<HeartRateResultsModel>> getHeartRateResults()
return mDbHelper.getHeartRateResults();
10.AppDbHelper.java
@Singleton
public class AppDbHelper implements DbHelper
private final AppDatabase mAppDatabase;
@Inject
public AppDbHelper(AppDatabase appDatabase)
this.mAppDatabase = appDatabase;
@Override
public Single<ArrayList<HeartRateResultsModel>> getHeartRateResults()
return Single.fromCallable(new Callable<ArrayList<HeartRateResultsModel>>()
@Override
public ArrayList<HeartRateResultsModel> call() throws Exception
ArrayList<HeartRateResultsModel> models = new ArrayList<>();
models.add(new HeartRateResultsModel("","1"));
models.add(new HeartRateResultsModel("","2"));
return models;
);
android mvvm android-recyclerview android-databinding android-livedata
android mvvm android-recyclerview android-databinding android-livedata
edited Apr 7 at 20:25
omid
asked Mar 28 at 12:58
omidomid
1132 silver badges10 bronze badges
1132 silver badges10 bronze badges
add a comment
|
add a comment
|
1 Answer
1
active
oldest
votes
add mViewDataBinding.setLifecycleOwner(this);
on method : onViewCreated()
at class BaseFragment
, like this :
@Override
public void onViewCreated(@NonNull View view, Bundle savedInstanceState)
super.onViewCreated(view, savedInstanceState);
mViewDataBinding.setVariable(getBindingVariable(), mViewModel);
mViewDataBinding.setLifecycleOwner(this);
mViewDataBinding.executePendingBindings();
add a comment
|
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/4.0/"u003ecc by-sa 4.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55398265%2fdatabinding-recyclerview-adapter-received-null-list-from-livedata%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
add mViewDataBinding.setLifecycleOwner(this);
on method : onViewCreated()
at class BaseFragment
, like this :
@Override
public void onViewCreated(@NonNull View view, Bundle savedInstanceState)
super.onViewCreated(view, savedInstanceState);
mViewDataBinding.setVariable(getBindingVariable(), mViewModel);
mViewDataBinding.setLifecycleOwner(this);
mViewDataBinding.executePendingBindings();
add a comment
|
add mViewDataBinding.setLifecycleOwner(this);
on method : onViewCreated()
at class BaseFragment
, like this :
@Override
public void onViewCreated(@NonNull View view, Bundle savedInstanceState)
super.onViewCreated(view, savedInstanceState);
mViewDataBinding.setVariable(getBindingVariable(), mViewModel);
mViewDataBinding.setLifecycleOwner(this);
mViewDataBinding.executePendingBindings();
add a comment
|
add mViewDataBinding.setLifecycleOwner(this);
on method : onViewCreated()
at class BaseFragment
, like this :
@Override
public void onViewCreated(@NonNull View view, Bundle savedInstanceState)
super.onViewCreated(view, savedInstanceState);
mViewDataBinding.setVariable(getBindingVariable(), mViewModel);
mViewDataBinding.setLifecycleOwner(this);
mViewDataBinding.executePendingBindings();
add mViewDataBinding.setLifecycleOwner(this);
on method : onViewCreated()
at class BaseFragment
, like this :
@Override
public void onViewCreated(@NonNull View view, Bundle savedInstanceState)
super.onViewCreated(view, savedInstanceState);
mViewDataBinding.setVariable(getBindingVariable(), mViewModel);
mViewDataBinding.setLifecycleOwner(this);
mViewDataBinding.executePendingBindings();
answered Aug 22 at 4:37
MenmaMenma
5091 gold badge7 silver badges30 bronze badges
5091 gold badge7 silver badges30 bronze badges
add a comment
|
add a comment
|
Got a question that you can’t ask on public Stack Overflow? Learn more about sharing private information with Stack Overflow for Teams.
Got a question that you can’t ask on public Stack Overflow? Learn more about sharing private information with Stack Overflow for Teams.
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55398265%2fdatabinding-recyclerview-adapter-received-null-list-from-livedata%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown