我在Android中使用自定义ListView
,并使用自定义EditText
的搜索。当我搜索名称时,我将使用getFilter().filter(cs);
获得结果。但是,当我旋转时,ListView
会显示完整列表(不进行过滤),然后在延迟后显示已过滤的列表。
当我在没有过滤的情况下旋转时,它会保持列表视图位置。
因此,当我旋转屏幕时,我必须维护已过滤的ListView
。
请帮忙。提前谢谢......
import java.util.ArrayList;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.LoaderManager;
import android.content.Context;
import android.content.Loader;
import android.content.res.Configuration;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.provider.ContactsContract;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.TypedValue;
import android.view.Display;
import android.view.View;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.Filter;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView;
@SuppressLint("HandlerLeak")
public class ContactsListActivity
extends Activity
implements LoaderManager.LoaderCallbacks<ArrayList<ListViewItem>> {
private LetterScrollListView mLSListView;
private ProgressBar mProgressBar;
private EditText mSearchText;
private ProgressBar mSearchProgressBar;
private LinearLayout mViewsLl;
private ContactAdapter mFullContactAdapter = null;
private ArrayList<ListViewItem> mFullContactsArrayList = null;
public boolean isSoftKeyOn = false;
public boolean isPortrait;
private long mLastTimeTextChanged = 0L;
private long mCurrentTime = 0L;
private Filter mFilter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_contacts_list);
RelativeLayout windowRl = (RelativeLayout) findViewById(R.id.window_RelativeLayout);
LinearLayout progressBarLl = (LinearLayout) windowRl.findViewById(R.id.progressBar_LinearLayout);
mViewsLl = (LinearLayout) windowRl.findViewById(R.id.views_LinearLayout);
mSearchText = (EditText) mViewsLl.findViewById(R.id.contact_SearchEditText);
mSearchProgressBar = (ProgressBar) mViewsLl.findViewById(R.id.search_ProgressBar);
mLSListView = (LetterScrollListView) mViewsLl.findViewById(R.id.contacts_LetterScrollListView);
mLSListView.setSearchText(mSearchText);
if(getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
isPortrait = true;
} else {
isPortrait = false;
}
final View activityRootView = windowRl;
activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(
new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
int heightDiff = activityRootView.getRootView()
.getHeight() - activityRootView.getHeight();
// if heightDiff > 100 pixels, its probably a keyboard...
if (heightDiff > 100) {
// Toast.makeText(getApplicationContext(), "Key ON",
// Toast.LENGTH_SHORT).show();
isSoftKeyOn = true;
} else {
// Toast.makeText(getApplicationContext(), "Key OFF",
// Toast.LENGTH_SHORT).show();
isSoftKeyOn = false;
mSearchText.clearFocus();
}
}
});
mSearchText.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence cs, int arg1, int arg2,
int arg3) {
mCurrentTime = System.currentTimeMillis();
if( (mCurrentTime - mLastTimeTextChanged) <= USER_TYPE_DELAY ) {
mSearchInputHandler.removeMessages(WHAT_SEARCH);
}
// preparing message
Bundle bundle = new Bundle();
bundle.putCharSequence(USER_INPUT_KEY, cs);
Message message = mSearchInputHandler.obtainMessage(WHAT_SEARCH);
message.setData(bundle);
mSearchInputHandler.sendMessageDelayed(message, USER_TYPE_DELAY);
mLastTimeTextChanged = mCurrentTime;
}
@Override
public void beforeTextChanged(CharSequence arg0, int arg1,
int arg2, int arg3) {
// TODO Auto-generated method stub
}
@Override
public void afterTextChanged(Editable arg0) {
// TODO Auto-generated method stub
}
});
// Create a progress bar to display while the list loads
mProgressBar = new ProgressBar(this);
mProgressBar.setIndeterminate(true);
progressBarLl.addView(mProgressBar);
getLoaderManager().initLoader(0, null, this).forceLoad();
}
@SuppressLint("HandlerLeak")
private final Handler mSearchInputHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
CharSequence cs = msg.getData().getCharSequence(USER_INPUT_KEY);
int what = msg.what;
switch(what) {
case WHAT_SEARCH:
// When user changed the Text after a delay
mSearchProgressBar.setVisibility(View.VISIBLE);
mFilter.filter(cs);
break;
}
}
};
public void removeSearchProgressBar() {
mSearchProgressBar.setVisibility(View.INVISIBLE);
}
/**
* Called when a new Loader needs to be created
*/
public Loader<ArrayList<ListViewItem>> onCreateLoader(int id, Bundle args) {
// Now create and return a CursorLoader that will take care of
// creating a Cursor for the data being displayed.
Uri uri = ContactsContract.Contacts.CONTENT_URI;
String[] projection = new String[] {
ContactsContract.Contacts._ID,
ContactsContract.Contacts.DISPLAY_NAME
};
boolean showInvisible = false;
String selection = ContactsContract.Contacts.IN_VISIBLE_GROUP + " = '" +
(showInvisible ? "0" : "1") + "'";
String[] selectionArgs = null;
String sortOrder = ContactsContract.Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC";
return new ContactArrayListLoader(this, uri, projection, selection, selectionArgs, sortOrder);
}
/**
* Called when a previously created loader has finished loading
*/
public void onLoadFinished(Loader<ArrayList<ListViewItem>> loader, ArrayList<ListViewItem> data) {
mProgressBar.setVisibility(View.INVISIBLE);
if(mLSListView.getAdapter() == null) {
mFullContactsArrayList = data;
mFullContactAdapter = new ContactAdapter(this, R.layout.contact_tuple, mFullContactsArrayList);
mFilter = mFullContactAdapter.getFilter();
mLSListView.setAdapter(mFullContactAdapter);
}
}
/**
* Called when a previously created loader is reset, making the data unavailable
*/
public void onLoaderReset(Loader<ArrayList<ListViewItem>> loader) {
// This is called when the last Cursor provided to onLoadFinished()
// above is about to be closed. We need to make sure we are no
// longer using it.
//////mListView.setAdapter(new ContactAdapter(this, R.layout.contact_tuple, null));
mProgressBar.setVisibility(View.VISIBLE);
}
}
答案 0 :(得分:0)
<强>解决强>
问题在于方法
public void onLoadFinished(Loader<ArrayList<ListViewItem>> loader, ArrayList<ListViewItem> data) {....}
在轮播/启动应用时,此方法中的参数data
始终是完整列表,而不是已过滤的列表。因此,要在旋转时获取已过滤的列表,只需创建一个静态成员
private static ArrayList<ListViewItem> sCurrentContactsArrayList = null;
并在屏幕旋转之前保存,如下所示:
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
if( TextUtils.isEmpty(mSearchText.getText()) ) {
sCurrentContactsArrayList = null;
} else {
sCurrentContactsArrayList = mFullContactAdapter.getCurrentItems();
}
}
还修改onLoadFinished()
:
public void onLoadFinished(Loader<ArrayList<ListViewItem>> loader, ArrayList<ListViewItem> data) {
mProgressBar.setVisibility(View.INVISIBLE);
if(mLSListView.getAdapter() == null) {
ArrayList<ListViewItem> contactsAL = null;
if(sCurrentContactsArrayList == null) {
contactsAL = data;
} else {
contactsAL = sCurrentContactsArrayList;
}
mFullContactAdapter = new ContactAdapter(this, R.layout.contact_tuple, contactsAL, data);
if(mFilter == null) mFilter = mFullContactAdapter.getFilter();
mLSListView.setAdapter(mFullContactAdapter);
}
mSearchText.setVisibility(View.VISIBLE);
}