编辑我没有添加我的 XML
我正在编写一个用于标记选择的对话框。第一个视图是应用他们在数据库中的标签。下一个屏幕是一个对话框,用于将新标签添加到他们的数据库中。我正在为他们提供用于标签的建议。我想在他们开始输入标签时过滤列表。我为每个屏幕使用两个自定义 CursorAdapter,但它们共享相同的 ListView。我还在使用 CursorLoader 在后台运行我的查询,两者都是从支持库扩展而来的。
当我第一次打开新标签屏幕时,对话框出现后,列表不会用 Android 4.0.3 中的过滤光标刷新,快速滚动也不起作用。如果我切换到标签视图,然后返回到新标签对话框,它会按应有的方式过滤和滚动。我的查询有效,代码每次都在 Android 2.3.3 中有效。我不知道为什么这不起作用。这是我的 CursorLoader 和 Suggestion 适配器的代码。
package org.lds.ldssa;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.res.Resources;
import android.database.Cursor;
import android.os.Bundle;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.support.v4.widget.SimpleCursorAdapter;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.*;
import org.lds.ldssa.service.MLDatabase;
import org.lds.ldssa.service.aws.Annotation;
public class TagDialog extends AlertDialog implements LoaderManager.LoaderCallbacks<Cursor> {
private static final String TAG = "ldssa.tagdialog";
public static final int TAGLOADERID = 0;
// View Items
private EditText mEditText;
private ListView mListView;
private TextView mEmptyView;
private ProgressBar mProgressBar;
private ImageButton mNewTagButton;
private ImageButton mSortTagButton;
private TextView mTitle;
private Button mOkButton;
private Button mCancelButton;
private String mTagTitle;
private String mNewTagTitle;
private Annotation mAnnotation;
private ContentFragment mContentFragment;
private boolean isNewTagView;
private static final String KEY_NEWTAGVIEW = "new_tag_view";
private SimpleCursorAdapter mSuggestionAdapter;
private TagListAdapter mTagAdapter;
private MLDatabase mlDatabase;
protected TagDialog(Context context) {
super(context);
}
public void onCreate(Bundle savedInstanceState){
Context context = getContext();
Resources r = context.getResources();
final LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(R.layout.dialog_tag, null);
// Main parts of the view
mEditText = (EditText) view.findViewById(R.id.tag_new_tag);
mListView = (ListView) view.findViewById(android.R.id.list);
mProgressBar = (ProgressBar) view.findViewById(R.id.tag_spin_progress_bar);
mEmptyView = (TextView) view.findViewById(android.R.id.empty);
mEmptyView.setVisibility(View.INVISIBLE);
// Titlebar
View titleBar = inflater.inflate(R.layout.dialog_tag_title, null);
mNewTagButton = (ImageButton) titleBar.findViewById(R.id.tag_new_icon);
mSortTagButton = (ImageButton) titleBar.findViewById(R.id.tag_sort_icon);
mTitle = (TextView) titleBar.findViewById(R.id.tag_title);
mTagTitle = r.getString(R.string.tag_dialog_title);
mNewTagTitle = r.getString(R.string.tag_new_dialog_title);
this.setCustomTitle(titleBar);
// Buttons
final String OK = r.getString(R.string.ok);
final String CANCEL = r.getString(R.string.cancel);
this.setButton(BUTTON_POSITIVE, OK, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) { /*Never Used*/}});
this.setButton(BUTTON_NEGATIVE, CANCEL, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) { /*Never Used*/}});
// Setup Button Listeners
setOnShowListener(new OnShowListener() {
@Override
public void onShow(DialogInterface dialog) {
Button ok = getButton(BUTTON_POSITIVE);
ok.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(isNewTagView){
hideIMM();
setupTagDialog();
mEditText.setText("");
} else {
dismiss();
}
}
});
Button cancel = getButton(BUTTON_NEGATIVE);
cancel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(isNewTagView){
hideIMM();
setupTagDialog();
mEditText.setText("");
} else {
dismiss();
}
}
});
}
});
mNewTagButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
setupNewTagDialog();
}
});
mSortTagButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
}
});
mEditText.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {}
@Override
public void afterTextChanged(Editable s) {
LoaderManager lm = getLoaderManager();
if(lm != null){
Loader l = lm.getLoader(TAGLOADERID);
if(l != null){
l.forceLoad();
} else {
restartLoader();
}
} else {
restartLoader();
}
}
});
String[] UIBindFrom = {MLDatabase.CL_ID};
int[] UIBindTo = {android.R.id.text1};
mTagAdapter = new TagListAdapter(context, null);
mSuggestionAdapter = new SimpleCursorAdapter(context, android.R.layout.simple_list_item_1, null,
UIBindFrom, UIBindTo, 0);
//Handle Rotations
if(savedInstanceState == null){
//New
setupTagDialog();
} else {
//rotated
isNewTagView = savedInstanceState.getBoolean(KEY_NEWTAGVIEW, false);
if(isNewTagView){
restoreTagState(savedInstanceState);
} else {
restoreNewTagState(savedInstanceState);
}
}
LoaderManager lm = getLoaderManager();
if(lm != null){
lm.initLoader(TAGLOADERID, null, this);
}
this.setView(view);
super.onCreate(savedInstanceState);
}
public void onStart(){
restartLoader();
}
@Override
public Bundle onSaveInstanceState(){
Bundle bundle = super.onSaveInstanceState();
bundle.putBoolean(KEY_NEWTAGVIEW, isNewTagView);
return bundle;
}
@Override
public void onBackPressed(){
if(isNewTagView){
hideIMM();
setupTagDialog();
} else {
this.dismiss();
}
}
private void setupTagDialog() {
isNewTagView = false;
mTitle.setText(mTagTitle);
mNewTagButton.setVisibility(View.VISIBLE);
mSortTagButton.setVisibility(View.VISIBLE);
mEditText.setVisibility(View.GONE);
mListView.setVisibility(View.GONE);
mProgressBar.setVisibility(View.VISIBLE);
mListView.setAdapter(mTagAdapter);
restartLoader();
}
private void setupNewTagDialog() {
isNewTagView = true;
mTitle.setText(mNewTagTitle);
mNewTagButton.setVisibility(View.INVISIBLE);
mSortTagButton.setVisibility(View.INVISIBLE);
mEditText.setVisibility(View.VISIBLE);
mListView.setVisibility(View.GONE);
mProgressBar.setVisibility(View.VISIBLE);
mListView.setAdapter(mSuggestionAdapter);
restartLoader();
}
private void restoreTagState(Bundle bundle) {
setupTagDialog();
}
private void restoreNewTagState(Bundle bundle) {
setupNewTagDialog();
}
public void setAnnotation(Annotation a) {
mAnnotation = a;
}
public void setContentViewInterface(ContentFragment contentFragment) {
mContentFragment = contentFragment;
}
private MLDatabase getDatabase() {
if(mlDatabase == null){
GospelLibraryApplication app = (GospelLibraryApplication) getContext().getApplicationContext();
mlDatabase = app.getMlDatabase();
}
return mlDatabase;
}
public String getFilter() {
return mEditText.getText().toString().trim();
}
public Integer getAnnotationID(){
if(mAnnotation != null){
return mAnnotation.getDbKey();
}
return -1;
}
private LoaderManager getLoaderManager(){
if(mContentFragment == null){
Log.d(TAG, "ContentFragment is NULL!");
return null;
}
return mContentFragment.getContentActivity().getSupportLoaderManager();
}
private void restartLoader(){
LoaderManager lm = getLoaderManager();
if(lm != null){
lm.restartLoader(TAGLOADERID, null, this);
}
}
private void hideIMM(){
InputMethodManager imm = (InputMethodManager)getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(mEditText.getWindowToken(), 0);
}
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
TagCursorLoader loader = new TagCursorLoader(getContext(), this);
return loader;
}
@Override
public void onLoadFinished(Loader<Cursor> cursorLoader, Cursor data) {
if(isNewTagView) {
mSuggestionAdapter.changeCursor(data);
} else {
mTagAdapter.changeCursor(data);
}
mListView.invalidateViews();
mProgressBar.setVisibility(View.GONE);
mListView.setVisibility(View.VISIBLE);
}
@Override
public void onLoaderReset(Loader<Cursor> cursorLoader) {
if(mSuggestionAdapter != null) {
mSuggestionAdapter.changeCursor(null);
}
}
public static class TagCursorLoader extends CursorLoader {
private final ForceLoadContentObserver mObserver = new ForceLoadContentObserver();
private TagDialog dialog;
private MLDatabase mlDatabase;
private Cursor mCursor;
private String mFilter;
private Integer mAnnotationID;
// Runs on worker thread
@Override
public Cursor loadInBackground(){
Cursor cursor = null;
if(dialog.isNewTagView){
mFilter = dialog.getFilter();
cursor = mlDatabase.getTagSuggestions(mFilter);
} else {
mAnnotationID = dialog.getAnnotationID();
}
if(cursor != null){
cursor.registerContentObserver(mObserver);
}
return cursor;
}
//Runs on UI thread
@Override
public void deliverResult(Cursor cursor){
//Handle if canceled in the middle.
if(isReset()){
if(cursor != null){
cursor.close();
}
return;
}
Cursor oldCursor = mCursor;
mCursor = cursor;
if(isStarted()) {
super.deliverResult(cursor);
}
if(oldCursor != null && !oldCursor.equals(cursor) && !oldCursor.isClosed()) {
oldCursor.close();
}
}
public TagCursorLoader(Context context, TagDialog dialog) {
super(context);
this.dialog = dialog;
mlDatabase = dialog.getDatabase();
}
@Override
public void onStartLoading(){
if(mCursor == null) {
forceLoad();
} else {
if(dialog.isNewTagView && mFilter.equals(dialog.getFilter())) {
deliverResult(mCursor);
} else {
forceLoad();
}
}
}
@Override
protected void onStopLoading() {
// Attempt to cancel the current load task if possible.
cancelLoad();
}
@Override
public void onCanceled(Cursor cursor) {
if (cursor != null && !cursor.isClosed()) {
cursor.close();
}
}
@Override
protected void onReset() {
super.onReset();
// Ensure the loader is stopped
onStopLoading();
if (mCursor != null && !mCursor.isClosed()) {
mCursor.close();
}
mCursor = null;
}
}
}
package org.lds.ldssa;
import android.R;
import android.content.Context;
import android.database.Cursor;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.support.v4.widget.CursorAdapter;
import android.widget.TextView;
import org.lds.ldssa.service.MLDatabase;
public class TagSuggestionAdapter extends CursorAdapter {
public TagSuggestionAdapter(Context context, Cursor cursor, int flags){
super(context, cursor, flags);
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
LayoutInflater inflater = LayoutInflater.from(context);
View v = inflater.inflate(R.layout.simple_list_item_1, parent, false);
bindView(v, context, cursor);
return v;
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
TextView tv = (TextView) view.findViewById(R.id.text1);
tv.setText(cursor.getString(cursor.getColumnIndex(MLDatabase.CL_ID)));
}
}
在此先感谢您的帮助。
XML
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/tag_layout"
android:orientation="vertical"
android:layout_height="wrap_content"
android:layout_width="@dimen/min_dialog_width"
android:padding="5dp"
android:animateLayoutChanges="true"
>
<!-- Here is the view to show if the list is emtpy -->
<TextView
android:id="@android:id/empty"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="50dp"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_centerInParent="true"
android:gravity="center"
android:text="@string/no_items"
android:visibility="invisible"
/>
<ListView
android:id="@android:id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="invisible"
/>
<ProgressBar
android:id="@+id/tag_spin_progress_bar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:indeterminate="true"
/>
</RelativeLayout>