提交 050b780e 编写于 作者: V Vignesh150493

Bring on Android Viewmodel and persist data on config change

上级 5dae12e4
......@@ -101,6 +101,11 @@ dependencies {
androidTestCompile "com.android.support.test.espresso:espresso-intents:$rootProject.espressoVersion"
androidTestCompile "org.mockito:mockito-core:$rootProject.mockitoVersion"
androidTestAnnotationProcessor "com.google.dagger:dagger-compiler:$rootProject.dagger2Version"
//Viewmodel
compile "android.arch.lifecycle:extensions:1.0.0-alpha3"
annotationProcessor "android.arch.lifecycle:compiler:1.0.0-alpha3"
}
configurations.all {
......
......@@ -45,8 +45,7 @@
<activity
android:name=".ui.main.MainActivity"
android:launchMode="singleTop"
android:screenOrientation="portrait" />
android:launchMode="singleTop" />
<activity
android:name="com.mindorks.framework.mvvm.ui.feed.FeedActivity"
......
package com.mindorks.framework.mvvm;
import android.arch.lifecycle.ViewModel;
import android.arch.lifecycle.ViewModelProvider;
/**
* Created by RV on 19/07/17.
* <p>
* A provider factory that persists ViewModels{@link ViewModel}.
* Used if the viewmodel has a parameterized constructor.
*/
public class ViewModelProviderFactory<V> implements ViewModelProvider.Factory {
private V viewModel;
public ViewModelProviderFactory(V viewModel) {
this.viewModel = viewModel;
}
@Override
public <T extends ViewModel> T create(Class<T> modelClass) {
if (modelClass.isAssignableFrom(viewModel.getClass())) {
return (T) viewModel;
}
throw new IllegalArgumentException("Unknown class name");
}
}
......@@ -29,6 +29,7 @@ public class QuestionCardData {
public Question question;
public List<Option> options;
public boolean mShowCorrectOptions;
public QuestionCardData(Question question, List<Option> options) {
this.question = question;
......
......@@ -16,13 +16,14 @@
package com.mindorks.framework.mvvm.di.module;
import android.arch.lifecycle.ViewModelProvider;
import android.content.Context;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import com.mindorks.framework.mvvm.ViewModelProviderFactory;
import com.mindorks.framework.mvvm.data.DataManager;
import com.mindorks.framework.mvvm.data.model.api.BlogResponse;
import com.mindorks.framework.mvvm.data.model.api.OpenSourceResponse;
import com.mindorks.framework.mvvm.di.ActivityContext;
import com.mindorks.framework.mvvm.di.PerActivity;
import com.mindorks.framework.mvvm.ui.about.AboutViewModel;
......@@ -68,11 +69,6 @@ public class ActivityModule {
return mActivity;
}
@Provides
CompositeDisposable provideCompositeDisposable() {
return new CompositeDisposable();
}
@Provides
SchedulerProvider provideSchedulerProvider() {
return new AppSchedulerProvider();
......@@ -81,53 +77,52 @@ public class ActivityModule {
@Provides
@PerActivity
SplashViewModel provideSplashViewModel(DataManager dataManager,
SchedulerProvider schedulerProvider,
CompositeDisposable compositeDisposable) {
return new SplashViewModel(dataManager, schedulerProvider, compositeDisposable);
SchedulerProvider schedulerProvider) {
return new SplashViewModel(dataManager, schedulerProvider);
}
@Provides
@PerActivity
LoginViewModel provideLoginViewModel(DataManager dataManager,
SchedulerProvider schedulerProvider,
CompositeDisposable compositeDisposable) {
return new LoginViewModel(dataManager, schedulerProvider, compositeDisposable);
SchedulerProvider schedulerProvider) {
return new LoginViewModel(dataManager, schedulerProvider);
}
@Provides
@PerActivity
MainViewModel provideMainViewModel(DataManager dataManager,
SchedulerProvider schedulerProvider,
CompositeDisposable compositeDisposable) {
return new MainViewModel(dataManager, schedulerProvider, compositeDisposable);
SchedulerProvider schedulerProvider) {
return new MainViewModel(dataManager, schedulerProvider);
}
@Provides
@PerActivity
ViewModelProvider.Factory mainViewModelProvider(MainViewModel mainViewModel) {
return new ViewModelProviderFactory<MainViewModel>(mainViewModel);
}
@Provides
AboutViewModel provideAboutViewModel(DataManager dataManager,
SchedulerProvider schedulerProvider,
CompositeDisposable compositeDisposable) {
return new AboutViewModel(dataManager, schedulerProvider, compositeDisposable);
SchedulerProvider schedulerProvider) {
return new AboutViewModel(dataManager, schedulerProvider);
}
@Provides
RateUsViewModel provideRateUsViewModel(DataManager dataManager,
SchedulerProvider schedulerProvider,
CompositeDisposable compositeDisposable) {
return new RateUsViewModel(dataManager, schedulerProvider, compositeDisposable);
SchedulerProvider schedulerProvider) {
return new RateUsViewModel(dataManager, schedulerProvider);
}
@Provides
BlogViewModel provideBlogViewModel(DataManager dataManager,
SchedulerProvider schedulerProvider,
CompositeDisposable compositeDisposable) {
return new BlogViewModel(dataManager, schedulerProvider, compositeDisposable);
SchedulerProvider schedulerProvider) {
return new BlogViewModel(dataManager, schedulerProvider);
}
@Provides
OpenSourceViewModel provideOpenSourceViewModel(DataManager dataManager,
SchedulerProvider schedulerProvider,
CompositeDisposable compositeDisposable) {
return new OpenSourceViewModel(dataManager, schedulerProvider, compositeDisposable);
SchedulerProvider schedulerProvider) {
return new OpenSourceViewModel(dataManager, schedulerProvider);
}
@Provides
......@@ -152,9 +147,8 @@ public class ActivityModule {
@Provides
@PerActivity
FeedViewModel provideFeedViewModel(DataManager dataManager,
SchedulerProvider schedulerProvider,
CompositeDisposable compositeDisposable) {
return new FeedViewModel(dataManager, schedulerProvider, compositeDisposable);
SchedulerProvider schedulerProvider) {
return new FeedViewModel(dataManager, schedulerProvider);
}
}
......@@ -74,7 +74,6 @@ public class AboutFragment extends BaseFragment<FragmentAboutBinding, AboutViewM
@Override
public void onDestroyView() {
mAboutViewModel.onDestroy();
super.onDestroyView();
}
private void performDependencyInjection(){
......
......@@ -29,9 +29,8 @@ import io.reactivex.disposables.CompositeDisposable;
public class AboutViewModel extends BaseViewModel<AboutNavigator> {
public AboutViewModel(DataManager dataManager,
SchedulerProvider schedulerProvider,
CompositeDisposable compositeDisposable) {
super(dataManager, schedulerProvider, compositeDisposable);
SchedulerProvider schedulerProvider) {
super(dataManager, schedulerProvider);
}
public void onNavBackClick() {
......
......@@ -62,6 +62,7 @@ public abstract class BaseActivity<T extends ViewDataBinding, V extends BaseView
initializeActivityComponent();
performDependencyInjection();
performDataBinding();
mViewModel.onViewCreated();
}
private void initializeActivityComponent() {
......@@ -103,6 +104,7 @@ public abstract class BaseActivity<T extends ViewDataBinding, V extends BaseView
@Override
protected void onDestroy() {
mViewModel.onDestroyView();
super.onDestroy();
}
......
......@@ -59,6 +59,7 @@ public abstract class BaseFragment<T extends ViewDataBinding, V extends BaseView
mViewModel = getViewModel();
mViewDataBinding.setVariable(getBindingVariable(), mViewModel);
mViewDataBinding.executePendingBindings();
mViewModel.onViewCreated();
}
@Override
......@@ -92,9 +93,11 @@ public abstract class BaseFragment<T extends ViewDataBinding, V extends BaseView
return mViewDataBinding;
}
@Override
public void onDestroy() {
super.onDestroy();
public void onDestroyView() {
mViewModel.onDestroyView();
super.onDestroyView();
}
public boolean isNetworkConnected() {
......
......@@ -16,6 +16,7 @@
package com.mindorks.framework.mvvm.ui.base;
import android.arch.lifecycle.ViewModel;
import android.databinding.ObservableBoolean;
import com.mindorks.framework.mvvm.data.DataManager;
......@@ -27,30 +28,35 @@ import io.reactivex.disposables.CompositeDisposable;
* Created by amitshekhar on 07/07/17.
*/
public abstract class BaseViewModel<N> {
public abstract class BaseViewModel<N> extends ViewModel {
private N mNavigator;
private final DataManager mDataManager;
private final SchedulerProvider mSchedulerProvider;
private final CompositeDisposable mCompositeDisposable;
private final ObservableBoolean mIsLoading = new ObservableBoolean(false);
private CompositeDisposable mCompositeDisposable;
public BaseViewModel(DataManager dataManager,
SchedulerProvider schedulerProvider,
CompositeDisposable compositeDisposable) {
SchedulerProvider schedulerProvider) {
this.mDataManager = dataManager;
this.mSchedulerProvider = schedulerProvider;
this.mCompositeDisposable = compositeDisposable;
}
public void setNavigator(N navigator) {
this.mNavigator = navigator;
}
public void onDestroy() {
public void onViewCreated() {
this.mCompositeDisposable = new CompositeDisposable();
}
public void onDestroyView() {
mCompositeDisposable.dispose();
}
public N getNavigator() {
return mNavigator;
}
......
......@@ -11,7 +11,7 @@ import io.reactivex.disposables.CompositeDisposable;
*/
public class FeedViewModel extends BaseViewModel {
public FeedViewModel(DataManager dataManager, SchedulerProvider schedulerProvider, CompositeDisposable compositeDisposable) {
super(dataManager, schedulerProvider, compositeDisposable);
public FeedViewModel(DataManager dataManager, SchedulerProvider schedulerProvider) {
super(dataManager, schedulerProvider);
}
}
......@@ -98,7 +98,6 @@ public class BlogFragment extends BaseFragment<FragmentBlogBinding, BlogViewMode
@Override
public void onDestroyView() {
mBlogViewModel.onDestroy();
super.onDestroyView();
}
......
......@@ -32,9 +32,8 @@ import io.reactivex.functions.Consumer;
public class BlogViewModel extends BaseViewModel<BlogNavigator> {
public BlogViewModel(DataManager dataManager,
SchedulerProvider schedulerProvider,
CompositeDisposable compositeDisposable) {
super(dataManager, schedulerProvider, compositeDisposable);
SchedulerProvider schedulerProvider) {
super(dataManager, schedulerProvider);
}
public void fetchBlogs() {
......
......@@ -99,7 +99,6 @@ public class OpenSourceFragment extends BaseFragment<FragmentOpenSourceBinding,
@Override
public void onDestroyView() {
mOpenSourceViewModel.onDestroy();
super.onDestroyView();
}
......
......@@ -41,9 +41,8 @@ public class OpenSourceViewModel extends BaseViewModel<OpenSourceNavigator> {
public OpenSourceViewModel(DataManager dataManager,
SchedulerProvider schedulerProvider,
CompositeDisposable compositeDisposable) {
super(dataManager, schedulerProvider, compositeDisposable);
SchedulerProvider schedulerProvider) {
super(dataManager, schedulerProvider);
}
public void fetchRepos() {
......
......@@ -55,7 +55,6 @@ public class LoginActivity extends BaseActivity<ActivityLoginBinding, LoginViewM
@Override
protected void onDestroy() {
super.onDestroy();
mLoginViewModel.onDestroy();
}
@Override
......
......@@ -33,9 +33,8 @@ import io.reactivex.functions.Consumer;
public class LoginViewModel extends BaseViewModel<LoginNavigator> {
public LoginViewModel(DataManager dataManager,
SchedulerProvider schedulerProvider,
CompositeDisposable compositeDisposable) {
super(dataManager, schedulerProvider, compositeDisposable);
SchedulerProvider schedulerProvider) {
super(dataManager, schedulerProvider);
}
public void onServerLoginClick() {
......
......@@ -16,8 +16,11 @@
package com.mindorks.framework.mvvm.ui.main;
import android.arch.lifecycle.ViewModelProvider;
import android.arch.lifecycle.ViewModelProviders;
import android.content.Context;
import android.content.Intent;
import android.databinding.BindingAdapter;
import android.databinding.DataBindingUtil;
import android.graphics.drawable.Animatable;
import android.graphics.drawable.Drawable;
......@@ -49,19 +52,23 @@ import com.mindorks.framework.mvvm.ui.feed.FeedActivity;
import com.mindorks.framework.mvvm.ui.login.LoginActivity;
import com.mindorks.framework.mvvm.ui.main.rating.RateUsDialog;
import com.mindorks.framework.mvvm.utils.ScreenUtils;
import com.mindorks.framework.mvvm.utils.ViewAnimationUtils;
import com.mindorks.placeholderview.SwipeDecor;
import com.mindorks.placeholderview.SwipePlaceHolderView;
import com.mindorks.placeholderview.listeners.ItemRemovedListener;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
public class MainActivity extends BaseActivity<ActivityMainBinding,MainViewModel> implements MainNavigator {
public class MainActivity extends BaseActivity<ActivityMainBinding, MainViewModel> implements MainNavigator {
@Inject
MainViewModel mMainViewModel;
ViewModelProvider.Factory mViewModelFactory;
private MainViewModel mMainViewModel;
private DrawerLayout mDrawer;
......@@ -100,7 +107,6 @@ public class MainActivity extends BaseActivity<ActivityMainBinding,MainViewModel
@Override
protected void onDestroy() {
super.onDestroy();
mMainViewModel.onDestroy();
}
@Override
......@@ -199,6 +205,8 @@ public class MainActivity extends BaseActivity<ActivityMainBinding,MainViewModel
mMainViewModel.onCardExhausted();
}
}, 800);
} else {
mMainViewModel.removeQuestionCard();
}
}
});
......@@ -235,31 +243,27 @@ public class MainActivity extends BaseActivity<ActivityMainBinding,MainViewModel
});
}
@Override
public void refreshQuestionnaire(List<QuestionCardData> questionList) {
for (QuestionCardData question : questionList) {
if (question != null
&& question.options != null
&& question.options.size() == 3) {
mCardsContainerView.addView(new QuestionCard(question));
@BindingAdapter({"adapter", "action"})
public static void setAdapter(SwipePlaceHolderView mCardsContainerView, ArrayList<QuestionCardData> mQuestionList, int mAction) {
if (mAction == MainViewModel.ACTION_ADD_ALL) {
if (mQuestionList != null) {
mCardsContainerView.removeAllViews();
for (QuestionCardData question : mQuestionList) {
if (question != null
&& question.options != null
&& question.options.size() == 3) {
mCardsContainerView.addView(new QuestionCard(question));
}
}
ViewAnimationUtils.scaleAnimateView(mCardsContainerView);
}
}
}
@Override
public void reloadQuestionnaire(List<QuestionCardData> questionList) {
refreshQuestionnaire(questionList);
ScaleAnimation animation =
new ScaleAnimation(
1.15f, 1, 1.15f, 1,
Animation.RELATIVE_TO_SELF, 0.5f,
Animation.RELATIVE_TO_SELF, 0.5f);
mCardsContainerView.setAnimation(animation);
animation.setDuration(100);
animation.start();
}
public void onFragmentDetached(String tag) {
FragmentManager fragmentManager = getSupportFragmentManager();
Fragment fragment = fragmentManager.findFragmentByTag(tag);
......@@ -304,8 +308,10 @@ public class MainActivity extends BaseActivity<ActivityMainBinding,MainViewModel
public void handleError(Throwable throwable) {
// handle error
}
@Override
public MainViewModel getViewModel() {
mMainViewModel = ViewModelProviders.of(this, mViewModelFactory).get(MainViewModel.class);
return mMainViewModel;
}
......@@ -322,7 +328,6 @@ public class MainActivity extends BaseActivity<ActivityMainBinding,MainViewModel
@Override
public void performDependencyInjection() {
getActivityComponent().inject(this);
}
......
......@@ -26,10 +26,6 @@ import java.util.List;
public interface MainNavigator {
void refreshQuestionnaire(List<QuestionCardData> questionList);
void reloadQuestionnaire(List<QuestionCardData> questionList);
void openLoginActivity();
void handleError(Throwable throwable);
......
......@@ -16,6 +16,7 @@
package com.mindorks.framework.mvvm.ui.main;
import android.databinding.ObservableArrayList;
import android.databinding.ObservableField;
import com.mindorks.framework.mvvm.data.DataManager;
......@@ -24,6 +25,7 @@ import com.mindorks.framework.mvvm.data.model.others.QuestionCardData;
import com.mindorks.framework.mvvm.ui.base.BaseViewModel;
import com.mindorks.framework.mvvm.utils.rx.SchedulerProvider;
import java.util.ArrayList;
import java.util.List;
import io.reactivex.disposables.CompositeDisposable;
......@@ -39,11 +41,15 @@ public class MainViewModel extends BaseViewModel<MainNavigator> {
public final ObservableField<String> userName = new ObservableField<>();
public final ObservableField<String> userEmail = new ObservableField<>();
public final ObservableField<String> userProfilePicUrl = new ObservableField<>();
public ObservableArrayList<QuestionCardData> questionDataList = new ObservableArrayList<>();
public int mAction = NO_ACTION;
public static final int NO_ACTION = -1, ACTION_ADD_ALL = 0, ACTION_DELETE_SINGLE = 1;
public MainViewModel(DataManager dataManager,
SchedulerProvider schedulerProvider,
CompositeDisposable compositeDisposable) {
super(dataManager, schedulerProvider, compositeDisposable);
SchedulerProvider schedulerProvider) {
super(dataManager, schedulerProvider);
}
public void updateAppVersion(String version) {
......@@ -69,18 +75,26 @@ public class MainViewModel extends BaseViewModel<MainNavigator> {
}
public void onViewInitialized() {
getCompositeDisposable().add(getDataManager()
.getQuestionCardData()
.subscribeOn(getSchedulerProvider().io())
.observeOn(getSchedulerProvider().ui())
.subscribe(new Consumer<List<QuestionCardData>>() {
@Override
public void accept(List<QuestionCardData> questionList) throws Exception {
if (questionList != null) {
getNavigator().refreshQuestionnaire(questionList);
if (mAction == NO_ACTION) {
getCompositeDisposable().add(getDataManager()
.getQuestionCardData()
.subscribeOn(getSchedulerProvider().io())
.observeOn(getSchedulerProvider().ui())
.subscribe(new Consumer<List<QuestionCardData>>() {
@Override
public void accept(List<QuestionCardData> questionList) throws Exception {
if (questionList != null) {
mAction = ACTION_ADD_ALL;
questionDataList.addAll(questionList);
}
}
}
}));
}));
} else {
ArrayList<QuestionCardData> arrayList = (ArrayList<QuestionCardData>)questionDataList.clone();
questionDataList.clear();
mAction = ACTION_ADD_ALL;
questionDataList.addAll(arrayList);
}
}
public void onCardExhausted() {
......@@ -92,7 +106,9 @@ public class MainViewModel extends BaseViewModel<MainNavigator> {
@Override
public void accept(List<QuestionCardData> questionList) throws Exception {
if (questionList != null) {
getNavigator().reloadQuestionnaire(questionList);
mAction = ACTION_ADD_ALL;
questionDataList.clear();
questionDataList.addAll(questionList);
}
}
}));
......@@ -119,4 +135,8 @@ public class MainViewModel extends BaseViewModel<MainNavigator> {
}));
}
public void removeQuestionCard() {
mAction = ACTION_DELETE_SINGLE;
questionDataList.remove(0);
}
}
......@@ -57,6 +57,7 @@ public class QuestionCard {
private QuestionCardData mQuestionCardData;
public QuestionCard(QuestionCardData questionCardData) {
mQuestionCardData = questionCardData;
}
......@@ -65,6 +66,9 @@ public class QuestionCard {
private void onResolved() {
mQuestionTextView.setText(mQuestionCardData.question.questionText);
if (mQuestionCardData.mShowCorrectOptions) {
showCorrectOptions();
}
for (int i = 0; i < 3; i++) {
Button button = null;
......@@ -90,6 +94,7 @@ public class QuestionCard {
}
private void showCorrectOptions() {
mQuestionCardData.mShowCorrectOptions = true;
for (int i = 0; i < 3; i++) {
Option option = mQuestionCardData.options.get(i);
Button button = null;
......
......@@ -75,7 +75,6 @@ public class RateUsDialog extends BaseDialog implements RateUsCallback {
@Override
public void onDestroyView() {
mRateUsViewModel.onDestroy();
super.onDestroyView();
}
......
......@@ -29,9 +29,8 @@ import io.reactivex.disposables.CompositeDisposable;
public class RateUsViewModel extends BaseViewModel<RateUsCallback> {
public RateUsViewModel(DataManager dataManager,
SchedulerProvider schedulerProvider,
CompositeDisposable compositeDisposable) {
super(dataManager, schedulerProvider, compositeDisposable);
SchedulerProvider schedulerProvider) {
super(dataManager, schedulerProvider);
}
public void onLaterClick() {
......
......@@ -53,7 +53,6 @@ public class SplashActivity extends BaseActivity<ActivitySplashBinding, SplashVi
@Override
protected void onDestroy() {
super.onDestroy();
mSplashViewModel.onDestroy();
}
@Override
......
......@@ -32,9 +32,8 @@ import io.reactivex.functions.Function;
public class SplashViewModel extends BaseViewModel<SplashNavigator> {
public SplashViewModel(DataManager dataManager,
SchedulerProvider schedulerProvider,
CompositeDisposable compositeDisposable) {
super(dataManager, schedulerProvider, compositeDisposable);
SchedulerProvider schedulerProvider) {
super(dataManager, schedulerProvider);
}
......
package com.mindorks.framework.mvvm.utils;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.ScaleAnimation;
/**
* Created by RV on 06/09/17.
*/
public final class ViewAnimationUtils {
private ViewAnimationUtils() {
// This class is not publicly instantiable
}
public static void scaleAnimateView(View view) {
ScaleAnimation animation =
new ScaleAnimation(
1.15f, 1, 1.15f, 1,
Animation.RELATIVE_TO_SELF, 0.5f,
Animation.RELATIVE_TO_SELF, 0.5f);
view.setAnimation(animation);
animation.setDuration(100);
animation.start();
}
}
......@@ -75,7 +75,9 @@
<com.mindorks.placeholderview.SwipePlaceHolderView
android:id="@+id/cardsContainer"
android:layout_width="match_parent"
android:layout_height="match_parent" />
android:layout_height="match_parent"
app:adapter="@{viewModel.questionDataList}"
app:action="@{viewModel.mAction}"/>
</LinearLayout>
</android.support.design.widget.CoordinatorLayout>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册