diff --git a/java/src/com/android/inputmethod/dictionarypack/DictionaryListInterfaceState.java b/java/src/com/android/inputmethod/dictionarypack/DictionaryListInterfaceState.java index cbf0476a3..8975d69a8 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 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 32825ba7f..6d302daa2 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 =