title: How Best To Implement ViewModel( in AndroidX) So Data Survives Configuration Changes
body: <p>I am trying to implement a ViewModel architecture for a RecyclerView in AndroidX, following the example as stated in <a href="https://developer.android.com/topic/libraries/architecture/viewmodel" rel="nofollow noreferrer">enter link description here</a> and <a href="https://developer.android.com/jetpack/androidx/releases/lifecycle#declaring_dependencies" rel="nofollow noreferrer">enter link description here</a>. Items in the recyclerView get selected on position clicked, but for some reason, the selected item de-select and revert to default after the device is rotated and configuration changed. I know there have been answers for questions like this in the past, but all I have seen are either not directly applicable in my case or are simply for deprecated cases.</p>
  <p>CAN SOMEONE PLEASE TELL ME WHAT I AM DOING WRONG!</p>
  <p>Below are snippets from my Code:</p>
  <p>Dependencies added</p>
  <pre><code>dependencies {
  
  def lifecycle_version = &quot;2.2.0&quot;
  
  // ViewModel
  implementation &quot;androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version&quot;
  
  // LiveData
  implementation &quot;androidx.lifecycle:lifecycle-livedata:$lifecycle_version&quot;
  
  // Saved state module for ViewModel
  implementation &quot;androidx.lifecycle:lifecycle-viewmodel-savedstate:$lifecycle_version&quot;
  
  // Annotation processor
  annotationProcessor &quot;androidx.lifecycle:lifecycle-compiler:$lifecycle_version&quot;
  
  implementation 'androidx.hilt:hilt-lifecycle-viewmodel:1.0.0-alpha02'
  </code></pre>
  <p>}</p>
  <p>Repository Class:
  public class TopicRepository {</p>
  <pre><code>private Application application;
  private SharedPreferences sharedPreferences;
  private ArrayList&lt;RootTopic&gt; topicGroupList;
  private MutableLiveData&lt;ArrayList&lt;RootTopic&gt;&gt;topicGroupMLD;
  
  public TopicRepository(Application application) {
      this.application = application;
      
  }
  
  public LiveData&lt;ArrayList&lt;RootTopic&gt;&gt; getRootTopicLD(String subject){
      if (topicGroupMLD == null){
          topicGroupMLD = new MutableLiveData&lt;ArrayList&lt;RootTopic&gt;&gt;();
          generateTopicGroup(subject);
      }
          return topicGroupMLD;
  }
  
  private void generateTopicGroup(final String subject){
      Log.d(TAG, &quot;generateTopicGroup: CALLED&quot;);
      isRequestingMLD.postValue(true);
      final String subjectTopicGroupList = subject + &quot;TopicGroupList&quot;;
  
      sharedPreferences = application.getSharedPreferences(AppConstant.Constants.PACKAGE_NAME, Context.MODE_PRIVATE);
      String serializedTopicGroup = sharedPreferences.getString(subjectTopicGroupList, null);
       if (serializedTopicGroup != null){
  
           Gson gson = new Gson();
           Type type = new TypeToken&lt;ArrayList&lt;RootTopic&gt;&gt;(){}.getType();
           topicGroupList = gson.fromJson(serializedTopicGroup, type);
           topicGroupMLD.postValue(topicGroupList);
  
       }else {//       - Not saved in SP
  
           Log.d(TAG, &quot;getTopicGroup: NOT IN SP&quot;);
           new ActiveConnectionCheck(new ActiveConnectionCheck.Consumer() {
               @Override
               public void accept(Boolean internet) {
                   Log.d(TAG, &quot;accept: CHECKED INTERNET&quot;);
                   if (internet){
                       Log.d(TAG, &quot;accept: INTERNET CONNECTION = TRUE&quot;);
                       internetCheckMLD.postValue(AppConstant.Constants.IS_INTERNET_REQUEST_SUCCESS);
  
                       FirebaseFirestore fbFStore = FirebaseFirestore.getInstance();
                       CollectionReference lectureRef = fbFStore.collection(subject);
                       lectureRef.orderBy(AppConstant.Constants.POSITION, Query.Direction.ASCENDING)
                               .get().addOnSuccessListener(
                               new OnSuccessListener&lt;QuerySnapshot&gt;() {
                                   @Override
                                   public void onSuccess(QuerySnapshot queryDocumentSnapshots) {
  
                                       ArrayList&lt;Topic&gt;topicList = new ArrayList&lt;&gt;();
                                       ArrayList&lt;String&gt; rootTitleList = new ArrayList&lt;&gt;();
  
                                       for (QueryDocumentSnapshot snapshot : queryDocumentSnapshots){
                                           Topic topic = snapshot.toObject(Topic.class);
                                           topicList.add(topic);
                                       }
  
                                       Log.d(TAG, &quot;onSuccess: TopicListSize = &quot; + topicList.size());
  
                                       for (Topic topic : topicList){
                                           String rootTopicString = topic.getRootTopic();
                                           if (!rootTitleList.contains(rootTopicString)){
                                               rootTitleList.add(rootTopicString);
                                           }
                                       }
  
                                       Log.d(TAG, &quot;onSuccess: RootTitleListSize = &quot; + rootTitleList.size());
  
                                      for (int x = 0; x &lt; rootTitleList.size(); x ++){
                                          RootTopic rootTopic = new RootTopic(rootTitleList.get(x), new ArrayList&lt;Topic&gt;());
                                          topicGroupList = new ArrayList&lt;&gt;();
                                          topicGroupList.add(rootTopic);
                                      }
  
                                       for (int e = 0; e &lt; topicList.size(); e++){
                                           addTopicToGroup(topicGroupList, topicList.get(e));
                                       }
  
                                       topicGroupMLD.postValue(topicGroupList);
                                       Gson gson = new Gson();
                                       String serializedTopicGroup = gson.toJson(topicGroupList);
                                       sharedPreferences.edit().putString(subjectTopicGroupList, serializedTopicGroup).apply();
  
                                       Log.d(TAG, &quot;onSuccess: TOPICGROUPSIZE = &quot; + topicGroupList.size());
                                       Log.d(TAG, &quot;onSuccess: SERIALIZED GROUP = &quot; + serializedTopicGroup);
                                       isRequestingMLD.postValue(false);
  
                                   }
                               }
                       ).addOnFailureListener(
                               new OnFailureListener() {
                                   @Override
                                   public void onFailure(@NonNull Exception e) {
                                       isRequestingMLD.postValue(false);
                                       Log.d(TAG, &quot;onFailure: FAILED TO GET TOPICLIST e = &quot; + e.toString());
                                   }
                               }
                       );
  
                   }else {
                       internetCheckMLD.postValue(AppConstant.Constants.IS_INTERNET_REQUEST_FAIL);
                       Log.d(TAG, &quot;accept: InternetCONECTION = &quot; + false);
                   }
               }
           });
  
       }
  
  }
  
  private void addTopicToGroup(ArrayList&lt;RootTopic&gt;rootGroup, Topic topic){
      for (int x = 0; x &lt; rootGroup.size(); x++){
          RootTopic rootTopic = rootGroup.get(x);
          if (rootTopic.getRootTopicName().equals(topic.getRootTopic())){
              rootTopic.getTopicGroup().add(topic);
          }
      }
  }
  </code></pre>
  <p>}</p>
  <p>My ViewModel class</p>
  <pre><code>public class LectureViewModel extends AndroidViewModel {
  
  public static final String TAG = AppConstant.Constants.GEN_TAG + &quot;:LectureVM&quot;;
  
  private Application application;
  private TopicRepository topicRepository;
  private ArrayList&lt;RootTopic&gt; topicGroupList;
  
  
  public LectureViewModel(@NonNull Application application) {
      super(application);
      this.application = application;
      topicRepository = new TopicRepository(application);
     
  }
  
  
  public LiveData&lt;ArrayList&lt;RootTopic&gt;&gt; getRootTopicListLD(String subject){
  
      return topicRepository.getRootTopicLD(subject);
  }
  </code></pre>
  <p>}</p>
  <p>Activity Implementing ViewModel</p>
  <pre><code>public class LectureRoomActivity extends AppCompatActivity {
  
  public static final String TAG = AppConstant.Constants.GEN_TAG + &quot; LecRoom&quot;;
  private LectureViewModel lectureRoomVM;
  private String subject;
  private RecyclerView mainRecyclerView;
  
  private RootTopicAdapter rootTopicAdapter;
  
  
  @Override
  protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_lecture_room);
  
      Intent intent = getIntent();
      subject = intent.getStringExtra(AppConstant.Constants.SUBJECT);
  
      mainRecyclerView = findViewById(R.id.recyclerView);
      
      downloadVM = new ViewModelProvider(this).get(DownloadLectureViewModel.class);
      lectureRoomVM = new ViewModelProvider(this).get(LectureViewModel.class);
      lectureRoomVM.getRootTopicListLD(subject).observe(
              this,
              new Observer&lt;ArrayList&lt;RootTopic&gt;&gt;() {
          @Override
          public void onChanged(ArrayList&lt;RootTopic&gt; rootTopics) {
              if (rootTopics != null){
                  currentTopic = lectureRoomVM.getCursorTopic(subject, rootTopics);
                  setUpRec(rootTopics, currentTopic);
              }
          }
      });
  
  }
  
  
  private void setUpRec( ArrayList&lt;RootTopic&gt;topicGroup, CursorTopic currentTopic){
       rootTopicAdapter = new RootTopicAdapter(topicGroup,
              new ArrayList&lt;String&gt;(), currentTopic.getParentPosition(),
              currentTopic.getCursorPosition());
  
      LinearLayoutManager linearLayoutManager = new LinearLayoutManager(
              this, RecyclerView.VERTICAL,false);
  
      mainRecyclerView.setHasFixedSize(true);
      mainRecyclerView.setLayoutManager(linearLayoutManager);
      mainRecyclerView.setAdapter(rootTopicAdapter);
  
      Log.d(TAG, &quot;setUpRec: SETTING REC&quot;);
  }
  </code></pre>
  <p>}</p>