0

我正在写一个字典应用程序。我的搜索屏幕非常简单:居中Activity是应用程序的徽标,与屏幕底部对齐的是搜索框。当搜索框获得焦点时,软键盘弹出,搜索框在其上方移动。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >

    <ImageView android:id="@+id/search_logo"
        android:layout_width="250dp"
        android:layout_height="wrap_content"
        android:src="@drawable/logo_transparent"
        android:layout_centerInParent="true"
        android:contentDescription="@string/desc_logo"
        />

    <EditText android:id="@+id/search_fld"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@drawable/textbox"
        android:inputType="text"
        android:hint="@string/search_hint"
        android:padding="10dp"
        android:layout_alignParentBottom="true"
        />

</RelativeLayout>

只要用户输入一个字母,我就会在 Lucene 中查询匹配的条目。我希望搜索框顶部的视图对ListView输入(或删除)的每个字母进行动态更新,但是如何从这个 XML 布局中做到这一点?这种设计的正确方法是什么?

4

2 回答 2

3

以下是最终将引导您找到答案的指针。

  1. 将 a 添加textwatcher到您要在其中编写搜索词的编辑字段。

     txtSearch.addTextChangedListener(textWatcher);
    
  2. afterTextChangedtextwatcher 的方法中,您将需要一个过滤器,将在搜索字段中键入的字符作为参数,以过滤掉搜索结果。

    private TextWatcher textWatcher = new TextWatcher() {
    
    @Override
    public void onTextChanged(CharSequence s, int start, int before,
            int count) {
        // TODO Auto-generated method stub
    }
    
    @Override
    public void beforeTextChanged(CharSequence s, int start, int count,
            int after) {
        // TODO Auto-generated method stub
    }
    
    @Override
    public void afterTextChanged(Editable s) {
    
        adapter.getFilter().filter(s);
        adapter.notifyDataSetChanged(); 
    }
    };
    
  3. 以下是我用于过滤目的的类。

    /*
     * Class that implements filtering functionality.
     */
    public class MyFilter extends Filter {
        public MyFilter(ArrayList<CustomerListRow> data) {
        }
    
        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
    
            constraint = constraint.toString().toLowerCase();
            FilterResults result = new FilterResults();
    
            if (constraint != null && constraint.toString().length() > 0) {
                ArrayList<CustomerListRow> filt = new ArrayList<CustomerListRow>();
    
                for (int i = 0; i < arrayListCopy.size(); i++) {
                    CustomerListRow each = arrayListCopy.get(i);
                    if (each.getName().toLowerCase().contains(constraint)) {
                        filt.add(each);
                    }
                }
                result.count = filt.size();
                result.values = filt;
            } else {
                synchronized (this) {
                    result.count = arrayListCopy.size();
                    result.values = arrayListCopy;
                }
            }
    
            return result;
        }
    
        @Override
        protected void publishResults(CharSequence constraint,
                FilterResults results) {
            ArrayList<CustomerListRow> filtered = (ArrayList<CustomerListRow>) results.values;
            clear();
    
            int size = filtered.size();
            for (int i = 0; i < size; i++) {
                add(filtered.get(i));
            }
            notifyDataSetInvalidated();
        }
    }
    
  4. 您将需要创建一个适配器,您将向其传递完整列表,最终将传递给过滤器。以下是我的适配器类的构造函数。

            public MyAdapter(Context context, int textViewResourceId,
                List<CustomerListRow> objects) {
            super(context, textViewResourceId, objects);
            this.context = context;
            inflator = (LayoutInflater) context
                    .getSystemService(LAYOUT_INFLATER_SERVICE);
            list = (ArrayList<CustomerListRow>) objects;
            filter = new MyFilter(list);
            arrayListCopy.addAll(list);
        } 
    
于 2012-10-18T09:53:04.913 回答
1

解决方案似乎更简单。首先,TextWatcherEditText. 然后,在里面onTextChanged(),这就是你要做的:

  1. 每当调用该方法时创建一个 Lucene 查询。得到结果。
  2. 调用clear()适配器。
  3. 将所有结果添加到适配器。
  4. 调用notifyDataSetChanged()适配器。
于 2012-10-29T04:51:00.850 回答