【问题标题】:Search Bar in application应用程序中的搜索栏
【发布时间】:2013-03-12 09:47:51
【问题描述】:

我正在开发一个应用程序。在其中显示数据来自 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);

在适配器类中:

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)

【问题讨论】:

    标签: android android-layout search searchbar


    【解决方案1】:

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

    拥有数据库的原始值列表。

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

    如果您的搜索条件与列表中的一个匹配,则将其添加到 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());
          }
      });
     }
    }
    

    【讨论】:

      【解决方案2】:

      根据您的要求,您必须在 android 中使用分段列表视图。请看这个链接。 http://samir-mangroliya.blogspot.in/2012/05/android-sectioned-listview-with-search_6865.html。 它将对您有很大帮助。如果您有任何疑问,请告诉我。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多