Fix a bug which causes the ViewModel not retain its state after orientation change.

This commit is contained in:
Alex Ning 2021-09-05 11:11:01 +08:00
parent 6dc0521e8e
commit 38caf7365a
5 changed files with 37 additions and 50 deletions

View File

@ -51,6 +51,8 @@ dependencies {
def lifecycleVersion = "2.2.0" def lifecycleVersion = "2.2.0"
implementation "androidx.lifecycle:lifecycle-livedata:$lifecycleVersion" implementation "androidx.lifecycle:lifecycle-livedata:$lifecycleVersion"
implementation "androidx.lifecycle:lifecycle-viewmodel:$lifecycleVersion" implementation "androidx.lifecycle:lifecycle-viewmodel:$lifecycleVersion"
implementation "androidx.lifecycle:lifecycle-runtime:$lifecycleVersion"
implementation "androidx.lifecycle:lifecycle-runtime-ktx:$lifecycleVersion"
implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycleVersion" implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycleVersion"
annotationProcessor "androidx.lifecycle:lifecycle-common-java8:$lifecycleVersion" annotationProcessor "androidx.lifecycle:lifecycle-common-java8:$lifecycleVersion"
implementation 'androidx.paging:paging-runtime:3.0.1' implementation 'androidx.paging:paging-runtime:3.0.1'

View File

@ -75,6 +75,7 @@ public class Paging3TestActivity extends BaseActivity {
@Inject @Inject
Executor mExecutor; Executor mExecutor;
public PostPaging3ViewModel viewModel; public PostPaging3ViewModel viewModel;
private Paging3TestAdapter adapter;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
@ -103,7 +104,7 @@ public class Paging3TestActivity extends BaseActivity {
} }
RecyclerView recyclerView = findViewById(R.id.recycler_view); RecyclerView recyclerView = findViewById(R.id.recycler_view);
Paging3TestAdapter adapter = new Paging3TestAdapter(this, new PostFragment(), mExecutor, adapter = new Paging3TestAdapter(this, new PostFragment(), mExecutor,
mOauthRetrofit, mGfycatRetrofit, mOauthRetrofit, mGfycatRetrofit,
mRedgifsRetrofit, mCustomThemeWrapper, locale, mRedgifsRetrofit, mCustomThemeWrapper, locale,
windowWidth, accessToken, accountName, postType, postLayout, true, windowWidth, accessToken, accountName, postType, postLayout, true,
@ -141,12 +142,14 @@ public class Paging3TestActivity extends BaseActivity {
}); });
recyclerView.setAdapter(adapter); recyclerView.setAdapter(adapter);
viewModel = new ViewModelProvider(this, new PostPaging3ViewModel.Factory(mExecutor, mPaging3Retrofit, viewModel = new ViewModelProvider(this, new PostPaging3ViewModel.Factory(getLifecycle(), mExecutor, mPaging3Retrofit,
accessToken, accountName, mSharedPreferences, mPostFeedScrolledPositionSharedPreferences, accessToken, accountName, mSharedPreferences, mPostFeedScrolledPositionSharedPreferences,
null, null, null, postType, sortType, null, null, null, null, null, postType, sortType, null, null,
null, null, null)).get(PostPaging3ViewModel.class); null, null, null)).get(PostPaging3ViewModel.class);
viewModel.getPosts().observe(this, postPagingData -> adapter.submitData(getLifecycle(), postPagingData)); viewModel.getPosts().observe(this, postPagingData -> {
adapter.submitData(getLifecycle(), postPagingData);
});
} }
@Override @Override

View File

@ -1,6 +1,7 @@
package ml.docilealligator.infinityforreddit.post; package ml.docilealligator.infinityforreddit.post;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.util.Log;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.lifecycle.MutableLiveData; import androidx.lifecycle.MutableLiveData;
@ -76,47 +77,10 @@ public class PostPaging3PagingSource extends ListenableFuturePagingSource<String
return null; return null;
} }
/*@Nullable
@Override
public Object load(@NonNull LoadParams<String> loadParams, @NonNull Continuation<? super LoadResult<String, Post>> continuation) {
RedditAPI api = retrofit.create(RedditAPI.class);
Call<String> bestPost;
if(sortType.getTime() != null) {
bestPost = api.getBestPosts(sortType.getType().value, sortType.getTime().value, loadParams.getKey(),
APIUtils.getOAuthHeader(accessToken));
} else {
bestPost = api.getBestPosts(sortType.getType().value, loadParams.getKey(), APIUtils.getOAuthHeader(accessToken));
}
try {
Response<String> response = bestPost.execute();
if (response.isSuccessful()) {
String responseString = response.body();
LinkedHashSet<Post> newPosts = ParsePost.parsePostsSync(responseString, -1, postFilter, readPostList);
String lastItem = ParsePost.getLastItem(responseString);
if (newPosts == null) {
return new LoadResult.Error<>(new Exception("Error parsing more posts"));
} else {
int currentPostsSize = postLinkedHashSet.size();
postLinkedHashSet.addAll(newPosts);
if (currentPostsSize == postLinkedHashSet.size()) {
return new LoadResult.Page<>(new ArrayList<>(), null, lastItem);
} else {
return new LoadResult.Page<>(new ArrayList<>(postLinkedHashSet).subList(currentPostsSize, postLinkedHashSet.size()), null, lastItem);
}
}
} else {
return new LoadResult.Error<>(new Exception("Response failed"));
}
} catch (IOException e) {
e.printStackTrace();
return new LoadResult.Error<>(e);
}
}*/
@NonNull @NonNull
@Override @Override
public ListenableFuture<LoadResult<String, Post>> loadFuture(@NonNull LoadParams<String> loadParams) { public ListenableFuture<LoadResult<String, Post>> loadFuture(@NonNull LoadParams<String> loadParams) {
Log.i("asfsaf", "s" + loadParams.getKey());
RedditAPI api = retrofit.create(RedditAPI.class); RedditAPI api = retrofit.create(RedditAPI.class);
ListenableFuture<Response<String>> bestPost; ListenableFuture<Response<String>> bestPost;
if(sortType.getTime() != null) { if(sortType.getTime() != null) {

View File

@ -34,6 +34,7 @@ public class PostPaging3Repository {
private String userWhere; private String userWhere;
private String multiRedditPath; private String multiRedditPath;
private LinkedHashSet<Post> postLinkedHashSet; private LinkedHashSet<Post> postLinkedHashSet;
private PostPaging3PagingSource paging3PagingSource;
public PostPaging3Repository(Executor executor, Retrofit retrofit, String accessToken, String accountName, public PostPaging3Repository(Executor executor, Retrofit retrofit, String accessToken, String accountName,
SharedPreferences sharedPreferences, SharedPreferences sharedPreferences,
@ -57,15 +58,16 @@ public class PostPaging3Repository {
this.userWhere = userWhere; this.userWhere = userWhere;
this.multiRedditPath = multiRedditPath; this.multiRedditPath = multiRedditPath;
this.postLinkedHashSet = postLinkedHashSet; this.postLinkedHashSet = postLinkedHashSet;
paging3PagingSource = new PostPaging3PagingSource(executor, retrofit, accessToken, accountName, sharedPreferences,
postFeedScrolledPositionSharedPreferences, postType, sortType, postFilter, readPostList);
} }
public LiveData<PagingData<Post>> getPostsLiveData() { public LiveData<PagingData<Post>> getPostsLiveData() {
return PagingLiveData.getLiveData(new Pager<>(new PagingConfig(25, 50, false), Pager<String, Post> pager = new Pager<>(new PagingConfig(25, 25, false), this::returnPagingSoruce);
this::returnPagingSoruce)); return PagingLiveData.getLiveData(pager);
} }
private PostPaging3PagingSource returnPagingSoruce() { public PostPaging3PagingSource returnPagingSoruce() {
return new PostPaging3PagingSource(executor, retrofit, accessToken, accountName, sharedPreferences, return paging3PagingSource;
postFeedScrolledPositionSharedPreferences, postType, sortType, postFilter, readPostList);
} }
} }

View File

@ -3,10 +3,13 @@ package ml.docilealligator.infinityforreddit.post;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LiveData; import androidx.lifecycle.LiveData;
import androidx.lifecycle.ViewModel; import androidx.lifecycle.ViewModel;
import androidx.lifecycle.ViewModelKt; import androidx.lifecycle.ViewModelKt;
import androidx.lifecycle.ViewModelProvider; import androidx.lifecycle.ViewModelProvider;
import androidx.paging.Pager;
import androidx.paging.PagingConfig;
import androidx.paging.PagingData; import androidx.paging.PagingData;
import androidx.paging.PagingLiveData; import androidx.paging.PagingLiveData;
@ -23,8 +26,10 @@ public class PostPaging3ViewModel extends ViewModel {
private PostPaging3Repository repository; private PostPaging3Repository repository;
private LiveData<PagingData<Post>> posts; private LiveData<PagingData<Post>> posts;
private PostPaging3PagingSource paging3PagingSource;
private Lifecycle lifecycle;
public PostPaging3ViewModel(Executor executor, Retrofit retrofit, String accessToken, String accountName, public PostPaging3ViewModel(Lifecycle lifecycle, Executor executor, Retrofit retrofit, String accessToken, String accountName,
SharedPreferences sharedPreferences, SharedPreferences sharedPreferences,
SharedPreferences postFeedScrolledPositionSharedPreferences, SharedPreferences postFeedScrolledPositionSharedPreferences,
String subredditOrUserName, String query, String trendingSource, int postType, String subredditOrUserName, String query, String trendingSource, int postType,
@ -32,14 +37,24 @@ public class PostPaging3ViewModel extends ViewModel {
String userWhere, String multiRedditPath, LinkedHashSet<Post> postLinkedHashSet) { String userWhere, String multiRedditPath, LinkedHashSet<Post> postLinkedHashSet) {
repository = new PostPaging3Repository(executor, retrofit, accessToken, accountName, sharedPreferences, postFeedScrolledPositionSharedPreferences, repository = new PostPaging3Repository(executor, retrofit, accessToken, accountName, sharedPreferences, postFeedScrolledPositionSharedPreferences,
subredditOrUserName, query, trendingSource, postType, sortType, postFilter, readPostList, userWhere, multiRedditPath, postLinkedHashSet); subredditOrUserName, query, trendingSource, postType, sortType, postFilter, readPostList, userWhere, multiRedditPath, postLinkedHashSet);
paging3PagingSource = repository.returnPagingSoruce();
Pager<String, Post> pager = new Pager<>(new PagingConfig(25, 25, false), this::returnPagingSoruce);
posts = PagingLiveData.cachedIn(PagingLiveData.getLiveData(pager), ViewModelKt.getViewModelScope(this));
} }
public LiveData<PagingData<Post>> getPosts() { public LiveData<PagingData<Post>> getPosts() {
posts = PagingLiveData.cachedIn(repository.getPostsLiveData(), ViewModelKt.getViewModelScope(this)); /*Pager<String, Post> pager = new Pager<>(new PagingConfig(25, 25, false), this::returnPagingSoruce);
posts = PagingLiveData.cachedIn(PagingLiveData.getLiveData(pager), ViewModelKt.getViewModelScope(this));
posts = PagingLiveData.cachedIn(PagingLiveData.getLiveData(pager), lifecycle);*/
return posts; return posts;
} }
private PostPaging3PagingSource returnPagingSoruce() {
return paging3PagingSource;
}
public static class Factory extends ViewModelProvider.NewInstanceFactory { public static class Factory extends ViewModelProvider.NewInstanceFactory {
private Lifecycle lifecycle;
private Executor executor; private Executor executor;
private Retrofit retrofit; private Retrofit retrofit;
private String accessToken; private String accessToken;
@ -57,11 +72,12 @@ public class PostPaging3ViewModel extends ViewModel {
private String multiRedditPath; private String multiRedditPath;
private LinkedHashSet<Post> postLinkedHashSet; private LinkedHashSet<Post> postLinkedHashSet;
public Factory(Executor executor, Retrofit retrofit, String accessToken, String accountName, SharedPreferences sharedPreferences, public Factory(Lifecycle lifecycle, Executor executor, Retrofit retrofit, String accessToken, String accountName, SharedPreferences sharedPreferences,
SharedPreferences postFeedScrolledPositionSharedPreferences, String subredditOrUserName, SharedPreferences postFeedScrolledPositionSharedPreferences, String subredditOrUserName,
String query, String trendingSource, int postType, SortType sortType, PostFilter postFilter, String query, String trendingSource, int postType, SortType sortType, PostFilter postFilter,
List<ReadPost> readPostList, String userWhere, String multiRedditPath, List<ReadPost> readPostList, String userWhere, String multiRedditPath,
LinkedHashSet<Post> postLinkedHashSet) { LinkedHashSet<Post> postLinkedHashSet) {
this.lifecycle = lifecycle;
this.executor = executor; this.executor = executor;
this.retrofit = retrofit; this.retrofit = retrofit;
this.accessToken = accessToken; this.accessToken = accessToken;
@ -83,7 +99,7 @@ public class PostPaging3ViewModel extends ViewModel {
@NonNull @NonNull
@Override @Override
public <T extends ViewModel> T create(@NonNull Class<T> modelClass) { public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
return (T) new PostPaging3ViewModel(executor, retrofit, accessToken, accountName, sharedPreferences, return (T) new PostPaging3ViewModel(lifecycle, executor, retrofit, accessToken, accountName, sharedPreferences,
postFeedScrolledPositionSharedPreferences, subredditOrUserName, query, trendingSource, postFeedScrolledPositionSharedPreferences, subredditOrUserName, query, trendingSource,
postType, sortType, postFilter, readPostList, userWhere, multiRedditPath, postLinkedHashSet); postType, sortType, postFilter, readPostList, userWhere, multiRedditPath, postLinkedHashSet);
} }