我在列表过滤时面临问题。我正在使用onTextChange()方法。它工作正常但问题是,当我在编辑文本中键入单个字符时,软键盘消失,我必须点击编辑文本再次键入完整的字符串。我也完成了代码,以便软键盘在文本更改后不会消失,但键入仍然我必须点击编辑文本。这是我的代码:
search.addTextChangedListener(new TextWatcher() {
@ Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
// TODO Auto-generated method stub
String startwith = s.toString();
ArrayList < Myshares > filterList = new ArrayList < Myshares > ();
for (int i = 0; i < fileList.size(); i++) {
if (fileList.get(i).getName().toLowerCase().startsWith(startwith) || fileList.get(i).getName().toUpperCase().startsWith(startwith)) {
filterList.add(fileList.get(i));
}
}
adapter = new MListAdapter(PlayListActivity.this, filterList);
playListView.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
@
Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
@
Override
public void afterTextChanged(Editable s) {
search.setSelection(search.getText().length());
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(search, InputMethodManager.SHOW_IMPLICIT);
}
});
这是我编辑文本的xml代码:
<EditText
android:ems="10"
android:id="@+id/search_bar"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="5dp"
android:layout_weight="2"
android:background="@drawable/searchbox"
android:editable="true"
android:focusable="true"
android:inputType="textFilter"
android:hint="Search"
android:keepScreenOn="true"
android:paddingLeft="10dp"
android:textSize="15dp" />
我还在列表视图上设置了android:focusable =“false”属性,这样它就不会与软键盘重叠。但编辑文本的问题仍然相同。这是截图
当我插入单个字符列表时,获取过滤器并且光标从编辑文本框中消失。
答案 0 :(得分:1)
我查看了ArrayAdapter的实际源代码,看起来它实际上是按照这种方式编写的。
ArrayAdapter有两个列表:mObjects和mOriginalValues。 mObjects是适配器将使用的主要数据集。使用add()函数,例如:
public void add(T object) { if (mOriginalValues != null) { synchronized (mLock) { mOriginalValues.add(object); if (mNotifyOnChange) notifyDataSetChanged(); } } else { mObjects.add(object); if (mNotifyOnChange) notifyDataSetChanged(); }
}
mOriginalValues最初为null,因此所有操作(add,insert,remove,clear)默认都是针对mObjects的。在您决定在列表上启用过滤并实际执行过滤之前,这一切都很好。第一次过滤使用mObjects具有的mOriginalValues初始化:
private class ArrayFilter extends Filter { @Override protected FilterResults performFiltering(CharSequence prefix) { FilterResults results = new FilterResults(); if (mOriginalValues == null) { synchronized (mLock) { mOriginalValues = new ArrayList<T>(mObjects); //mOriginalValues is no longer null } } if (prefix == null || prefix.length() == 0) { synchronized (mLock) { ArrayList<T> list = new ArrayList<T>(mOriginalValues); results.values = list; results.count = list.size(); } } else { //filtering work happens here and a new filtered set is stored in newValues results.values = newValues; results.count = newValues.size(); } return results; } @Override protected void publishResults(CharSequence constraint, FilterResults results) { //noinspection unchecked mObjects = (List<T>) results.values; if (results.count > 0) { notifyDataSetChanged(); } else { notifyDataSetInvalidated(); } } }
mOriginalValues现在拥有原始值/项的副本,因此适配器可以完成其工作并通过mObjects显示已过滤的列表,而不会丢失预过滤的数据。
现在原谅我(并且请告诉和解释)如果我的想法不正确但我觉得这很奇怪,因为现在mOriginalValues不再为null,所有后续调用任何适配器操作都只会修改mOriginalValues。但是,由于适配器设置为将mObjects视为其主要数据集,因此屏幕上将显示没有任何事情发生。直到你执行另一轮过滤。删除过滤器会触发:
if (prefix == null || prefix.length() == 0) { synchronized (mLock) { ArrayList<T> list = new ArrayList<T>(mOriginalValues); results.values = list; results.count = list.size(); } }
mOriginalValues,我们自第一个过滤器以来一直在修改(虽然我们看不到它在屏幕上发生)存储在另一个列表中并复制到mObjects,最后显示所做的更改。不过从这一点开始它将是这样的:所有操作都将在mOriginalValues上完成,并且只有在过滤后才会出现更改。
至于解决方案,我现在提出的是(1)放置一个布尔标志,告诉适配器操作是否有正在进行的过滤 - 如果过滤完成,则复制将mOriginalValues的内容转换为mObjects,或者(2)简单地调用适配器的Filter对象并传递一个空字符串* .getFilter()。filter(“”)以在每次操作后强制过滤器[同样由Santhosh建议]。
如果有人能够对这个问题有所了解或确认我刚刚做了什么,我们将不胜感激。谢谢!
答案 1 :(得分:0)
//ArrayAdapter Definition. Make it activity class field.
ArrayAdapter<String> adapter;
//initialize the adapter by loading complete data and set Adapter to ListView.
//**Note: I have used ArrayList<String> below.**
ArrayList <String> filterList = new ArrayList <Myshares> ();
for (int i = 0; i < fileList.size(); i++) {
if (fileList.get(i).getName().toLowerCase() || fileList.get(i).getName().toUpperCase()) {
filterList.add(fileList.get(i));
}
}
adapter = new ArrayAdapter<String>(this, R.layout.searchresult_item, R.id.search_item_name,filterList);
//Here, searchresult_item is the layout file name. and search_item_name is the Textview inside it.
search.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence cs, int start, int before, int count) {
YourActivity.this.Youradapter.getFilter().filter(cs);
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,int after) {
}
@Override
public void afterTextChanged(Editable s) {
}
});
答案 2 :(得分:0)
我猜你已经通过addView()方法在列表视图中添加了编辑文本。确实发生了这种情况,因为所有视图都被重新绘制,因此表示用于聚焦的任何行的编辑文本现在是完全不同的对象。在适配器中设置变量:int currentFocusedRow;
在适配器的getView中: 添加onFocusChanged侦听器以编辑文本 当编辑文本获得焦点时,设置 currentFocusedRow(int variable)=聚焦(包含)编辑文本的行恰好在。还设置了当前聚焦路径中任何已编辑的文本。
如果您在此看到一些问题,请回复我。