Enable filtering <select> lists.
Fix a bug where the filter text could not be deleted,
and another where filtering changes the checked item,
so that filtering <select> lists can be reenabled.
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index a926355..563d819 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -21,6 +21,7 @@
import android.content.DialogInterface;
import android.content.Intent;
import android.content.DialogInterface.OnCancelListener;
+import android.database.DataSetObserver;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
@@ -60,6 +61,7 @@
import android.webkit.TextDialog.AutoCompleteAdapter;
import android.webkit.WebViewCore.EventHub;
import android.widget.AbsoluteLayout;
+import android.widget.Adapter;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.FrameLayout;
@@ -4809,7 +4811,10 @@
@Override
public boolean hasStableIds() {
- return true;
+ // AdapterView's onChanged method uses this to determine whether
+ // to restore the old state. Return false so that the old (out
+ // of date) state does not replace the new, valid state.
+ return false;
}
private Container item(int position) {
@@ -4873,6 +4878,51 @@
}
}
+ /*
+ * Whenever the data set changes due to filtering, this class ensures
+ * that the checked item remains checked.
+ */
+ private class SingleDataSetObserver extends DataSetObserver {
+ private long mCheckedId;
+ private ListView mListView;
+ private Adapter mAdapter;
+
+ /*
+ * Create a new observer.
+ * @param id The ID of the item to keep checked.
+ * @param l ListView for getting and clearing the checked states
+ * @param a Adapter for getting the IDs
+ */
+ public SingleDataSetObserver(long id, ListView l, Adapter a) {
+ mCheckedId = id;
+ mListView = l;
+ mAdapter = a;
+ }
+
+ public void onChanged() {
+ // The filter may have changed which item is checked. Find the
+ // item that the ListView thinks is checked.
+ int position = mListView.getCheckedItemPosition();
+ long id = mAdapter.getItemId(position);
+ if (mCheckedId != id) {
+ // Clear the ListView's idea of the checked item, since
+ // it is incorrect
+ mListView.clearChoices();
+ // Search for mCheckedId. If it is in the filtered list,
+ // mark it as checked
+ int count = mAdapter.getCount();
+ for (int i = 0; i < count; i++) {
+ if (mAdapter.getItemId(i) == mCheckedId) {
+ mListView.setItemChecked(i, true);
+ break;
+ }
+ }
+ }
+ }
+
+ public void onInvalidate() {}
+ }
+
public void run() {
final ListView listView = (ListView) LayoutInflater.from(mContext)
.inflate(com.android.internal.R.layout.select_dialog, null);
@@ -4901,8 +4951,7 @@
// filtered. Do not allow filtering on multiple lists until
// that bug is fixed.
- // Disable filter altogether
- // listView.setTextFilterEnabled(!mMultiple);
+ listView.setTextFilterEnabled(!mMultiple);
if (mMultiple) {
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
int length = mSelectedArray.length;
@@ -4922,6 +4971,9 @@
listView.setSelection(mSelection);
listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
listView.setItemChecked(mSelection, true);
+ DataSetObserver observer = new SingleDataSetObserver(
+ adapter.getItemId(mSelection), listView, adapter);
+ adapter.registerDataSetObserver(observer);
}
}
dialog.setOnCancelListener(new DialogInterface.OnCancelListener() {