应用程序中的搜索栏

时间:2013-03-12 09:47:52

标签: android android-layout search searchbar

我正在开发一个应用程序。其中显示列表视图,其中数据来自SQLite数据库。我在String []中获取数据。

现在需要申请的是:我想在活动的顶部添加一个搜索栏。此搜索栏应仅在活动上显示的列表中执行搜索。

当用户在搜索栏中输入一个字母时,所有数据都应显示在列表视图中,其中包含该字母。

我尝试了以下代码。

在main.java中

EditText search= (EditText) findViewById(R.id.edittext_searchbar);
search.addTextChangedListener(new TextWatcher() {
    public void onTextChanged(CharSequence s, int start, int before, int count) {
    adapter.getFilter().filter(s);
        adapter.notifyDataSetChanged();
    }   
    public void beforeTextChanged(CharSequence s, int start, int count,int after) {
    }
    @Override
    public void afterTextChanged(Editable s) {
    }
    });
listView.setAdapter(adapter);

在Adapter类中:

public void setData(String[] menuList) {   
    menuListofAdapter = menuList;//contains class items data.
}

@Override
public Filter getFilter() {
    return new Filter() {
    @Override
    protected void publishResults(CharSequence constraint, FilterResults results) {
        if (results != null && results.count >= 0) {
        setData((String[]) results.values);//if results of search is null set the searched results data
    } else {
                setData(menuListofAdapter);// set original values
            }
            notifyDataSetInvalidated();
        }

        @SuppressWarnings("null")
        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            FilterResults result = new FilterResults();
            if (!TextUtils.isEmpty(constraint)) {
                constraint = constraint.toString();
                String[] fItem = null;
                if(Utility.mainMenuList!=null){
                    for(int i=0,j=0;i<Utility.mainMenuList.length;i++){
                    if (Utility.mainMenuList[i].equalsIgnoreCase(constraint.toString())) {
                             fItem[j] = Utility.mainMenuList[i];
                         j=j+1;
                     }else{
                     }
                 }
             }
             result.count = fItem.length;
             result.values = fItem;
         } else{
             result.count=-1;// no search results found
         }             
         return result;
        }
     };
 }

我应该为此做些什么。数据在String []中。在列表视图中显示。

请建议我需要进行哪些更改。

当我应用上面的代码并运行我的应用程序并尝试搜索时,我得到错误:

03-12 18:16:19.215: D/AndroidRuntime(836): Shutting down VM
03-12 18:16:19.215: W/dalvikvm(836): threadid=1: thread exiting with uncaught exception (group=0x40015560)
03-12 18:16:19.215: E/AndroidRuntime(836): FATAL EXCEPTION: main
03-12 18:16:19.215: E/AndroidRuntime(836): java.lang.ClassCastException: java.util.ArrayList
03-12 18:16:19.215: E/AndroidRuntime(836):  at com.abc.example.adapters.MyListAdapter$1.publishResults(MainMenuListAdapter.java:41)
03-12 18:16:19.215: E/AndroidRuntime(836):  at android.widget.Filter$ResultsHandler.handleMessage(Filter.java:282)
03-12 18:16:19.215: E/AndroidRuntime(836):  at android.os.Handler.dispatchMessage(Handler.java:99)
03-12 18:16:19.215: E/AndroidRuntime(836):  at android.os.Looper.loop(Looper.java:123)
03-12 18:16:19.215: E/AndroidRuntime(836):  at android.app.ActivityThread.main(ActivityThread.java:3683)
03-12 18:16:19.215: E/AndroidRuntime(836):  at java.lang.reflect.Method.invokeNative(Native Method)
03-12 18:16:19.215: E/AndroidRuntime(836):  at java.lang.reflect.Method.invoke(Method.java:507)
03-12 18:16:19.215: E/AndroidRuntime(836):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
03-12 18:16:19.215: E/AndroidRuntime(836):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
03-12 18:16:19.215: E/AndroidRuntime(836):  at dalvik.system.NativeStart.main(Native Method)

2 个答案:

答案 0 :(得分:0)

根据您的要求,您必须在android中使用Sectioned List视图。请看这个链接。  http://samir-mangroliya.blogspot.in/2012/05/android-sectioned-listview-with-search_6865.html。 它会帮助你。让我知道你有任何疑问。

答案 1 :(得分:0)

在列表视图的顶部有一个editext。我建议你有一个自定义列表适配器。

列出数据库的原始值。

有另一个列表来设置临时数据以匹配搜索条件。

如果您的搜索条件与列表中的匹配,请将这些条件添加到founditmes并在列表中显示数据。如果它与列表中的显示原始数据不匹配。

我已经提出了一个大致的想法。以下代码可以根据您的需要进行修改。我自己实现了搜索,但它确实有效。

我在SO中问了一个问题,我从How to implement search in CustomListView based on class item of POJO class in Android?得到了答案。

尝试以下操作,如果您无法使其正常工作,您可以随时在SO中发布问题。

     search= (EditText) findViewById(R.id.search);
     //look for text changing in edittext.
     search.addTextChangedListener(new TextWatcher() {

         public void onTextChanged(CharSequence s, int start, int before, int count) {
                         youradapter.getFilter().filter(s);
                         youradapter.notifyDataSetChanged();

         }

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


           }

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

在列表中实施过滤器

 public void setData(ArrayList mPpst) {   
         set data either searched data or original values from database
        mPostingData = mPpst;//contains class items data.
    }

 @Override
 public Filter getFilter() {
     return new Filter() {
         @Override
         protected void publishResults(CharSequence constraint, FilterResults results) {
             if (results != null && results.count >= 0) {
                 setData( results.values);//if results match set data
             } else {
                 setData(mOri);// set data for listview original values.
             }

             notifyDataSetInvalidated();
         }



        @Override
         protected FilterResults performFiltering(CharSequence constraint) {
             FilterResults result = new FilterResults();
             if (!TextUtils.isEmpty(constraint)) {
                   ArrayList foundItems = new ArrayList();
                 constraint = constraint.toString().toLowerCase();
                 if(listitems!=null)
                 {
                         if(listitems.equals(constarint))//matching
                         foundItems.add(listitems);

                     }
                     else
                     {

                     }
                 }
                 }
                 result.count = foundItems.size();//search results found return count
                 result.values = foundItems;// return values
             } 
             else
             {
                 result.count=-1;// no search results found
             }


             return result;
         }
     };
 }

编辑1

how to set json parsed data in a listview and then adding search functionality in it。链接中的答案有效。我使用了临时数据并对其进行了搜索功能。您可以显示数据表单数据库并进行修改。

编辑2:

 public class MainActivity extends Activity {

// List view
private ListView lv;

// Listview Adapter
ArrayAdapter<String> adapter;

// Search EditText
EditText inputSearch;


// ArrayList for Listview
ArrayList<HashMap<String, String>> productList;

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

    // Listview Data
    String products[] = {"aaa","bbbb","cccc","dddd"};

    lv = (ListView) findViewById(R.id.list_view);
    inputSearch = (EditText) findViewById(R.id.inputSearch);

    // Adding items to listview
    adapter = new ArrayAdapter<String>(this, R.layout.list_item, R.id.product_name, products);
    lv.setAdapter(adapter);

    /**
     * Enabling Search Filter
     * */
    inputSearch.addTextChangedListener(new TextWatcher() {

        @Override
        public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) {
            // When user changed the Text
            MainActivity.this.adapter.getFilter().filter(cs);   
        }

        @Override
        public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,
                int arg3) {
            // TODO Auto-generated method stub

        }

        @Override
        public void afterTextChanged(Editable arg0) {
            // TODO Auto-generated method stub                          
        }
    });
  }

}

使用数据库中的数据编辑3搜索

 public class SearchActivity extends ListActivity {
 ArrayAdapter<String> dataAdapter = null;

  private ArrayList<String> results = new ArrayList<String>();
  private String tableName = DatabaseHandler.TABLE_SEARCH;
  private SQLiteDatabase newDB;
  ArrayAdapter<String> adapter = null;

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

   DatabaseHandler dbHelper = new DatabaseHandler(this.getApplicationContext());
   newDB = dbHelper.getWritableDatabase();
   Cursor c = newDB.rawQuery("SELECT skeys FROM " +
        tableName, null);
   if (c != null ) {
    if  (c.moveToFirst()) {
        do {
            String skeys = c.getString(c.getColumnIndex("skeys"));
            results.add(skeys);
        }while (c.moveToNext());
    } 
 }           

dataAdapter = new ArrayAdapter<String>(this,
        R.layout.listviews_search, results);

setListAdapter(new ArrayAdapter<String>(this,
        R.layout.listviews_search, results));

  ListView listView = (ListView) findViewById(android.R.id.list);
  listView.setAdapter(dataAdapter);
  listView.setTextFilterEnabled(true);

  listView.setOnItemClickListener(new OnItemClickListener() {
      public void onItemClick(AdapterView<?> parent, View view,
              int position, long id) {
          Toast.makeText(getApplicationContext(),
                  ((TextView) view).getText(), Toast.LENGTH_SHORT).show();
      }
  });

  EditText myFilter = (EditText) findViewById(R.id.search);
  myFilter.addTextChangedListener(new TextWatcher(){
      public void afterTextChanged(Editable s) {
  }

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

      public void onTextChanged(CharSequence s, int start, int before, int count) {
   dataAdapter.getFilter().filter(s.toString());
      }
  });
 }
}