Android操作栏使用listview搜索

时间:2015-08-11 13:31:13

标签: android listview search

我是Android开发新手。我想要的是使用动作栏搜索视图小部件搜索我的列表视图。我该如何实现搜索功能。我缺少的是搜索功能。我看过一些搜索功能,但它基于editText。请帮忙。

这是我的代码:

menu.xml文件

   <item android:id="@+id/menu_search"
          android:title="@string/menu_search"
          android:icon="@android:drawable/ic_menu_search"
          android:showAsAction="ifRoom|collapseActionView"
          android:actionViewClass="android.widget.SearchView" />

在我的manifest.xml中

<activity
            android:name=".MainActivity"
             <intent-filter>
                <action android:name="android.intent.action.SEARCH" />
            </intent-filter>
            <meta-data
                android:name="android.app.searchable"
                android:resource="@xml/searchable">
            </meta-data>
        </activity>
我的MainActivity.java

  protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);

                this.lv = (ListView) findViewById(R.id.listView);

                this.databaseAccess = DatabaseAccess.getInstance(getApplicationContext());
                this.persons= getPersonList();

                Adapter adapter = new Adapter(this, persons);
                this.lv.setAdapter(adapter);
}
    public List<Person> getPersonList(){
            databaseAccess.open();
            List<Person> person= databaseAccess.getPersons();
            databaseAccess.close();
            return person;
        }

 private class Adapter extends ArrayAdapter<Person> {

        public Adapter(Context context, List<Person> objects) {
            super(context, 0, objects);
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            if (convertView == null) {
                convertView = getLayoutInflater().inflate(R.layout.persons, parent, false);
            }

            TextView id = (TextView) convertView.findViewById(R.id.id);
            TextView name= (TextView) convertView.findViewById(R.id.name);
            TextView lastname = (TextView) convertView.findViewById(R.id.latname);

            Person p = persons.get(position);
            id.setText(p.getId());
            name.setText(p.getName());
            lastname.setText(p.getLastName());

            return convertView;
        }

4 个答案:

答案 0 :(得分:3)

您需要在适配器中实现Filterable接口。

然后膨胀菜单:

  @Override
  public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    MenuItem searchMenuItem = menu.findItem(R.id.menu_search);
    if (searchMenuItem == null) {
        return;
    }

    searchView = (SearchView) searchMenuItem.getActionView();
    if (searchView != null) {
        searchView.setQueryHint(getString(R.string.search_hint));
        searchView.setMaxWidth(2129960); // https://stackoverflow.com/questions/18063103/searchview-in-optionsmenu-not-full-width
        searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextSubmit(String s) {
                return false;
            }

            @Override
            public boolean onQueryTextChange(String s) {
                SearchFragment.this.onQueryTextChange(s);
                return false;
            }
        });
    }
}

然后指定处理查询文本更改事件的方法,例如:

void onQueryTextChange(String query) {
    searchAdapter.getFilter().filter(query);
}

查找更多信息here

答案 1 :(得分:1)

你必须使用model,listview和customadapter进行过滤。我为此创建了一个演示,假设您有一个名为Product的模型,并且您在自定义列表视图中显示其内容,其中名称,价格以textview显示。我的意思是在具有两个textviews的自定义行中。并且您想要过滤自定义row字段之一的列表。我用“name”过滤了

源代码

//这是你的模特

public class Product {

    public String name;
    public Integer price;
    public Product(String name, Integer price) {
        super();
        this.name = name;
        this.price = price;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Integer getPrice() {
        return price;
    }
    public void setPrice(Integer price) {
        this.price = price;
    }

}

//这是您使用自定义适配器和列表视图的活动

public class MainActivity extends Activity{
private LinearLayout llContainer;
private EditText etSearch;
private ListView lvProducts;

private ArrayList<Product> mProductArrayList = new ArrayList<Product>();
private MyAdapter adapter1;


@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);


    initialize();



    // Add Text Change Listener to EditText
    etSearch.addTextChangedListener(new TextWatcher() {

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            // Call back the Adapter with current character to Filter
            adapter1.getFilter().filter(s.toString());
        }

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count,int after) {
        }

        @Override
        public void afterTextChanged(Editable s) {
        }
    });
}

private void initialize() {
    etSearch = (EditText) findViewById(R.id.etSearch);
    lvProducts = (ListView)findViewById(R.id.lvOS);
}

@Override
protected void onResume() {
    // TODO Auto-generated method stub
    super.onResume();

    mProductArrayList.add(new Product("a", 100));
    mProductArrayList.add(new Product("b", 200));
    mProductArrayList.add(new Product("c", 300));
    mProductArrayList.add(new Product("d", 400));
    mProductArrayList.add(new Product("e", 500));
    mProductArrayList.add(new Product("f", 600));
    mProductArrayList.add(new Product("g", 700));
    mProductArrayList.add(new Product("h", 800));
    mProductArrayList.add(new Product("i", 900));
    mProductArrayList.add(new Product("j", 1000));
    mProductArrayList.add(new Product("k", 1100));
    mProductArrayList.add(new Product("l", 1200));
    mProductArrayList.add(new Product("m", 1000));
    mProductArrayList.add(new Product("n", 1300));
    mProductArrayList.add(new Product("o", 1400));
    mProductArrayList.add(new Product("p", 1500));


    adapter1 = new MyAdapter(MainActivity.this, mProductArrayList);
    lvProducts.setAdapter(adapter1);
}


// Adapter Class            
public class MyAdapter extends BaseAdapter implements Filterable {

    private ArrayList<Product> mOriginalValues; // Original Values
    private ArrayList<Product> mDisplayedValues;    // Values to be displayed
    LayoutInflater inflater;

    public MyAdapter(Context context, ArrayList<Product> mProductArrayList) {
        this.mOriginalValues = mProductArrayList;
        this.mDisplayedValues = mProductArrayList;
        inflater = LayoutInflater.from(context);
    }

    @Override
    public int getCount() {
        return mDisplayedValues.size();
    }

    @Override
    public Object getItem(int position) {
        return position;
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    private class ViewHolder {
        LinearLayout llContainer;
        TextView tvName,tvPrice;
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {

        ViewHolder holder = null;

        if (convertView == null) {

            holder = new ViewHolder();
            convertView = inflater.inflate(R.layout.row, null);
            holder.llContainer = (LinearLayout)convertView.findViewById(R.id.llContainer);
            holder.tvName = (TextView) convertView.findViewById(R.id.tvName);
            holder.tvPrice = (TextView) convertView.findViewById(R.id.tvPrice);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }
        holder.tvName.setText(mDisplayedValues.get(position).name);
        holder.tvPrice.setText(mDisplayedValues.get(position).price+"");

        holder.llContainer.setOnClickListener(new OnClickListener() {

            public void onClick(View v) {

                Toast.makeText(MainActivity.this, mDisplayedValues.get(position).name, Toast.LENGTH_SHORT).show();
            }
        });

        return convertView;
    }

    @Override
    public Filter getFilter() {
        Filter filter = new Filter() {

            @SuppressWarnings("unchecked")
            @Override
            protected void publishResults(CharSequence constraint,FilterResults results) {

                mDisplayedValues = (ArrayList<Product>) results.values; // has the filtered values
                notifyDataSetChanged();  // notifies the data with new filtered values
            }

            @Override
            protected FilterResults performFiltering(CharSequence constraint) {
                FilterResults results = new FilterResults();        // Holds the results of a filtering operation in values
                ArrayList<Product> FilteredArrList = new ArrayList<Product>();

                if (mOriginalValues == null) {
                    mOriginalValues = new ArrayList<Product>(mDisplayedValues); // saves the original data in mOriginalValues
                }

                /********
                 *
                 *  If constraint(CharSequence that is received) is null returns the mOriginalValues(Original) values
                 *  else does the Filtering and returns FilteredArrList(Filtered)  
                 *
                 ********/
                if (constraint == null || constraint.length() == 0) {

                    // set the Original result to return  
                    results.count = mOriginalValues.size();
                    results.values = mOriginalValues;
                } else {
                    constraint = constraint.toString().toLowerCase();
                    for (int i = 0; i < mOriginalValues.size(); i++) {
                        String data = mOriginalValues.get(i).name;
                        if (data.toLowerCase().startsWith(constraint.toString())) {
                            FilteredArrList.add(new Product(mOriginalValues.get(i).name,mOriginalValues.get(i).price));
                        }
                    }
                    // set the Filtered result to return
                        results.count = FilteredArrList.size();
                        results.values = FilteredArrList;
                    }
                    return results;
                }
            };
            return filter;
        }
    }
}

//这是你的activity_main.xml

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

    <EditText 
        android:id="@+id/etSearch"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"/>

    <ListView 
        android:id="@+id/lvProducts"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"></ListView>    

</LinearLayout>

//这是你的row.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/llContainer"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal" >

    <TextView 
        android:id="@+id/tvName"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:singleLine="true"
        android:layout_weight="1"/>

    <TextView 
        android:id="@+id/tvPrice"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:singleLine="true"
        android:layout_weight="1"/>

</LinearLayout>

答案 2 :(得分:0)

试试这个样本。 Sample search widget

答案 3 :(得分:0)

使用SearchView(一种默认的操作栏功能),可以很好地解释您在此链接中要查找的内容。

http://blog.lovelyhq.com/implementing-a-live-list-search-in-android-action-bar/

希望它有所帮助。