I want to display favored items from two tables: Item and ItemMoto. Both tables share same table Favourite.
Portion of files are"
FavouriteListFragment.java
public class FavouriteListFragment extends PSFragment implements DataBoundListAdapter.DiffUtilDispatchedInterface {
private final androidx.databinding.DataBindingComponent dataBindingComponent = new FragmentDataBindingComponent(this);
private FavouriteViewModel favouriteViewModel;
private FavouriteMotoViewModel favouriteViewModelMoto;
@VisibleForTesting
private AutoClearedValue<FragmentFavouriteListBinding> binding;
private AutoClearedValue<ItemVerticalListAdapter> adapter;
private AutoClearedValue<ItemAutoVerticalListAdapter> adapterMoto;
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
FragmentFavouriteListBinding dataBinding = DataBindingUtil.inflate(inflater, R.layout.fragment_favourite_list, container,
false, dataBindingComponent);
binding = new AutoClearedValue<>(this, dataBinding);
// binding.get().setLoadingMore(connectivity.isConnected());
return binding.get().getRoot();
}
}
@Override
protected void initViewModels() {favouriteViewModel = new ViewModelProvider(this,
viewModelFactory).get(FavouriteViewModel.class);
favouriteViewModelMoto = new ViewModelProvider(this,
viewModelFactory).get(FavouriteMotoViewModel.class);
}
@Override
protected void initData() {
favouriteViewModel.setItemFavouriteListObj(loginUserId, String.valueOf(favouriteViewModel.offset));
LiveData<Resource<List<Item>>> news = favouriteViewModel.getItemFavouriteData();
if (news != null) {
news.observe(this, listResource -> {
if (listResource != null) {
switch (listResource.status) {
case LOADING:
// Loading State
// Data are from Local DB
if (listResource.data != null) {
//fadeIn Animation
fadeIn(binding.get().getRoot());
// Update the data
replaceData(listResource.data);
}
break;
case SUCCESS:
// Success State
// Data are from Server
if (listResource.data != null) {
// Update the data
replaceData(listResource.data);
}
favouriteViewModel.setLoadingState(false);
break;
case ERROR:
// Error State
favouriteViewModel.setLoadingState(false);
favouriteViewModel.forceEndLoading = true;
break;
default:
// Default
break;
}
} else {
// Init Object or Empty Data
if (favouriteViewModel.offset > 1) {
// No more data for this list
// So, Block all future loading
favouriteViewModel.forceEndLoading = true;
}
}
});
}
private void replaceData(List<Item> favouriteList) {
adapter.get().replace(favouriteList);
binding.get().executePendingBindings();
}
}
FavouriteViewModel.java
public class FavouriteViewModel extends PSViewModel {
private final LiveData<Resource<List<Item>>> itemFavouriteData;
private MutableLiveData<FavouriteViewModel.TmpDataHolder> itemFavouriteListObj = new MutableLiveData<>();
@Inject
FavouriteViewModel(ItemRepository itemRepository) {
itemFavouriteData = Transformations.switchMap(itemFavouriteListObj, obj -> {
if (obj == null) {
return AbsentLiveData.create();
}
Utils.psLog("itemFavouriteData");
return itemRepository.getFavouriteList(Config.API_KEY, obj.userId, obj.offset);
});
}
public LiveData<Resource<List<Item>>> getItemFavouriteData() {
return itemFavouriteData;
}
}
ItemRepository.java
@Singleton
public class ItemRepository extends PSRepository {
public LiveData<Resource<List<Item>>> getFavouriteList(String apiKey, String loginUserId, String offset) {
final MediatorLiveData<Resource<Boolean>> favLiveData = new MediatorLiveData<>();
return new NetworkBoundResource<List<Item>, List<Item>>(appExecutors) {
@Override
protected void saveCallResult(@NonNull List<Item> itemList) {
Utils.psLog("SaveCallResult of related products.");
try {
db.runInTransaction(() -> {
db.itemDao().deleteAllFavouriteItems();
db.itemDao().insertAll(itemList);
for (int i = 0; i < itemList.size(); i++) {
db.itemDao().insertFavourite(new ItemFavourite(itemList.get(i).id, i + 1));
}
});
} catch (Exception ex) {
Utils.psErrorLog("Error at ", ex);
}
}
@Override
protected boolean shouldFetch(@Nullable List<Item> data) {
// Recent news always load from server
return connectivity.isConnected();
}
@NonNull
@Override
protected LiveData<List<Item>> loadFromDb() {
Utils.psLog("Load related From Db");
return db.itemDao().getAllFavouriteProducts();
}
@NonNull
@Override
protected LiveData<ApiResponse<List<Item>>> createCall() {
Utils.psLog("Call API Service to get related.");
return psApiService.getFavouriteList(apiKey, Utils.checkUserId(loginUserId), String.valueOf(Config.ITEM_COUNT), offset);
}
@Override
protected void onFetchFailed(int code, String message) {
Utils.psLog("Fetch Failed (getRelated) : " + message);
if (code == Config.ERROR_CODE_10001) {
try {
appExecutors.diskIO().execute(() -> db.runInTransaction(() -> db.itemDao().deleteAllFavouriteItems()));
} catch (Exception ex) {
Utils.psErrorLog("Error at ", ex);
}
}
}
}.asLiveData();
}
}
ItemDao.java
@Query("SELECT prd.* FROM Item prd, ItemFavourite fp WHERE prd.id = fp.itemId order by fp.sorting ")
// I have tried the below code
//@Query("select * from ItemFavourite fp left join Item prd on fp.itemId = prd.id left join ItemMoto im on fp.itemId = im.id")
LiveData<List<Item>> getAllFavouriteProducts();
The above displays favourited items from table Item.
Same idea for table ItemMoto exempt file name changes.
Before both Item and ItemMoto were displaying favourite from their own fragments.
Now I am trying to combine them to show on one fragment.
I have read about using Mediator, but I couldn’t find an example that it similar to mine or I am just confused. I don’t know if it goes at Model or Repository level.
Any idea where to start?
I have tried to combine the two tables and display them, but no success.
Also here is the php side:
function get_item_favourite( $conds = array(), $limit = false, $offset = false )
{
$this->db->select('bs_items.*');
$this->db->from('bs_items');
$this->db->join('bs_favourite', 'bs_favourite.item_id = bs_items.id');
if(isset($conds['user_id'])) {
if ($conds['user_id'] != "" || $conds['user_id'] != 0) {
$this->db->where( 'user_id', $conds['user_id'] );
}
}
if ( $limit ) {
// if there is limit, set the limit
$this->db->limit($limit);
}
if ( $offset ) {
// if there is offset, set the offset,
$this->db->offset($offset);
}
return $this->db->get();
// print_r($this->db->last_query());die;
}
Also there is another query that handles ItemMoto
Source: Android Questions