diff options
Diffstat (limited to 'java/src/com/android/inputmethod/dictionarypack')
6 files changed, 79 insertions, 46 deletions
diff --git a/java/src/com/android/inputmethod/dictionarypack/ButtonSwitcher.java b/java/src/com/android/inputmethod/dictionarypack/ButtonSwitcher.java index 5ab94a429..c5aca174a 100644 --- a/java/src/com/android/inputmethod/dictionarypack/ButtonSwitcher.java +++ b/java/src/com/android/inputmethod/dictionarypack/ButtonSwitcher.java @@ -57,6 +57,11 @@ public class ButtonSwitcher extends FrameLayout { super(context, attrs, defStyle); } + public void reset() { + mStatus = NOT_INITIALIZED; + mAnimateToStatus = NOT_INITIALIZED; + } + @Override protected void onLayout(final boolean changed, final int left, final int top, final int right, final int bottom) { @@ -64,9 +69,7 @@ public class ButtonSwitcher extends FrameLayout { mInstallButton = (Button)findViewById(R.id.dict_install_button); mCancelButton = (Button)findViewById(R.id.dict_cancel_button); mDeleteButton = (Button)findViewById(R.id.dict_delete_button); - mInstallButton.setOnClickListener(mOnClickListener); - mCancelButton.setOnClickListener(mOnClickListener); - mDeleteButton.setOnClickListener(mOnClickListener); + setInternalOnClickListener(mOnClickListener); setButtonPositionWithoutAnimation(mStatus); if (mAnimateToStatus != NOT_INITIALIZED) { // We have been asked to animate before we were ready, so we took a note of it. @@ -139,6 +142,12 @@ public class ButtonSwitcher extends FrameLayout { public void setInternalOnClickListener(final OnClickListener listener) { mOnClickListener = listener; + if (null != mInstallButton) { + // Already laid out : do it now + mInstallButton.setOnClickListener(mOnClickListener); + mCancelButton.setOnClickListener(mOnClickListener); + mDeleteButton.setOnClickListener(mOnClickListener); + } } private ViewPropertyAnimator animateButton(final View button, final int direction) { diff --git a/java/src/com/android/inputmethod/dictionarypack/DictionaryListInterfaceState.java b/java/src/com/android/inputmethod/dictionarypack/DictionaryListInterfaceState.java index de3711c27..5ad5900d4 100644 --- a/java/src/com/android/inputmethod/dictionarypack/DictionaryListInterfaceState.java +++ b/java/src/com/android/inputmethod/dictionarypack/DictionaryListInterfaceState.java @@ -16,8 +16,11 @@ package com.android.inputmethod.dictionarypack; +import android.view.View; + import com.android.inputmethod.latin.CollectionUtils; +import java.util.ArrayList; import java.util.HashMap; /** @@ -37,6 +40,7 @@ public class DictionaryListInterfaceState { } private HashMap<String, State> mWordlistToState = CollectionUtils.newHashMap(); + private ArrayList<View> mViewCache = CollectionUtils.newArrayList(); public boolean isOpen(final String wordlistId) { final State state = mWordlistToState.get(wordlistId); @@ -64,4 +68,16 @@ public class DictionaryListInterfaceState { state.mOpen = false; } } + + public View findFirstOrphanedView() { + for (final View v : mViewCache) { + if (null == v.getParent()) return v; + } + return null; + } + + public View addToCacheAndReturnView(final View view) { + mViewCache.add(view); + return view; + } } diff --git a/java/src/com/android/inputmethod/dictionarypack/DictionarySettingsFragment.java b/java/src/com/android/inputmethod/dictionarypack/DictionarySettingsFragment.java index 618322357..4b89d20bb 100644 --- a/java/src/com/android/inputmethod/dictionarypack/DictionarySettingsFragment.java +++ b/java/src/com/android/inputmethod/dictionarypack/DictionarySettingsFragment.java @@ -222,7 +222,9 @@ public final class DictionarySettingsFragment extends PreferenceFragment refreshNetworkState(); removeAnyDictSettings(prefScreen); + int i = 0; for (Preference preference : prefList) { + preference.setOrder(i++); prefScreen.addPreference(preference); } } @@ -302,7 +304,7 @@ public final class DictionarySettingsFragment extends PreferenceFragment // the description. final String key = matchLevelString + "." + description + "." + wordlistId; final WordListPreference existingPref = prefMap.get(key); - if (null == existingPref || hasPriority(status, existingPref.mStatus)) { + if (null == existingPref || existingPref.hasPriorityOver(status)) { final WordListPreference oldPreference = mCurrentPreferenceMap.get(key); final WordListPreference pref; if (null != oldPreference @@ -313,7 +315,7 @@ public final class DictionarySettingsFragment extends PreferenceFragment // need to be the same, others have been tested through the key of the // map. Also, status may differ so we don't want to use #equals() here. pref = oldPreference; - pref.mStatus = status; + pref.setStatus(status); } else { // Otherwise, discard it and create a new one instead. pref = new WordListPreference(activity, mDictionaryListInterfaceState, @@ -329,18 +331,6 @@ public final class DictionarySettingsFragment extends PreferenceFragment } } - /** - * Finds out if a given status has priority over another for display order. - * - * @param newStatus - * @param oldStatus - * @return whether newStatus has priority over oldStatus. - */ - private static boolean hasPriority(final int newStatus, final int oldStatus) { - // Both of these should be one of MetadataDbHelper.STATUS_* - return newStatus > oldStatus; - } - @Override public boolean onOptionsItemSelected(final MenuItem item) { switch (item.getItemId()) { diff --git a/java/src/com/android/inputmethod/dictionarypack/LocaleUtils.java b/java/src/com/android/inputmethod/dictionarypack/LocaleUtils.java index d0e8446f5..77f67b8a3 100644 --- a/java/src/com/android/inputmethod/dictionarypack/LocaleUtils.java +++ b/java/src/com/android/inputmethod/dictionarypack/LocaleUtils.java @@ -144,7 +144,7 @@ public final class LocaleUtils { public static String getMatchLevelSortedString(final int matchLevel) { // This works because the match levels are 0~99 (actually 0~30) // Ideally this should use a number of digits equals to the 1og10 of the greater matchLevel - return String.format("%02d", MATCH_LEVEL_MAX - matchLevel); + return String.format(Locale.ROOT, "%02d", MATCH_LEVEL_MAX - matchLevel); } /** diff --git a/java/src/com/android/inputmethod/dictionarypack/MetadataDbHelper.java b/java/src/com/android/inputmethod/dictionarypack/MetadataDbHelper.java index 03ed267c3..dac12137d 100644 --- a/java/src/com/android/inputmethod/dictionarypack/MetadataDbHelper.java +++ b/java/src/com/android/inputmethod/dictionarypack/MetadataDbHelper.java @@ -36,8 +36,6 @@ import java.util.TreeMap; * Various helper functions for the state database */ public class MetadataDbHelper extends SQLiteOpenHelper { - - @SuppressWarnings("unused") private static final String TAG = MetadataDbHelper.class.getSimpleName(); // This was the initial release version of the database. It should never be @@ -437,37 +435,37 @@ public class MetadataDbHelper extends SQLiteOpenHelper { */ public static ContentValues completeWithDefaultValues(final ContentValues result) throws BadFormatException { - if (!result.containsKey(WORDLISTID_COLUMN) || !result.containsKey(LOCALE_COLUMN)) { + if (null == result.get(WORDLISTID_COLUMN) || null == result.get(LOCALE_COLUMN)) { throw new BadFormatException(); } // 0 for the pending id, because there is none - if (!result.containsKey(PENDINGID_COLUMN)) result.put(PENDINGID_COLUMN, 0); + if (null == result.get(PENDINGID_COLUMN)) result.put(PENDINGID_COLUMN, 0); // This is a binary blob of a dictionary - if (!result.containsKey(TYPE_COLUMN)) result.put(TYPE_COLUMN, TYPE_BULK); + if (null == result.get(TYPE_COLUMN)) result.put(TYPE_COLUMN, TYPE_BULK); // This word list is unknown, but it's present, else we wouldn't be here, so INSTALLED - if (!result.containsKey(STATUS_COLUMN)) result.put(STATUS_COLUMN, STATUS_INSTALLED); + if (null == result.get(STATUS_COLUMN)) result.put(STATUS_COLUMN, STATUS_INSTALLED); // No description unless specified, because we can't guess it - if (!result.containsKey(DESCRIPTION_COLUMN)) result.put(DESCRIPTION_COLUMN, ""); + if (null == result.get(DESCRIPTION_COLUMN)) result.put(DESCRIPTION_COLUMN, ""); // File name - this is an asset, so it works as an already deleted file. // hence, we need to supply a non-existent file name. Anything will // do as long as it returns false when tested with File#exist(), and // the empty string does not, so it's set to "_". - if (!result.containsKey(LOCAL_FILENAME_COLUMN)) result.put(LOCAL_FILENAME_COLUMN, "_"); + if (null == result.get(LOCAL_FILENAME_COLUMN)) result.put(LOCAL_FILENAME_COLUMN, "_"); // No remote file name : this can't be downloaded. Unless specified. - if (!result.containsKey(REMOTE_FILENAME_COLUMN)) result.put(REMOTE_FILENAME_COLUMN, ""); + if (null == result.get(REMOTE_FILENAME_COLUMN)) result.put(REMOTE_FILENAME_COLUMN, ""); // 0 for the update date : 1970/1/1. Unless specified. - if (!result.containsKey(DATE_COLUMN)) result.put(DATE_COLUMN, 0); + if (null == result.get(DATE_COLUMN)) result.put(DATE_COLUMN, 0); // Checksum unknown unless specified - if (!result.containsKey(CHECKSUM_COLUMN)) result.put(CHECKSUM_COLUMN, ""); + if (null == result.get(CHECKSUM_COLUMN)) result.put(CHECKSUM_COLUMN, ""); // No filesize unless specified - if (!result.containsKey(FILESIZE_COLUMN)) result.put(FILESIZE_COLUMN, 0); + if (null == result.get(FILESIZE_COLUMN)) result.put(FILESIZE_COLUMN, 0); // Smallest possible version unless specified - if (!result.containsKey(VERSION_COLUMN)) result.put(VERSION_COLUMN, 1); + if (null == result.get(VERSION_COLUMN)) result.put(VERSION_COLUMN, 1); // Assume current format unless specified - if (!result.containsKey(FORMATVERSION_COLUMN)) + if (null == result.get(FORMATVERSION_COLUMN)) result.put(FORMATVERSION_COLUMN, UpdateHandler.MAXIMUM_SUPPORTED_FORMAT_VERSION); // No flags unless specified - if (!result.containsKey(FLAGS_COLUMN)) result.put(FLAGS_COLUMN, 0); + if (null == result.get(FLAGS_COLUMN)) result.put(FLAGS_COLUMN, 0); return result; } @@ -572,7 +570,8 @@ public class MetadataDbHelper extends SQLiteOpenHelper { * If several clients use the same metadata URL, we know to only download it once, and * dispatch the update process across all relevant clients when the download ends. This means * several clients may share a single download ID if they share a metadata URI. - * The dispatching is done in {@link UpdateHandler#downloadFinished(Context, Intent)}, which + * The dispatching is done in + * {@link UpdateHandler#downloadFinished(Context, android.content.Intent)}, which * finds out about the list of relevant clients by calling this method. * * @param context a context instance to open the databases @@ -863,17 +862,20 @@ public class MetadataDbHelper extends SQLiteOpenHelper { r.getAsString(WORDLISTID_COLUMN), Integer.toString(STATUS_INSTALLED) }, null, null, null); - if (c.moveToFirst()) { - // There should never be more than one file, but if there are, it's a bug - // and we should remove them all. I think it might happen if the power of the - // phone is suddenly cut during an update. - final int filenameIndex = c.getColumnIndex(LOCAL_FILENAME_COLUMN); - do { - Utils.l("Setting for removal", c.getString(filenameIndex)); - filenames.add(c.getString(filenameIndex)); - } while (c.moveToNext()); + try { + if (c.moveToFirst()) { + // There should never be more than one file, but if there are, it's a bug + // and we should remove them all. I think it might happen if the power of + // the phone is suddenly cut during an update. + final int filenameIndex = c.getColumnIndex(LOCAL_FILENAME_COLUMN); + do { + Utils.l("Setting for removal", c.getString(filenameIndex)); + filenames.add(c.getString(filenameIndex)); + } while (c.moveToNext()); + } + } finally { + c.close(); } - r.put(STATUS_COLUMN, STATUS_INSTALLED); db.beginTransactionNonExclusive(); // Delete all old entries. There should never be any stalled entries, but if diff --git a/java/src/com/android/inputmethod/dictionarypack/WordListPreference.java b/java/src/com/android/inputmethod/dictionarypack/WordListPreference.java index 451a0fb82..7ec7e9c13 100644 --- a/java/src/com/android/inputmethod/dictionarypack/WordListPreference.java +++ b/java/src/com/android/inputmethod/dictionarypack/WordListPreference.java @@ -61,7 +61,7 @@ public final class WordListPreference extends Preference { public final Locale mLocale; public final String mDescription; // The status - public int mStatus; + private int mStatus; // The size of the dictionary file private final int mFilesize; @@ -92,12 +92,25 @@ public final class WordListPreference extends Preference { setKey(wordlistId); } - private void setStatus(final int status) { + public void setStatus(final int status) { if (status == mStatus) return; mStatus = status; setSummary(getSummary(status)); } + @Override + public View onCreateView(final ViewGroup parent) { + final View orphanedView = mInterfaceState.findFirstOrphanedView(); + if (null != orphanedView) return orphanedView; // Will be sent to onBindView + final View newView = super.onCreateView(parent); + return mInterfaceState.addToCacheAndReturnView(newView); + } + + public boolean hasPriorityOver(final int otherPrefStatus) { + // Both of these should be one of MetadataDbHelper.STATUS_* + return mStatus > otherPrefStatus; + } + private String getSummary(final int status) { switch (status) { // If we are deleting the word list, for the user it's like it's already deleted. @@ -209,6 +222,9 @@ public final class WordListPreference extends Preference { final ButtonSwitcher buttonSwitcher = (ButtonSwitcher)view.findViewById(R.id.wordlist_button_switcher); + // We need to clear the state of the button switcher, because we reuse views; if we didn't + // reset it would animate from whatever its old state was. + buttonSwitcher.reset(); if (mInterfaceState.isOpen(mWordlistId)) { // The button is open. final int previousStatus = mInterfaceState.getStatus(mWordlistId); |