2017-05-17 3 views
0

初めてこのサイトで質問しましたが、
というサイトを使って、私のプロジェクトを作る過程で他の多くの問題を解決しました。 Udacity。OnClickがSQLiteデータベースの値を変更した後、CursorAdapterでListViewを更新しますか?

私はSQLiteデータベースにアイテムを保存して表示するインベントリアプリケーションを持っていますが、すべてのアイテムとペアになっているセールボタンを除いてすべての機能が完了しています。 Here is a screenshot, including the sale button

[販売]ボタンは現在、データベースの数量を1減らしますが、スクリーンショットにも含まれるリストビュー数は更新されません。項目をクリックして詳細を入力すると更新される唯一の方法ですアイテム画面を表示し、戻るボタンを押します。

は、私の答えは私の再探索からchangeCursor()またはnotifyDataSetChanged()のいずれかであると考えているが、私は何の効果に私のコードに適用することができませんでした。

ItemCursorAdapter

public ItemCursorAdapter(Context context, Cursor c) { 
    super(context, c, 0); 
} 


@Override 
public View newView(Context context, Cursor cursor, ViewGroup parent) { 

    return LayoutInflater.from(context).inflate(R.layout.list_layout, parent, false); 
} 

@Override 

public void bindView(final View view, final Context context, final Cursor mCursor) { 
    TextView itemName = (TextView) view.findViewById(R.id.list_item_name); 
    TextView itemQty = (TextView) view.findViewById(R.id.list_ItemQty); 
    TextView locText = (TextView) view.findViewById(R.id.list_ItemLocation); 
    TextView priceText = (TextView) view.findViewById(R.id.list_ItemPrice); 
    final Button saleButton = (Button) view.findViewById(R.id.list_salebutton); 
    //get values from cursor 

    int nameColumnIndex = mCursor.getColumnIndex(DBhelper.KEY_NAME); 
    int qtyColumnIndex = mCursor.getColumnIndex(DBhelper.KEY_QUANTITY_HAVE); 
    int locColumnIndex = mCursor.getColumnIndex(DBhelper.KEY_LOCATION); 
    int priceColumnIndex = mCursor.getColumnIndex(DBhelper.KEY_QUANTITY_WANT); 
    int idColumnIndex = mCursor.getColumnIndex(DBhelper.KEY_ID); 
    //Populate fields with values 
    String itemNameString = mCursor.getString(nameColumnIndex); 
    QUANTITY_HAVESTRING = mCursor.getString(qtyColumnIndex); 
    String locationString = mCursor.getString(locColumnIndex); 
    String priceString = mCursor.getString(priceColumnIndex); 
    SELECTEDITEM_SOLD_BUTTON = mCursor.getString(idColumnIndex); 

    //Adds tags to the Sale Buttons as they are created, Quantity and ID 
    saleButton.setTag(R.id.tagQuantity, mCursor.getString(qtyColumnIndex)); 
    saleButton.setTag(R.id.tagID, mCursor.getString(idColumnIndex)); 


    itemName.setText(itemNameString); 
    itemQty.setText(QUANTITY_HAVESTRING); 
    locText.setText(locationString); 
    priceText.setText("$" + priceString); 

    saleButton.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      String tagID = (String) saleButton.getTag(R.id.tagID); 
      String tagQuantity = (String) saleButton.getTag(R.id.tagQuantity); 



      if (Integer.parseInt(tagQuantity) > 0) { 
       DBhelper mDBhelper = new DBhelper(mContext); 
       SQLiteDatabase db = mDBhelper.getWritableDatabase(); 

       ContentValues values = new ContentValues(); 
       values.put(DBhelper.KEY_QUANTITY_HAVE, (Integer.parseInt(tagQuantity) - 1)); 
       db.update(DBhelper.TABLE_INVENTORY, values, "_id = " + tagID, null); 

       Toast.makeText(mContext, itemAdapter.toString(), Toast.LENGTH_SHORT).show(); 

       itemAdapter.changeCursor(mCursor); 
       itemAdapter.notifyDataSetChanged(); 



      } 
     } 
    }); 


    //todo add on destroy db close 

    } 

} 

MainActivity

public class MainActivity extends AppCompatActivity { 

    private DBhelper mDBhelper; 
    public Cursor cursor; 
    public static ItemCursorAdapter itemAdapter; 
    public static ListView lvItems; 

    // ON CREATE 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     mDBhelper = new DBhelper(this); 


    } 


    // ON CREATE OPTIONS MENU 
    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     // Inflate the menu options from the res/menu/menu_catalog.xml file. 
     // This adds menu items to the app bar. 
     getMenuInflater().inflate(R.menu.inventory_menu_main, menu); 
     return true; 
    } 

    //ACTION BAR MENU when clicked 
    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 

     SQLiteDatabase db = mDBhelper.getWritableDatabase(); 
     // User clicked on a menu option in the app bar overflow menu 
     switch (item.getItemId()) { 


      // Respond to a click on the "Delete all entries" menu option 
      case R.id.action_delete_all_entries: 


       db.delete(DBhelper.TABLE_INVENTORY, null, null); 
       onStart(); 
       return true; 
//Populate Standard Items, that the app is primarily designed to track. 
      case R.id.action_add_standard_entries_entries: 

       String[] INSERT_ROWS = getResources().getStringArray(R.array.artilleryEquipmentRows); 


       for (int i = 0; i < 33; i++) 
        db.execSQL(INSERT_ROWS[i]); 
       onStart(); 
       return true; 


//ABOUT APP INFO 
      case R.id.action_display_appInfo: 

       AlertDialog aboutDialog = new AlertDialog.Builder(MainActivity.this).create(); 
       aboutDialog.setTitle(MainActivity.this.getString(R.string.aboutDialogTitle)); 
       aboutDialog.setMessage(MainActivity.this.getString(R.string.aboutDialogMessage)); 
       //TODO set a icon 
       aboutDialog.setButton(AlertDialog.BUTTON_NEUTRAL, MainActivity.this.getString(R.string.confirmDialogOk), 
         new DialogInterface.OnClickListener() { 
          @Override 
          public void onClick(DialogInterface dialog, int which) { 
           dialog.dismiss(); 

          } 


         }); 
       aboutDialog.show(); 
       return true; 


      // Add new Item Button (Shows up as a + sign) 
      case R.id.action_additem: 
       Intent intent = new Intent(MainActivity.this, AddItemActivity.class); 
       startActivity(intent); 

       return true; 
     } 
     return super.onOptionsItemSelected(item); 
    } 

    @Override 
    protected void onStart() { 
     super.onStart(); 
     displayDatabaseInfo(); 
    } 


    // Populates the list 
    public void displayDatabaseInfo() { 
     // Create and/or open a database to read from it 
     SQLiteDatabase db = mDBhelper.getReadableDatabase(); 

     // Define a projection that specifies which columns from the database 
     // you will actually use after this query. 

     String[] projection = { 
       DBhelper.KEY_ID, 
       DBhelper.KEY_NAME, 
       DBhelper.KEY_QUANTITY_HAVE, 
       DBhelper.KEY_QUANTITY_WANT, 
       DBhelper.KEY_LOCATION, 
       DBhelper.KEY_ISSUED_BOOLEAN}; 

     // Perform a query on the pets table 
     cursor = db.query(
       DBhelper.TABLE_INVENTORY, // The table to query 
       projection,   // The columns to return 
       null,     // The columns for the WHERE clause 
       null,     // The values for the WHERE clause 
       null,     // Don't group the rows 
       null,     // Don't filter by row groups 
       null);     // The sort order 

     ListView lvItems = (ListView) findViewById(R.id.main_list_view); 
     itemAdapter = new ItemCursorAdapter(this, cursor); 
     lvItems.setAdapter(itemAdapter); 


//Assigns Empty View for when no items in Database 
     View emptyView = findViewById(R.id.empty_view); 
     lvItems.setEmptyView(emptyView); 

     lvItems.setOnItemClickListener(new AdapterView.OnItemClickListener() { 
      @Override 
      public void onItemClick(AdapterView<?> parent, View view, int position, long passID) { 


       Intent intent = new Intent(MainActivity.this, AddItemActivity.class); 
       intent.putExtra("itemPosition", passID); 
       startActivity(intent); 
      } 
     }); 

    } 


    //Closes the cursor on app termination 
    @Override 
    protected void onDestroy() { 
     super.onDestroy(); 
     cursor.close(); 
     Log.d("tag", "Cursor(MainActivity) Closed"); 
    } 
} 
+0

'ItemCapterAdapter'内の' itemAdapter' – Saurabh

+0

MainActivityをグローバル静的変数から作成しようとしましたが、CursorAdapterからアクセスできました。これは私の問題でしょうか?私は解決策としてこれを行うように思われた別の投稿を見つけました。 –

+0

クラス間で値を共有するために 'static'を使うべきではありません。むしろ 'static'変数は、単一のクラスのすべてのインスタンスに対して同じ値を与えることを意図しています。この場合、それぞれの 'MainActivity'インスタンスは独自の' CursorAdapter'インスタンスを持っているはずなので、staticは不適切です。 –

答えて

0

0123に

itemAdapter.changeCursor(mCursor); 
itemAdapter.notifyDataSetChanged(); 

を変更してみてください

changeCursor(mCursor); 
notifyDataSetChanged(); 

うまくいくはずです。

+0

まだ動作しませんが、私は変更を維持します –

0

私は多少それを解決しました、プロジェクトに入るのに十分です。

saleButton.setOnClickListener(new View.OnClickListener() { 
    @Override 
    public void onClick(View v) { 

     TextView itemQty = (TextView) view.findViewById(R.id.list_ItemQty); 
     String itemQtyString = itemQty.getText().toString(); 
     int itemQtyInt = Integer.parseInt(itemQtyString); 

     String tagID = (String) saleButton.getTag(R.id.tagID); 
     String tagQuantity = (String) saleButton.getTag(R.id.tagQuantity); 


     if (itemQtyInt > 0) { 

      itemQtyInt = itemQtyInt - 1; 

      itemQtyString = Integer.toString(itemQtyInt); 
      DBhelper mDBhelper = new DBhelper(mContext); 
      SQLiteDatabase db = mDBhelper.getWritableDatabase(); 

      ContentValues values = new ContentValues(); 
      values.put(DBhelper.KEY_QUANTITY_HAVE, itemQtyInt); 
      db.update(DBhelper.TABLE_INVENTORY, values, "_id = " + tagID, null); 

      itemQty.setText(itemQtyString); 
0

onClick()のコードはItemCursorAdapter内部にあるので、あなただけの現在のカーソルを再利用できるので、あなたはchangeCursor()を呼び出す必要はありません

notifyDataSetChanged(); 

を呼び出す必要があります。

+0

ありがとう、おそらく最も効率的な方法ではないにしても、私は問題を解決しました。興味深いことに、notifyDataSetChanged();それはそれが必要とするように働くことを妨げる。 –

+0

@NicholasCherryholmesあなたは 'notifyDataSetChanged()'または 'changeCursor()'を実行する必要がありますが、両方を行うべきではありません。 –

0

私もコースをやっていて、同じ問題が発生しました。私は別のルートに行きましたが、もう少しエレガントでしょうか?そのテクニックは、TextViewテキストを使用して数量値を取得することです。

これは私のカスタムCursorAdapterからである:

// Quantity Button 
    ImageButton button = (ImageButton) view.findViewById(R.id.sales_button); 
    // Get the current items ID 
    int currentId = cursor.getInt(cursor.getColumnIndex(InventoryEntry._ID)); 
    // Make the content uri for the current Id 
    final Uri contentUri = Uri.withAppendedPath(InventoryEntry.CONTENT_URI, Integer.toString(currentId)); 

    // Change the quantity when you click the button 
    button.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      TextView quantityView = (TextView) view.findViewById(R.id.quantity); 
      int quantity = Integer.valueOf(quantityView.getText().toString()); 

      if (quantity > 0) { 
       quantity = quantity - 1; 
      } 
      // Content Values to update quantity 
      ContentValues values = new ContentValues(); 
      values.put(InventoryEntry.COLUMN_QUANTITY, quantity); 

      // update the database 
      context.getContentResolver().update(contentUri, values, null, null); 
     } 
    }); 

あなたは、アダプタの変更を通知しますがすることになっているとして、プロバイダでそれを行うと、変化にmAdapter.swapCursor()関数を使用していませんMainActivityのLoaderManagerコールバック内のカーソル。

関連する問題