简体   繁体   English

如何根据第一个微调器中的选择从数据库中过滤第二个微调器值?

[英]How to filter second spinner values from database on the basis of selection made in the first spinner?

I am setting a new activity named Dispatch Report, which has two Spinners: CustomerSpinner and LotSpinner.我正在设置一个名为 Dispatch Report 的新活动,它有两个 Spinner:CustomerSpinner 和 LotSpinner。

LotSpinner shows all Lots in Dispatch Table instead of showing only those Lots which are related to the Customer selected in the first Spinner. LotSpinner 在调度表中显示所有批次,而不是仅显示与在第一个 Spinner 中选择的客户相关的批次。

I have fetched CustomerSpinner Value from Dispatch Table.我从调度表中获取了 CustomerSpinner 值。 In LotSpinner also fetched Lot numbers from Dispatch Table, but not Filtered according to customer selection.在 LotSpinner 中,也从 Dispatch Table 中获取批号,但未根据客户选择进行过滤。

DispatchReportActivity.Java DispatchReportActivity.Java

// Fetching customer from dispatch table  
private void loadCustomerNameDispatch() {
    DatabaseHelper db = new DatabaseHelper( getApplicationContext() );

        List<String> lables1 = db.getFirmNAmeMoveStock();
        ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(this,
                android.R.layout.simple_spinner_item, lables1);
        dataAdapter           .setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        // attaching data adapter to spinner
        spinCustomer.setAdapter(dataAdapter);
        spinCustomer.setOnItemSelectedListener(this);
    }

// Fetching lot from dispatch table
    private void loadLotbyCustomerDispatch() {
        // database handler
        DatabaseHelper db = new DatabaseHelper(getApplicationContext());
        // Spinner Drop down elements
        List<String> lables = db.getLotbyCustomer();
        // Creating adapter for spinner
        ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(this,
                android.R.layout.simple_spinner_item, lables);
        // Drop down layout style - list view with radio button
        dataAdapter
                .setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        // attaching data adapter to spinner
        spinLotbyCustomer.setAdapter(dataAdapter);
    }

DATABASEHELPER.Java数据库助手

//Get firm name in Dispatch Stock Report screen
public List < String > getFirmNAmeMoveStock() {
    List < String > labels = new ArrayList < String > ();

    // Select all query
    String selectQuery = "SELECT * FROM " + Table_Inventory;
    SQLiteDatabase db = this.getReadableDatabase();
    Cursor cursor = db.rawQuery(selectQuery, null);

    // Looping through all rows and adding to list
    if (cursor.moveToFirst()) {
        do {
            labels.add(cursor.getString(3));
            Set < String > set = new HashSet < >(labels);
            labels.clear();
            labels.addAll(set);
        } while ( cursor . moveToNext ());
    }

    // Closing connection
    cursor.close();
    db.close();

    // Returning lables
    return labels;
}

// Method to get Lot No. in Dispatch Stock Report Activity
public List < String > getLotbyCustomer() {
    List < String > labels1 = new ArrayList < String > ();

    // Select all query
    String selectQuery = "SELECT * FROM " + Table_StockDispatch;
    SQLiteDatabase db = this.getReadableDatabase();
    Cursor cursor = db.rawQuery(selectQuery, null);

    // looping through all rows and adding to list
    if (cursor.moveToFirst()) {
        do {
            labels1.add(cursor.getString(4));
            Set < String > set = new HashSet < >(labels1);
            labels1.clear();
            labels1.addAll(set);
        } while ( cursor . moveToNext ());
    }

    // Closing connection
    cursor.close();
    db.close();

    // Returning lables
    return labels1;
}

There will be multiple customers, and each customer could have multiple Lots, so I want the second spinner to show only those Lots which are relevant to the customer selected in the first Spinner.将有多个客户,每个客户可以有多个批次,因此我希望第二个微调器仅显示与第一个微调器中选择的客户相关的那些批次。

I'd suggest utilising Cursor's and Cursor adapters which can make matter simpler as :-我建议使用 Cursor's 和 Cursor 适配器,这可以使事情变得更简单:-

  • there is no need for intermediate arrays (one of your issues is that String arrays do not provide sufficient information)不需要中间数组(您的问题之一是字符串数组没有提供足够的信息)
  • CursorAdapters are designed to handle id (albiet a requirement that these exists in the Cursor with the column name _id (see the use of BaseColumns._ID below)). CursorAdapters旨在处理id (尽管要求这些存在于 Cursor 中,列名称为_id (请参阅下面的BaseColumns._ID的使用))。

The following is a basic example of related spinners based loosely upon your requirements.以下是相关微调器的基本示例,该示例松散地基于您的要求。

First the DatbaseHelper DatabaseHelper.java首先是DatabaseHelper DatabaseHelper.java

Two tables are defined/created Customers and Lots, methods to add data for each exist as do methods to extract a list from each of the tables.两个表是定义/创建的客户和批次,存在为每个表添加数据的方法以及从每个表中提取列表的方法。 The lots extracted are based upon the customer to which they reference/belong to/associate with.提取的批次基于他们参考/属于/关联的客户。

public class DatabaseHelper extends SQLiteOpenHelper {

    public static final String DBNAME = "mydb";
    public static final int DBVERSION = 1;
    public static final String TBL_CUSTOMER = "customer";
    public static final String TBL_LOT = "lot";


    public static final String COL_CUSTOMER_ID = BaseColumns._ID; //<<<<<<<<<< column name is _id (needed for Cursor Adapter)
    public static final String COL_CUSTOMER_NAME = "customer_name";

    public static final String COL_LOT_ID = BaseColumns._ID; //<<<<<<<<<< column name is _id (needed for Cursor Adapter)
    public static final String COL_LOT_NAME = "lot_name";
    public static final String COL_LOT_CUSTOMERREFERENCE = "customer_refererence";

    SQLiteDatabase mDB;

    public DatabaseHelper(Context context) {
        super(context, DBNAME, null, DBVERSION);
        mDB = this.getWritableDatabase(); //<<<<<<<<<< get the database connection (force create when constructing helper instance)
    }

    @Override
    public void onCreate(SQLiteDatabase db) {

        String crt_customer_table_sql = "CREATE TABLE IF NOT EXISTS " + TBL_CUSTOMER + "(" +
                COL_CUSTOMER_ID + " INTEGER PRIMARY KEY, " +
                COL_CUSTOMER_NAME + " TEXT UNIQUE " +
                ")";

        String crt_lot_table_sql = "CREATE TABLE IF NOT EXISTS " + TBL_LOT + "(" +
                COL_LOT_ID + " INTEGER PRIMARY KEY, " +
                COL_LOT_NAME + " TEXT, " +
                COL_LOT_CUSTOMERREFERENCE + " INTEGER " +
                /*?????????? OPTIONAL IF FOREIGN KEYS ARE TURNED ON
                "REFERENCES " + TBL_CUSTOMER + "(" +
                COL_CUSTOMER_ID +
                ")" +
                */
                ")";
        db.execSQL(crt_customer_table_sql);
        db.execSQL(crt_lot_table_sql);

    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }

    public long addCustomer(String name) {
        ContentValues cv = new ContentValues();
        cv.put(COL_CUSTOMER_NAME,name);
        return mDB.insert(TBL_CUSTOMER,null,cv);
    }

    public long addLot(String name, long customer_reference) {
        ContentValues cv = new ContentValues();
        cv.put(COL_LOT_NAME,name);
        cv.put(COL_LOT_CUSTOMERREFERENCE,customer_reference);
        return mDB.insert(TBL_LOT,name,cv);
    }

    public Cursor getCustomers() {
        return mDB.query(TBL_CUSTOMER,null,null,null,null,null,COL_CUSTOMER_NAME);
    }

    public Cursor getLotsPerCustomer(long customer_id) {
        String whereclause = COL_LOT_CUSTOMERREFERENCE + "=?";
        String[] whereargs = new String[]{String.valueOf(customer_id)};
        return mDB.query(TBL_LOT,null,whereclause,whereargs,null,null,COL_LOT_NAME);
    }
}
  • Note the above is pretty straight-forward.请注意,上面的内容非常简单。 However, it would obviously need to be adapted to suit you App.但是,它显然需要进行调整以适合您的应用程序。

The second code is the activity that utilises the above and incorporates the 2 linked/related spinners where the selectable Lots are as per those lots associated with the currently selected customer.第二个代码是利用上述代码并结合 2 个链接/相关微调器的活动,其中可选批次与当前所选客户相关的批次相同。

The layout used for the activity is very basic, it just has two spinners.用于活动的布局非常基本,它只有两个微调器。 The spiners use the stock Simple_List_Item_2 layout (2 has been used to allow the all important ID's to be viewed (typically the user would not be shown the ID's)). Spiners 使用库存 Simple_List_Item_2 布局(2 已用于允许查看所有重要的 ID(通常不会向用户显示 ID))。

In short whenever a selection is made in the Customer spinner the Lot spinner is managed (setup or refreshed) based upon the customer id which is used to select the related/reference lots.简而言之,每当在客户微调器中进行选择时,都会根据用于选择相关/参考批次的客户 ID 来管理(设置或刷新)批次微调器。

public class MainActivity extends AppCompatActivity {

    Context mContext;
    DatabaseHelper mDBHlpr;
    SimpleCursorAdapter mCustomerSCA, mLotSCA;
    Spinner mCustomerList, mLotList;
    Cursor mCustomers, mLots;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mContext = this;
        mDBHlpr = new DatabaseHelper(this);
        mCustomerList = this.findViewById(R.id.customer_list);
        mLotList = this.findViewById(R.id.lot_list);

        addTestingDataIfNoData(); //Go and add some testing data if there is none
        manageCustomerSpinner();
    }

    private void manageCustomerSpinner() {
        mCustomers = mDBHlpr.getCustomers();
        if (mCustomerSCA == null) {
            mCustomerSCA = new SimpleCursorAdapter(
                    this,
                    android.R.layout.simple_list_item_2,
                    mCustomers,
                    new String[]{
                            DatabaseHelper.COL_CUSTOMER_NAME,
                            DatabaseHelper.COL_CUSTOMER_ID
                    },
                    new int[]{
                            android.R.id.text1,
                            android.R.id.text2
                    },
                    0
            );
            mCustomerList.setAdapter(mCustomerSCA);

            mCustomerList.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
                @Override
                public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                    manageLotSpinner(id); //<<<<<<<<<< WHENEVER CUSTOMER IS SELECTED THE LOT SPINNER IS MANAGED >>>>>>>>>>
                }

                @Override
                public void onNothingSelected(AdapterView<?> parent) {

                }
            });
        } else {
            mCustomerSCA.swapCursor(mCustomers);
        }
    }

    private void manageLotSpinner(long id) {
        mLots = mDBHlpr.getLotsPerCustomer(id);
        if (mLotSCA == null) {
            mLotSCA = new SimpleCursorAdapter(
                    this,
                    android.R.layout.simple_list_item_2,
                    mLots,
                    new String[]{
                            DatabaseHelper.COL_LOT_NAME,
                            DatabaseHelper.COL_LOT_ID
                    },
                    new int[]{
                            android.R.id.text1,
                            android.R.id.text2
                    },
                    0
            );
            mLotList.setAdapter(mLotSCA);
        } else {
            mLotSCA.swapCursor(mLots);
        }
    }


    private void addTestingDataIfNoData() {
        if (DatabaseUtils.queryNumEntries(mDBHlpr.getWritableDatabase(),DatabaseHelper.TBL_CUSTOMER) < 1) {
            mDBHlpr.addCustomer("Fred");
            mDBHlpr.addCustomer("Mary");
            mDBHlpr.addCustomer("Sue");
            mDBHlpr.addCustomer("Alan");

            mDBHlpr.addLot("Lot001",2); // Lot for mary
            mDBHlpr.addLot("Lot002",1); // Lot for fred
            mDBHlpr.addLot("Lot003",4); // Lot for ala
            mDBHlpr.addLot("Lot004",3); // Lot for sue
            mDBHlpr.addLot("Lot005",3); // Lot for sue
            mDBHlpr.addLot("Lot006",3); // Lot for use
            mDBHlpr.addLot("Lot007",2); // Lot for mary
            mDBHlpr.addLot("Lot008",2); // Lot for mary
            mDBHlpr.addLot("Lot009",2); // Lot for mary
            mDBHlpr.addLot("Lot0010",2); // Lot for mary
            mDBHlpr.addLot("Lot0020",1); // Lot for Fred
            mDBHlpr.addLot("Lot00130",4); // Lot for Alan
            mDBHlpr.addLot("Lot00130",3); // Lot for Sue
        }
    }
}  

Result Example结果示例

Initial最初的

在此处输入图片说明

  • Alan is initial selection due to sort order由于排序顺序,Alan 是初始选择

After Selecting Mary选择玛丽后

在此处输入图片说明

  • Note Lot names, as used, are not really suited to sorting注意 使用的批次名称并不真正适合分类

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM