0

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

2 回答 2

0

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

于 2013-03-12T09:55:33.440 回答
0

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

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

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

如果您的搜索条件与列表中的一个匹配,则将其添加到 founditmes 并在列表中显示数据。如果不匹配,则在列表中显示原始数据。

我已经给出了一个大概的想法。下面的代码可以根据你的需要进行修改。我自己实现了搜索并且它有效。

我在 SO 中问了一个问题,我从如何根据 Android 中 POJO 类的类项在 CustomListView 中实现搜索得到了答案?.

试试下面的,如果你不能让它工作,你可以随时在 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

如何在列表视图中设置 json 解析数据,然后在其中添加搜索功能。链接中的答案有效。我使用了临时数据并对其进行了搜索。您可以显示数据表单数据库并对其进行修改。

编辑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());
      }
  });
 }
}
于 2013-03-12T10:16:39.743 回答