-1

我在过滤列表时遇到问题。我正在使用 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" 属性,这样它就不会与软键盘重叠。但是编辑文本的问题仍然相同。这里是截图

在此处输入图像描述

当我插入一个单字符列表时,会得到过滤器,并且光标从编辑文本框中消失了。

在此处输入图像描述

4

3 回答 3

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,因此默认情况下所有操作(添加、插入、删除、清除)都针对 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 不再为空,所有对任何适配器操作的后续调用都只会修改 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 所建议的]。

如果有人能对这个问题有更多的了解或确认我刚刚做了什么,我们将不胜感激。谢谢!

于 2013-05-17T07:01:49.030 回答
0

我猜你已经通过 addView() 方法在列表视图中添加了编辑文本。这确实发生了,因为所有视图都被重绘了,所以表示过去被聚焦的任何行的编辑文本现在是一个完全不同的对象。在适配器中设置一个变量: int currentFocusedRow;

在您的适配器的 getView 中:添加一个 onFocusChanged 侦听器来编辑文本,当该编辑文本获得焦点时,设置 currentFocusedRow (int variable) = row thatfocused(contained) 编辑文本恰好在其中。还设置在currentFocusedRow 被聚焦。

如果您发现其中有一些问题,请回复我。

于 2013-05-25T11:30:09.000 回答
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) {


}
});
于 2013-05-14T13:15:07.230 回答