当用户键入输入(字典应用程序)时,如何将屏幕的上半部分更改为列表视图?

时间:2012-10-18 09:04:34

标签: android android-layout android-listview

我正在写一本字典应用程序。我的搜索屏幕非常简单: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布局中执行此操作?这种设计的正确方法是什么?

2 个答案:

答案 0 :(得分:3)

以下是最终将引导您回答的指针。

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

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

    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);
        } 
    

答案 1 :(得分:1)

解决方案似乎更直截了当。首先,为TextWatcher创建EditText。然后,在onTextChanged()内,这就是你所做的:

  1. 每次调用方法时创建Lucene查询。得到结果。
  2. 在适配器中调用clear()
  3. 将所有结果添加到适配器。
  4. 在适配器上调用notifyDataSetChanged()