【问题标题】:how to make a search in a list view android which is populated from SQLite database如何在从 SQLite 数据库填充的列表视图 android 中进行搜索
【发布时间】:2021-02-21 15:37:09
【问题描述】:

大家好,我是 android 新手,只是一个初学者。我正在开发一个应用程序,它显示带有品牌名称和通用名称的药物列表。我使用 ListView 来显示数据,这些数据来自 SQLite 数据库。当用户在 editText 中输入药物名称时,我想要的是它应该显示来自 ListView 的搜索结果,例如我的列表有一个药物名称 NICOX 一个品牌名称。并且用户想要搜索此名称并在编辑文本中输入 N 然后此名称应显示在列表视图中,所有其他名称以用户在编辑文本中输入的字母开头我添加的所有代码都是我的主要活动代码。

           package com.example.clnicmangmentapp;
        
        import androidx.appcompat.app.AppCompatActivity;
        
        import android.content.Intent;
        import android.database.Cursor;
        import android.database.sqlite.SQLiteDatabase;
        import android.os.Bundle;
        import android.provider.BaseColumns;
        import android.view.Menu;
        import android.view.MenuInflater;
        import android.view.MenuItem;
        import android.view.View;
        import android.widget.AdapterView;
        import android.widget.ListView;
        import android.widget.SearchView;
        
        import com.example.clnicmangmentapp.data.AddNewProductContract.AddNewProductEntry;
        import com.example.clnicmangmentapp.data.AddNewProductDataBaseHelper;
        
        public class MainActivity extends AppCompatActivity {
        
            AddNewProductDataBaseHelper mDataBaseHelper;
        
            SQLiteDatabase database;
            Cursor cursor;
        
            SearchView mSearchView;
        
            @Override
            protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_main);
                mSearchView = findViewById(R.id.search_view);
        
                mDataBaseHelper = new AddNewProductDataBaseHelper(this);
        
                 database = mDataBaseHelper.getWritableDatabase();
        
        
                cursor = database.rawQuery("SELECT * FROM " + AddNewProductEntry.TABLE_NAME, null);
        
        
                ListView listView = findViewById(R.id.list_view);
                DispalyDataAdapterView adapter = new DispalyDataAdapterView(this, cursor);
                listView.setAdapter(adapter);
        
                adapter.changeCursor(cursor);
        
        
        
                listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                    @Override
                    public void onItemClick(AdapterView<?> parent, View view, int position, long id) 
                      {
        
                      int brandNameCol = 
                         cursor.getColumnIndex(AddNewProductEntry.COLUMN_PRODUCT_NAME);
                      int genericNameCol = 
                   cursor.getColumnIndex(AddNewProductEntry.COLUMN_GENERIC_NAME);
                      int retailPriceCol = 
                    cursor.getColumnIndex(AddNewProductEntry.COLUMN_RETAIL_PRICE);
                      int packSizeCol = cursor.getColumnIndex(AddNewProductEntry.COLUMN_PACK_SIZE);
                      int oneUnitPriceCol = 
                     cursor.getColumnIndex(AddNewProductEntry.COLUMN_ONE_UNIT_PRICE);
        
                      String brandName = cursor.getString(brandNameCol);
                      String genericName = cursor.getString(genericNameCol);
                      Double retailPrice = cursor.getDouble(retailPriceCol);
                      int packSize = cursor.getInt(packSizeCol);
                      Double oneUnitPrice = cursor.getDouble(oneUnitPriceCol);
        
        
                        Intent intent  = new Intent(MainActivity.this, 
                            DisplayOneProductActivity.class);
                        intent.putExtra("name", brandName);
                        intent.putExtra("genericName", genericName);
                        intent.putExtra("retailPrice", retailPrice);
                        intent.putExtra("packSize", packSize);
                        intent.putExtra("oneUnitPrice", oneUnitPrice);
                        startActivity(intent);
                        //finish();
                    }
                });
        
           mSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextSubmit(String query) {
                return false;
            }
        
            @Override
            public boolean onQueryTextChange(String newText) {
        
        
                return false;
            }
        });
        
            }
        
            @Override
            public boolean onCreateOptionsMenu(Menu menu) {
                MenuInflater inflater = getMenuInflater();
                inflater.inflate(R.menu.main_menu, menu);
                return true;
            }
        
            @Override
            public boolean onOptionsItemSelected(MenuItem item) {
                // Handle item selection
                switch (item.getItemId()) {
                    case R.id.add_item:
            //                Toast.makeText(MainActivity.this, "Item is clicked", 
                        Toast.LENGTH_LONG).show();
                        Intent intent = new Intent(this, AddItemActivity.class);
                        startActivity(intent);
                        return true;
                    case R.id.view_cart_menu:
                        Intent cartIntent = new Intent(this, ViewCartActivity.class);
                        startActivity(cartIntent);
                    default:
                        return super.onOptionsItemSelected(item);
                }
        
            }
        
           
        
        }

这是我的AddItemActivity,它正在向数据库中添加一个新项目

                      package com.example.clnicmangmentapp;
        
        import androidx.appcompat.app.AppCompatActivity;
        
        import android.content.ContentValues;
        import android.content.Intent;
        import android.database.sqlite.SQLiteDatabase;
        import android.database.sqlite.SQLiteOpenHelper;
        import android.os.Bundle;
        import android.text.TextUtils;
        import android.view.View;
        import android.widget.AdapterView;
        import android.widget.ArrayAdapter;
        import android.widget.Button;
        import android.widget.EditText;
        import android.widget.Spinner;
        import android.widget.TextView;
        import android.widget.Toast;
        
        import com.example.clnicmangmentapp.data.AddNewProductContract.AddNewProductEntry;
        import com.example.clnicmangmentapp.data.AddNewProductDataBaseHelper;
        
        import java.text.DecimalFormat;
        
        public class AddItemActivity extends AppCompatActivity {
        
        
            private static DecimalFormat df = new DecimalFormat("0.00");
        
            AddNewProductDataBaseHelper mDataBaseHelper;
        
        
            private Button mAddDataBtn;
            private Button mCancleBtn;
        
        
            private EditText mBrandName;
            private EditText mGenericName;
            private EditText mCompanyName;
            private EditText mRetailPrice;
            private EditText mPackSize;
            private TextView mOneUnitPrice;
            private Spinner typeSpinner;
        
        
            private int mSpinnerType = AddNewProductEntry.CAP;
        
        
            @Override
            protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_add_item);
        
                mDataBaseHelper = new AddNewProductDataBaseHelper(this);
        
                mAddDataBtn = findViewById(R.id.add_data_btn);
                mCancleBtn = findViewById(R.id.clear_data_btn);
        
                mBrandName = findViewById(R.id.product_name);
                mGenericName = findViewById(R.id.genric_name);
                mCompanyName = findViewById(R.id.company_name);
                mRetailPrice = findViewById(R.id.retail_price);
                mPackSize = findViewById(R.id.pack_size);
        
        
                typeSpinner = (Spinner) findViewById(R.id.medicine_type);
        
                // for setting spinner to take the value drop down menu
                setSpinner();
        
        
                mAddDataBtn.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        insertData();
                        clearInputs();
                    }
                });
        
        
                mCancleBtn.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        Intent intent = new Intent(AddItemActivity.this, MainActivity.class);
                        startActivity(intent);
                    }
                });
            }
            private void setSpinner(){
        
                // Create an ArrayAdapter using the string array and a default spinner layout
                ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,
                        R.array.medicine_array, android.R.layout.simple_spinner_item);
        // Specify the layout to use when the list of choices appears
                adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        // Apply the adapter to the spinner
                typeSpinner.setAdapter(adapter);
        
                typeSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
                    @Override
                    public void onItemSelected(AdapterView<?> parent, View view, int position, long 
                                   id) {
        
                        String selectedItem = (String) parent.getItemAtPosition(position);
        
                        if(!TextUtils.isEmpty(selectedItem)){
                            if(selectedItem.equals(getString(R.string.cap))){
                                Toast.makeText(AddItemActivity.this, "Cap is clicked", 
                                     Toast.LENGTH_LONG).show();
                                mSpinnerType = AddNewProductEntry.CAP;
                            }else if(selectedItem.equals(getString(R.string.tab))){
                                Toast.makeText(AddItemActivity.this, "Tab is clicked", 
                              Toast.LENGTH_LONG).show();
                                mSpinnerType = AddNewProductEntry.TAB;
                            }else if(selectedItem.equals(getString(R.string.syp))){
                                Toast.makeText(AddItemActivity.this, "Syp is clicked", 
                               Toast.LENGTH_LONG).show();
                                mSpinnerType = AddNewProductEntry.SYP;
                            }else{
                                Toast.makeText(AddItemActivity.this, "Inj is clicked", 
                             Toast.LENGTH_LONG).show();
                                mSpinnerType = AddNewProductEntry.INJ;
                            }
                        }
                    }
        
                    @Override
                    public void onNothingSelected(AdapterView<?> parent) {
        
                    }
                });
        
            }
        
        
            // this method clear all edit text after inter data to database as add button is pressed
            private void clearInputs(){
        
                mBrandName.getText().clear();
                mGenericName.getText().clear();
                mCompanyName.getText().clear();
                mRetailPrice.getText().clear();
                mPackSize.getText().clear();
            }
        
        
            private void insertData(){
        
                String brand_name = mBrandName.getText().toString().toUpperCase().trim();
                String generic_name = mGenericName.getText().toString().toUpperCase().trim();
                String company_name = mCompanyName.getText().toString().toUpperCase().trim();
                String  retail_price = mRetailPrice.getText().toString().trim();
        
                Double retailPrice = Double.parseDouble(retail_price);
        
                String  pack_size = mPackSize.getText().toString().trim();
                int packSize = Integer.parseInt(pack_size);
        
                Double oneUnitPrice = retailPrice/packSize;
        // in this line of code we limiting out put to decimal places like 33.33
               String convertedPrice = df.format(oneUnitPrice);
        
                SQLiteDatabase sqLiteDatabase = mDataBaseHelper.getWritableDatabase();
        
                ContentValues contentValues = new ContentValues();
                contentValues.put(AddNewProductEntry.COLUMN_PRODUCT_NAME, brand_name);
                contentValues.put(AddNewProductEntry.COLUMN_GENERIC_NAME, generic_name);
                contentValues.put(AddNewProductEntry.COLUMN_COMPANY_NAME, company_name);
                contentValues.put(AddNewProductEntry.COLUMN_RETAIL_PRICE, retail_price);
                contentValues.put(AddNewProductEntry.COLUMN_PACK_SIZE, packSize);
                contentValues.put(AddNewProductEntry.COLUMN_TYPE_OF_PRODUCT, mSpinnerType);
                contentValues.put(AddNewProductEntry.COLUMN_ONE_UNIT_PRICE, convertedPrice);
        
                long newRowId = sqLiteDatabase.insert(AddNewProductEntry.TABLE_NAME,null, 
                 contentValues);
                if(newRowId == -1){
                    Toast.makeText(AddItemActivity.this,"Error Inserting Data", 
                    Toast.LENGTH_LONG).show();
                }else{
                    Toast.makeText(AddItemActivity.this,"Data is Inserted Successfully", 
                   Toast.LENGTH_LONG).show();
                }
        
            }
        
        
        }

这是我的 DisplayDataAdapterView

                               package com.example.clnicmangmentapp;
                
                import android.content.Context;
                import android.database.Cursor;
                import android.view.LayoutInflater;
                import android.view.View;
                import android.view.ViewGroup;
                import android.widget.CursorAdapter;
                import android.widget.TextView;
                
                import com.example.clnicmangmentapp.data.AddNewProductContract.AddNewProductEntry;
                
                public class DispalyDataAdapterView extends CursorAdapter {
                
                
                    public DispalyDataAdapterView(Context context, Cursor cursor) {
                        super(context, cursor, 0);
                    }
                
                    @Override
                    public View newView(Context context, Cursor cursor, ViewGroup parent) {
                        return LayoutInflater.from(context).inflate(R.layout.item_view, parent, 
                             false);
                    }
                
                    @Override
                    public void bindView(View view, Context context, Cursor cursor) {
                
                        TextView brandNameTextView = view.findViewById(R.id.brand_name_view);
                        TextView genericNameTextView = view.findViewById(R.id.generic_name_view);
                
                        int brandNameCol = 
                        cursor.getColumnIndex(AddNewProductEntry.COLUMN_PRODUCT_NAME);
                         int genericNameCol = 
                        cursor.getColumnIndex(AddNewProductEntry.COLUMN_GENERIC_NAME);
                
                         String brandName = cursor.getString(brandNameCol);
                         String genericName = cursor.getString(genericNameCol);
                
                         brandNameTextView.setText(brandName);
                         genericNameTextView.setText(genericName);
                
                    }
                
                }

这是我的添加新产品合同

                             package com.example.clnicmangmentapp.data;
            
            import android.provider.BaseColumns;
            
            public class AddNewProductContract {
            
                private AddNewProductContract(){}
            
            
                public static class AddNewProductEntry implements BaseColumns{
            
                    public static final String  TABLE_NAME = "add_new_product";
            
                    public static final String _ID = BaseColumns._ID;
                    public static final String COLUMN_PRODUCT_NAME = "product_name";
                    public static final String COLUMN_GENERIC_NAME = "generic_name";
                    public static final String COLUMN_COMPANY_NAME = "company_name";
                    public static final String COLUMN_RETAIL_PRICE = "retail_price";
                    public static final String COLUMN_PACK_SIZE = "pack_size";
                    public static final String COLUMN_TYPE_OF_PRODUCT = "product_type";
                    public static final String COLUMN_ONE_UNIT_PRICE = "one_unit_price";
            
            
            
                    public static final int CAP = 100;
                    public static final int TAB = 101;
                    public static final int SYP = 102;
                    public static final int INJ = 103;
                }
            
                public static class AddItemToCart implements BaseColumns{
            
                    public static final String TABLE_CART = "add_to_cart";
            
                    public static final String _CART_ID = BaseColumns._ID;
                    public static final String COLUMN_CART_PRODUCT_NAME = "cart_product_name";
                    public static final String COLUMN_CART_QUANTITY = "cart_product_quantity";
                    public static final String COLUMN_CART_PRICE = "cart_product_price";
                    public static final String COLUMN_CART_TOTAL_PRICE = "cart_total_price";
                }
            }

这是我的数据库助手类

                            package com.example.clnicmangmentapp.data;
        
        import android.content.Context;
        import android.database.sqlite.SQLiteDatabase;
        import android.database.sqlite.SQLiteOpenHelper;
        import com.example.clnicmangmentapp.data.AddNewProductContract.AddNewProductEntry;
        import com.example.clnicmangmentapp.data.AddNewProductContract.AddItemToCart;
        import androidx.annotation.Nullable;
        
        public class AddNewProductDataBaseHelper extends SQLiteOpenHelper {
        
            private static final String DATABASE_NAME = "products";
        
            private static final int DATABASE_VERSION = 1;
        
            public AddNewProductDataBaseHelper(Context context) {
                super(context, DATABASE_NAME, null, DATABASE_VERSION);
            }
        
        
            @Override
            public void onCreate(SQLiteDatabase db) {
        
                String CREATE_TABLE_ENTITIES =  "CREATE TABLE " + AddNewProductEntry.TABLE_NAME + "("
                        + AddNewProductEntry._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
                        + AddNewProductEntry.COLUMN_PRODUCT_NAME + " TEXT, "
                        + AddNewProductEntry.COLUMN_GENERIC_NAME + " TEXT, "
                        + AddNewProductEntry.COLUMN_COMPANY_NAME + " TEXT, "
                        + AddNewProductEntry.COLUMN_RETAIL_PRICE + " REAL, "
                        + AddNewProductEntry.COLUMN_PACK_SIZE + " INTEGER, "
                        + AddNewProductEntry.COLUMN_TYPE_OF_PRODUCT + " INTEGER, "
                        + AddNewProductEntry.COLUMN_ONE_UNIT_PRICE + " REAL )" ;
        
        
        
                String CREATE_CART_TABLE = "CREATE TABLE " + AddItemToCart.TABLE_CART + "("
                        + AddItemToCart._CART_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
                        + AddItemToCart.COLUMN_CART_PRODUCT_NAME + " TEXT, "
                        + AddItemToCart.COLUMN_CART_QUANTITY + " INTEGER, "
                        + AddItemToCart.COLUMN_CART_PRICE + " REAL, "
                        + AddItemToCart.COLUMN_CART_TOTAL_PRICE + " REAL )";
        
                db.execSQL(CREATE_TABLE_ENTITIES);
                db.execSQL(CREATE_CART_TABLE);
            }
        
            @Override
            public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        
                 String DROP_TABLE_PRODUCTS = " DROP TABLE IF EXISTS " + 
                 AddNewProductEntry.TABLE_NAME;
                  String DROP_TABLE_ADD_TO_CART = " DROP TABLE IF EXISTS " + 
                      AddItemToCart.TABLE_CART;
        
                 db.execSQL(DROP_TABLE_PRODUCTS);
                db.execSQL(DROP_TABLE_ADD_TO_CART);
                onCreate(db);
            }
        }

这是我的列表视图 xml 文件

                         <?xml version="1.0" encoding="utf-8"?>
        <LinearLayout
            xmlns:android="http://schemas.android.com/apk/res/android"
            xmlns:app="http://schemas.android.com/apk/res-auto"
            xmlns:tools="http://schemas.android.com/tools"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical"
            tools:context=".MainActivity">
        <EditText
            android:id="@+id/search_view"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="Enter Your Search"
            android:padding="8dp"
            android:layout_marginBottom="4dp">
        
        </EditText>
        
        <ListView
            android:id="@+id/list_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>
        
        </LinearLayout>

这是我的列表项布局 xml

                               <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
    
        <TextView
            android:id="@+id/brand_name_view"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:padding="8dp"
            android:text="@string/brand_name"
            android:textSize="18sp"/>
    
        <TextView
            android:id="@+id/generic_name_view"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textSize="16sp"
            android:text="Generic Name"
            android:paddingLeft="8dp"/>
    
    </LinearLayout>

请帮忙解决这个问题

我尝试了这段代码,现在它可以工作了

         android.database.StaleDataException: Attempting to access a closed 
       CursorWindow.Most probable cause: cursor is deactivated prior to 
         calling this method.
                     at 

                      android.database.AbstractWindowedCursor.
                  checkPosition(AbstractWindowedCursor.java :141)
                  at 
                 android.database.AbstractWindowedCursor.
                getString(AbstractWindowedCursor.java:52)
                 at 

                 com.example.clnicmangmentapp.MainActivity$3.
                   onItemClick(MainActivity.java:97)

这是我尝试的代码

     adapter.setFilterQueryProvider(new FilterQueryProvider() {
        @Override
        public Cursor runQuery(CharSequence constraint) {

            String search = constraint.toString();
            String searchResult = (" SELECT * FROM " +
                    AddNewProductEntry.TABLE_NAME + " WHERE " + 
            AddNewProductEntry.COLUMN_PRODUCT_NAME + " LIKE '%" + search + 
           "%'");
            return database.rawQuery(searchResult, null);
        }
    });
    mSearchEditText.addTextChangedListener(new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, 
          int after) {

        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int 
         count) {
            adapter.getFilter().filter(s);
            // Don't forget to notify the adapter
            adapter.notifyDataSetChanged();
        }

        @Override
        public void afterTextChanged(Editable s) {

        }
    });

我在这里为另一个代码工作,这是工作代码 它可以过滤数据,但数据不只显示空列表,但是当我点击一个项目时,它会显示正确的数据

        public void showSearch(String search){

        String searchQuery = (" SELECT * FROM " +
            AddNewProductEntry.TABLE_NAME + " WHERE " +
            AddNewProductEntry.COLUMN_PRODUCT_NAME + " LIKE '%" + search + 
         "%'");

    cursor = database.rawQuery(searchQuery, null);

    SimpleCursorAdapter adapterSimple = new 
   SimpleCursorAdapter(MainActivity.this, 
      android.R.layout.simple_list_item_2, cursor,
             new String[] {AddNewProductEntry.COLUMN_PRODUCT_NAME, 
         AddNewProductEntry.COLUMN_GENERIC_NAME},
            new int[] {R.id.brand_name_view, R.id.generic_name_view},
            0);
    listView.setAdapter(adapterSimple);
    adapterSimple.notifyDataSetChanged();

}

我像这样在我的 mSearchEditText 中使用这个函数

             mSearchEditText.addTextChangedListener(new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, 
               int after) {

        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int 
              count) {
            String search = s.toString();
             showSearch(search);
        }

        @Override
        public void afterTextChanged(Editable s) {

        }
    });
  

当我键入一个单词时,此代码正在工作并过滤数据,但它显示空列表,当我单击此列表时,它会显示该列表项的数据。

【问题讨论】:

  • 所以您的数据显示正确并且一切正常,但是您需要一种使用 SearchView 过滤数据的方法吗?
  • 尝试使用RecyclerView 而不是ListView,因为 RV 是更高级的列表视图
  • 阿里开斋节你是对的,我的数据显示正确,一切都很好,只是想知道如何过滤这些数据

标签: java android


【解决方案1】:

由于我已经使用 DisplayDataAdpaterView 显示数据列表,所以我使用了这个方法并在我的 editText 搜索方法中使用了这个方法

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            String search = s.toString();
             showSearch(search);
        }

此方法从数据库中搜索结果并绑定视图并显示为列表视图

  public void showSearch(String search){

    String searchQuery = (" SELECT * FROM " +
            AddNewProductEntry.TABLE_NAME + " WHERE " +
            AddNewProductEntry.COLUMN_PRODUCT_NAME + " LIKE '%" + search + "%'");

    cursor = database.rawQuery(searchQuery, null);

    // so this is the DisplayAdpater which already displaying data
    // so we use this adapter to show search in a list view
    adapter = new DispalyDataAdapterView(this,cursor);
    listView.setAdapter(adapter);
    adapter.notifyDataSetChanged();
}

【讨论】:

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