diff --git a/java/src/com/android/inputmethod/dictionarypack/DictionaryListInterfaceState.java b/java/src/com/android/inputmethod/dictionarypack/DictionaryListInterfaceState.java
index cbf0476a31fa0c7459134624453672cc88b90a21..8975d69a8313c64694a32a09754a914f21cac648 100644
--- a/java/src/com/android/inputmethod/dictionarypack/DictionaryListInterfaceState.java
+++ b/java/src/com/android/inputmethod/dictionarypack/DictionaryListInterfaceState.java
@@ -16,9 +16,46 @@
 
 package com.android.inputmethod.dictionarypack;
 
+import com.android.inputmethod.latin.CollectionUtils;
+
+import java.util.HashMap;
+
 /**
  * Helper class to maintain the interface state of word list preferences.
+ *
+ * This is necessary because the views are created on-demand by calling code. There are many
+ * situations where views are renewed with little relation with user interaction. For example,
+ * when scrolling, the view is reused so it doesn't keep its state, which means we need to keep
+ * it separately. Also whenever the underlying dictionary list undergoes a change (for example,
+ * update the metadata, or finish downloading) the whole list has to be thrown out and recreated
+ * in case some dictionaries appeared, disappeared, changed states etc.
  */
 public class DictionaryListInterfaceState {
-    public String mLastClickedId = null;
+    private static class State {
+        public boolean mOpen = false;
+        public int mStatus = MetadataDbHelper.STATUS_UNKNOWN;
+    }
+
+    private HashMap<String, State> mWordlistToState = CollectionUtils.newHashMap();
+
+    public boolean isOpen(final String wordlistId) {
+        final State state = mWordlistToState.get(wordlistId);
+        if (null == state) return false;
+        return state.mOpen;
+    }
+
+    public void setOpen(final String wordlistId, final int status) {
+        final State newState;
+        final State state = mWordlistToState.get(wordlistId);
+        newState = null == state ? new State() : state;
+        newState.mOpen = true;
+        newState.mStatus = status;
+        mWordlistToState.put(wordlistId, newState);
+    }
+
+    public void closeAll() {
+        for (final State state : mWordlistToState.values()) {
+            state.mOpen = false;
+        }
+    }
 }
diff --git a/java/src/com/android/inputmethod/dictionarypack/WordListPreference.java b/java/src/com/android/inputmethod/dictionarypack/WordListPreference.java
index 32825ba7ff6db0126d0702f3268411f013adcf8f..6d302daa218b7a3af87750aeeab3d86933f6cfd5 100644
--- a/java/src/com/android/inputmethod/dictionarypack/WordListPreference.java
+++ b/java/src/com/android/inputmethod/dictionarypack/WordListPreference.java
@@ -194,9 +194,7 @@ public final class WordListPreference extends Preference {
         ((ViewGroup)view).setLayoutTransition(null);
         final Button button = (Button)view.findViewById(R.id.wordlist_button);
         button.setText(getButtonLabel(mStatus));
-        // String identity match. This is an ==, not an .equals, on purpose.
-        button.setVisibility(mWordlistId == mInterfaceState.mLastClickedId
-                ? View.VISIBLE : View.INVISIBLE);
+        button.setVisibility(mInterfaceState.isOpen(mWordlistId) ? View.VISIBLE : View.INVISIBLE);
         button.setOnClickListener(mActionButtonClickHandler);
         view.setOnClickListener(mPreferenceClickHandler);
     }
@@ -210,15 +208,16 @@ public final class WordListPreference extends Preference {
             if (!(parent instanceof ListView)) return;
             final ListView listView = (ListView)parent;
             final int indexToOpen;
-            if (mInterfaceState.mLastClickedId == mWordlistId) {
-                // This button was being shown. Clear last state to record that there isn't a
-                // displayed button any more, and note that we don't want to open any button.
-                mInterfaceState.mLastClickedId = null;
+            // Close all first, we'll open back any item that needs to be open.
+            mInterfaceState.closeAll();
+            if (mInterfaceState.isOpen(mWordlistId)) {
+                // This button being shown. Take note that we don't want to open any button in the
+                // loop below.
                 indexToOpen = -1;
             } else {
-                // This button was not being shown. Mark it as the latest selected button, and
-                // remember the index of this child as the one to open in the following loop.
-                mInterfaceState.mLastClickedId = mWordlistId;
+                // This button was not being shown. Open it, and remember the index of this
+                // child as the one to open in the following loop.
+                mInterfaceState.setOpen(mWordlistId, mStatus);
                 indexToOpen = listView.indexOfChild(v);
             }
             final int lastDisplayedIndex =