Rub some butter on dictionary list scrolling.

The default implementation for preferences refuses to
cache the views for custom preferences at all. We can
do it, but the system won't do it for us, so this does it.
This makes the screen scrolling smooth again.

Incidentally it also fixes the bug where the button may
not animate on the first element.

Bug: 8882722
Bug: 8883108
Change-Id: I9b2306ac4bf93761a808ebfee3477a65f017cddf
main
Jean Chalard 2013-05-28 20:28:52 +09:00
parent 305509ed2f
commit 2b34b4eab6
3 changed files with 39 additions and 3 deletions

View File

@ -57,6 +57,11 @@ public class ButtonSwitcher extends FrameLayout {
super(context, attrs, defStyle); super(context, attrs, defStyle);
} }
public void reset() {
mStatus = NOT_INITIALIZED;
mAnimateToStatus = NOT_INITIALIZED;
}
@Override @Override
protected void onLayout(final boolean changed, final int left, final int top, final int right, protected void onLayout(final boolean changed, final int left, final int top, final int right,
final int bottom) { final int bottom) {
@ -64,9 +69,7 @@ public class ButtonSwitcher extends FrameLayout {
mInstallButton = (Button)findViewById(R.id.dict_install_button); mInstallButton = (Button)findViewById(R.id.dict_install_button);
mCancelButton = (Button)findViewById(R.id.dict_cancel_button); mCancelButton = (Button)findViewById(R.id.dict_cancel_button);
mDeleteButton = (Button)findViewById(R.id.dict_delete_button); mDeleteButton = (Button)findViewById(R.id.dict_delete_button);
mInstallButton.setOnClickListener(mOnClickListener); setInternalOnClickListener(mOnClickListener);
mCancelButton.setOnClickListener(mOnClickListener);
mDeleteButton.setOnClickListener(mOnClickListener);
setButtonPositionWithoutAnimation(mStatus); setButtonPositionWithoutAnimation(mStatus);
if (mAnimateToStatus != NOT_INITIALIZED) { if (mAnimateToStatus != NOT_INITIALIZED) {
// We have been asked to animate before we were ready, so we took a note of it. // 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) { public void setInternalOnClickListener(final OnClickListener listener) {
mOnClickListener = 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) { private ViewPropertyAnimator animateButton(final View button, final int direction) {

View File

@ -16,8 +16,11 @@
package com.android.inputmethod.dictionarypack; package com.android.inputmethod.dictionarypack;
import android.view.View;
import com.android.inputmethod.latin.CollectionUtils; import com.android.inputmethod.latin.CollectionUtils;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
/** /**
@ -37,6 +40,7 @@ public class DictionaryListInterfaceState {
} }
private HashMap<String, State> mWordlistToState = CollectionUtils.newHashMap(); private HashMap<String, State> mWordlistToState = CollectionUtils.newHashMap();
private ArrayList<View> mViewCache = CollectionUtils.newArrayList();
public boolean isOpen(final String wordlistId) { public boolean isOpen(final String wordlistId) {
final State state = mWordlistToState.get(wordlistId); final State state = mWordlistToState.get(wordlistId);
@ -64,4 +68,16 @@ public class DictionaryListInterfaceState {
state.mOpen = false; 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;
}
} }

View File

@ -98,6 +98,14 @@ public final class WordListPreference extends Preference {
setSummary(getSummary(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);
}
private String getSummary(final int status) { private String getSummary(final int status) {
switch (status) { switch (status) {
// If we are deleting the word list, for the user it's like it's already deleted. // If we are deleting the word list, for the user it's like it's already deleted.
@ -209,6 +217,9 @@ public final class WordListPreference extends Preference {
final ButtonSwitcher buttonSwitcher = final ButtonSwitcher buttonSwitcher =
(ButtonSwitcher)view.findViewById(R.id.wordlist_button_switcher); (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)) { if (mInterfaceState.isOpen(mWordlistId)) {
// The button is open. // The button is open.
final int previousStatus = mInterfaceState.getStatus(mWordlistId); final int previousStatus = mInterfaceState.getStatus(mWordlistId);