can anyone help me with changing the name of the item in listview? I don't have an idea how to do it. I am using SQLite database and this is my update name:
public void doneName(String finishedName,int id, String oldName)
{
SQLiteDatabase db = this.getWritableDatabase();
String query = "UPDATE " + TABLE_NAME + " SET " + COL2 + " = '" + finishedName + "' WHERE " + COL1 +
" = '" + id + "'" + " AND " + COL2 + " = '" + oldName + "'";
db.execSQL(query );
}
after that in my activity I have set onItemClickListener where it should change name but it does not, it only shows toast:
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String name = parent.getItemAtPosition(position).toString();
Cursor cursor =th.getItemID(name);
int itemID = -1;
while(cursor.moveToNext())
{
itemID = cursor.getInt(0);
}
if(itemID>-1) {
String item = "Done";
th.doneName(item, selectedID, selectedName);
Toast.makeText(HomePageActivity.this, "You have accomplished this task!", Toast.LENGTH_SHORT).show();
}}
});
I'm afraid you don't update the instance of the relevant adapter item.
If you have a list of Strings that attached with this ListView Adapter you should initialize the String item at the relevant position with the name you want to show. Then call Adapter.notifyDataSetChanged to refresh all UI elements in the ListView with the updated list.
It seems, that you never update the String instance in your Adapter list
You issue is two-fold.
First you are not extracting the updated data from the database (you could assume that the underlying data has been update bit that is risky).
You are not refreshing the Listview with the changes, so it shows the data it knows about.
I'd suggest utilising a CursorAdapter which can simplify matters as Cursor Adapters are designed for use with Cursors and they especially make all data readily available via the adpater as the Cursor is typically positioned at the appropriate row (e.g. when using onItemClick and onItemLongClick)
The following is an example based upon your code that utilises the SimpleCursorAdapter changing the database and the listview when an item in the list is clicked (to demostrate clicking the same row instead of changing the test to Done it reverses the text so it will will flip for each click).
However, to use a Cursor Adapoter you MUST have a column named _id and that column should be a unique integer (should really be a long rather than int) and typically it would be an alias of the rowid (i.e. defined using _id INTEGER PRIMARY KEY (with or without AUTOINCREMENT, best without)). As such there is a constant BaseColumns._ID that contains the value _id.
First the DatabaseHelper (subclass of SQLiteOpenHelper) in this case DatabaseHelper.java :-
public class DatabaseHelper extends SQLiteOpenHelper {
public static final String DBNAME = "mydb";
public static final int DBVERSION = 1;
public static final String TABLE_NAME = "mytable";
/*<<<<<<<<<< id column must be _id (BaseColumns._ID) for Cursor Adapters >>>>>>>>>*/
public static final String COLID = BaseColumns._ID;
public static final String COL1 = "mycol1";
public static final String COL2 = "mycol2";
public DatabaseHelper(#Nullable Context context) {
super(context, DBNAME, null, DBVERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE IF NOT EXISTS " + TABLE_NAME + "(" +
COLID + " INTEGER PRIMARY KEY, " +
COL1 + " TEXT, " +
COL2 + " TEXT " +
")"
);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
public long insert(String col1, String col2) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues cv = new ContentValues();
cv.put(COL1,col1);
cv.put(COL2,col2);
return db.insert(TABLE_NAME,null,cv);
}
public int doneName(String finishedName,int id, String oldName) {
/*
Alternative using the update convenience method
Based upon :-
String query = "UPDATE " + TABLE_NAME + " SET " + COL2 + " = '" + finishedName + "' WHERE " + COL1 +
" = '" + id + "'" + " AND " + COL2 + " = '" + oldName + "'";
writes the SQL for you.
protects against SQL Injection
returns the number of rows updated
*/
SQLiteDatabase db = this.getWritableDatabase();
ContentValues cv = new ContentValues();
cv.put(COL2,finishedName);
return db.update(TABLE_NAME,cv,COLID + "=? AND " + COL2 + "=?",new String[]{String.valueOf(id),oldName});
}
public Cursor getAll() {
SQLiteDatabase db = this.getWritableDatabase();
return db.query(TABLE_NAME,null,null,null,null,null,null);
}
}
Three custom methods insert (inserts a row), getAll (returns a Cursor with all the rows) and your doneName method (rewritten to take advantage the the update convenience method).
You may notice the absence of any methods to convert extracted data into a List/ArrayList/Array of objects. This is because there is no need when using a Cursor adapter.
The activity MainActivity.java
public class MainActivity extends AppCompatActivity {
ListView mListView;
DatabaseHelper th;
Cursor csr;
SimpleCursorAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mListView = this.findViewById(R.id.listview);
th = new DatabaseHelper(this);
addSomeTestData();
manageAdapter();
}
#Override
protected void onDestroy() {
super.onDestroy();
csr.close(); //<<<<<<<<<< Should always close Cursors when done with them
}
private void manageAdapter() {
/* This handles but the initialisation and the refreshing of the Listview */
/* First time it is called it initialises the Adapter and Listview */
/* On subsequent calls it refreshes the ListView */
csr = th.getAll();
if (adapter == null) {
adapter = new SimpleCursorAdapter(
this,
android.R.layout.simple_expandable_list_item_2,csr,
new String[]{
DatabaseHelper.COL1,
DatabaseHelper.COL2
},
new int[]{
android.R.id.text1,
android.R.id.text2},
0
);
mListView.setAdapter(adapter);
mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if (th.doneName(
/* reverses string to test multiple updates of the same row */
new StringBuilder(csr.getString(csr.getColumnIndex(DatabaseHelper.COL2))).reverse().toString()
/* "Done" */,
(int )id /* NOTE ID IS PASSED to onItemClick FOR CURSOR ADAPTER */,
csr.getString(csr.getColumnIndex(DatabaseHelper.COL2)) /* NOTE Oldname isn't required as ID will identify the row */
) > 0) {
manageAdapter(); //<<<<<<<<< after updating refresh the Cursor and the ListView
Toast.makeText(view.getContext(),"Updated OK.",Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(view.getContext(),"Not Updated!!!",Toast.LENGTH_SHORT).show();
}
}
});
} else {
adapter.swapCursor(csr);
}
}
private void addSomeTestData() {
//Add some data but only if none exists
if (DatabaseUtils.queryNumEntries(th.getWritableDatabase(),DatabaseHelper.TABLE_NAME) > 0) return;
th.insert("TEST1 COL1","TEST1 COL2");
th.insert("TEST2 COL1","TEST2 COL2");
th.insert("TEST3 COL1","TEST3 COL2");
th.insert("TEST4 COL1","TEST4 COL2");
th.insert("TEST5 COL1","TEST5 COL2");
}
}
Note that you can use your own layouts with SimpleCursorAdapter (4th (String[]) and 5th (int[]) are used to specify the column that the data comes from and the id of the respective view into which the data goes to)
Result :-
When initially run you get :-
Clicking a row and you get :-
If you then click all rows you get :-
And so on.
Related
I've got two Fragments
AddActivityFragment - This Fragment is responsible for adding data into my SQLite database.
and
ActivityListFragment - This Fragment is responsible for displaying the data in a ListView
The problem is that whenever data is added to the SQLite table, the table is not updated until the application is restarted. Because of this, if I try to add some data into the table, it is not updated in the ListView until I restart the application.
I've come across adapter.notifyDataSetChanged() on multiple threads regarding similar problems but I can not for the life of me figure out how I'm supposed to implement this into my own code.
AddActivityFragment.java:
public class AddActivityFragment extends Fragment implements View.OnClickListener {
private static final String TAG = "AddActivityFragment";
private TextInputLayout activityNameTextField, activityDateTextField;
private TextInputEditText activityNameInput, activityDateInput;
public DatabaseHelper mDatabaseHelper;
private LocationRequest mLocationRequest;
private FusedLocationProviderClient mFusedLocationProviderClient;
private Location mLastLocation;
private ActivityListFragment mActivityListFragment;
private DatePicker mDatePicker;
Context mContext;
private double activityLocationLat;
private double activityLocationLong;
public AddActivityFragment() {
// Required empty public constructor
}
#Override
public android.view.View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View activityViewFragment = inflater.inflate(R.layout.fragment_add_activity, container, false);
// Get context from fragment.
this.mContext = activityViewFragment.getContext();
mDatabaseHelper = new DatabaseHelper(mContext);
// Find the layout components.
activityNameTextField = activityViewFragment.findViewById(R.id.activityNameTextField);
activityNameInput = activityViewFragment.findViewById(R.id.activityNameInput);
mDatePicker = activityViewFragment.findViewById(R.id.datePicker);
Button addActivityButton = activityViewFragment.findViewById(R.id.addActivityButton);
// Set listener to addActivityButton in this view.
addActivityButton.setOnClickListener(this);
// Set hints for text fields.
activityNameTextField.setHint("Activity Name");
return activityViewFragment;
}
#Override
public void onClick(View v) {
switch(v.getId()) {
case R.id.addActivityButton:
StringBuilder sb = new StringBuilder();
int day = mDatePicker.getDayOfMonth();
int month = mDatePicker.getMonth() + 1;
int year = mDatePicker.getYear();
sb.append(day);
sb.append("-");
sb.append(month);
sb.append("-");
sb.append(year);
String activityName = activityNameInput.getText().toString();
String activityDate = sb.toString();
activityNameInput.setText("");
//Add the activity data to the SQL database
mDatabaseHelper.addData(activityName,activityDate,activityLocationLat,activityLocationLong);
break;
default:
break;
}
#Override
public void onResume(){
super.onResume();
Log.d(TAG,"Log when activity is swiped to.");
}
#Override
public void onPause() {
super.onPause();
Log.d(TAG, "List paused.");
}
}
ActivityListFragment.java:
public class ActivityListFragment extends Fragment {
//Class tag
private static final String TAG = "ActivityListFragment";
private static final String ACTIVITY_LIST_FRAGMENT_TAG = "ACTIVITY_LIST_FRAGMENT";
DatabaseHelper mDatabaseHelper;
Context mContext;
private ListView mListView;
public ArrayAdapter adapter;
private ArrayList<ArrayList> listData;
public ActivityListFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View listViewFragment = inflater.inflate(R.layout.fragment_activity_list, container, false);
this.mContext = listViewFragment.getContext();
mListView = listViewFragment.findViewById(R.id.activity_list_view);
mDatabaseHelper = new DatabaseHelper(mContext);
listData = new ArrayList<>();
for(int i = 0; i < mDatabaseHelper.getRowCount(); i++) {
listData.add(mDatabaseHelper.getDataFromIndex(i));
}
adapter = new ArrayAdapter<>(mContext, android.R.layout.simple_list_item_1, listData);
mListView.setAdapter(adapter);
handleOnItemClick();
return listViewFragment;
}
#Override
public void onResume(){
super.onResume();
Log.d(TAG,"Log when activity is swiped to.");
}
#Override
public void onPause() {
super.onPause();
Log.d(TAG, "List paused.");
}
ViewPagerAdapter.java:
public class ViewPagerAdapter extends FragmentStateAdapter {
public ViewPagerAdapter(#NonNull FragmentManager fragmentManager, #NonNull Lifecycle lifecycle) {
super(fragmentManager, lifecycle);
}
#NonNull
#Override
public Fragment createFragment(int position) {
switch (position) {
case 0:
return new MapViewFragment();
case 1:
return new AddActivityFragment();
case 2:
return new ActivityListFragment();
}
return null;
}
#Override
public int getItemCount() {
return 3;
}
}
DataBaseHelper.java:
public class DatabaseHelper extends SQLiteOpenHelper {
private static final String TAG = "DatabaseHelper";
//Table name, column names.
private static final String TABLE_NAME = "activity_table";
private static final String COL_ID = "ID";
private static final String COL_NAME = "name";
private static final String COL_DATE = "date";
private static final String COL_LOCATION_LAT = "location_lat";
private static final String COL_LOCATION = "location_long";
private Cursor mCursor;
ArrayList latLongList;
public DatabaseHelper(Context context) {
super(context, TABLE_NAME, null, 1);
}
/**
* Method: onCreate
* #param db - The database that we are creating the table in.
*/
#Override
public void onCreate(SQLiteDatabase db) {
String CREATE_ACTIVITES_TABLE = "CREATE TABLE " + TABLE_NAME + "("
+ COL_ID + " INTEGER PRIMARY KEY," + COL_NAME + " VARCHAR,"
+ COL_DATE + " VARCHAR," + COL_LOCATION_LAT + " DOUBLE," + COL_LOCATION + " DOUBLE" + ");";
db.execSQL(CREATE_ACTIVITES_TABLE);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
onCreate(db);
}
/**
* Method: addData
* #param name - The "name"-value which is added to the table column COL_NAME.
* #param date - The "date"-value which is added to the table column COL_DATE.
* #param locationLat - The "locationLat"-value which is added to the table column COL_LOCATION_LAT.
* #param locationLong - The "locationLong"-value which is added to the table column COL_LOCATION_LONG.
* #return true or false, depending if the addition to the table was successful or not.
*/
public boolean addData(String name, String date, Double locationLat, Double locationLong) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(COL_NAME, name);
contentValues.put(COL_DATE, date);
contentValues.put(COL_LOCATION_LAT, locationLat);
contentValues.put(COL_LOCATION, locationLong);
Log.d(TAG, "addData: Adding " + name + " to " + TABLE_NAME);
Log.d(TAG, "addData: Adding " + date + " to " + TABLE_NAME);
Log.d(TAG, "addData: Adding " + locationLat + " to " + TABLE_NAME);
Log.d(TAG, "addData: Adding " + locationLong + " to " + TABLE_NAME);
long result = db.insert(TABLE_NAME, null, contentValues);
if(result == -1) {
Log.d(TAG, "Something went wrong when adding data to database.");
return false;
} else {
Log.d(TAG, "Data correctly added to database");
return true;
}
}
/**
* Method: getData
* #return mCursor - Returns entire table from database.
*/
public Cursor getData() {
SQLiteDatabase db = this.getWritableDatabase();
String query = "SELECT * FROM " + TABLE_NAME;
mCursor = db.rawQuery(query, null);
return mCursor;
}
/**
* Method: getDataFromIndex
* #param index - Row index in activity_table table.
* #return list - ArrayList of data at row index.
*/
public ArrayList getDataFromIndex (int index) {
ArrayList list = new ArrayList();
if(mCursor == null) {
getData();
}
mCursor.moveToPosition(index);
list.add(mCursor.getString(1));
list.add(mCursor.getString(2));
list.add(mCursor.getDouble(3));
list.add(mCursor.getDouble(4));
return list;
}
/**
* Method: getRowCount
* #return mCursor.getCount - Total amount of rows in table.
*/
public int getRowCount() {
if(mCursor == null) {
getData();
}
return mCursor.getCount();
}
/** TODO: This might be useless as we will need to fetch the names associated to the activity anyway, to be decided.
* Method: latLongArrayListFromIndex
* #param index - Row index in activity_table table.
* #return latLongList - ArrayList of data at row index.
*/
public ArrayList latLongArrayListFromIndex(int index) {
latLongList = new ArrayList();
if(mCursor == null) {
getData();
}
mCursor.moveToPosition(index);
latLongList.add(mCursor.getDouble(mCursor.getColumnIndex("location_lat")));
latLongList.add(mCursor.getDouble(mCursor.getColumnIndex("location_long")));
return latLongList;
}
/**
* Method getItemId
*/
public Cursor getItemId(String name) {
SQLiteDatabase db = this.getWritableDatabase();
String query = "SELECT " + COL_ID + " FROM " + TABLE_NAME + " WHERE " + COL_NAME + " = '" + name + "'";
Cursor data = db.rawQuery(query, null);
return data;
}
/**
* Method: updateName
* #param newName
* #param id
* #param oldName
*/
public void updateName(String newName, int id, String oldName) {
SQLiteDatabase db = this.getWritableDatabase();
String query = "UPDATE " + TABLE_NAME + " SET " + COL_NAME + " = '" + newName + "' WHERE " + COL_ID + " = '" + id + "'" + " AND " + COL_NAME + " = '" + oldName + "'";
Log.d(TAG, "updateName: query: " + query);
Log.d(TAG, "updateName: Setting new name of activity to: " + newName);
db.execSQL(query);
}
public void deleteActivity(int id, String name) {
SQLiteDatabase db = this.getWritableDatabase();
String query = "DELETE FROM " + TABLE_NAME + " WHERE " + COL_ID + " = '" + id + "'" + " AND " + COL_NAME + " = '" + name + "'";
Log.d(TAG, "deleteActivity: query: " + query);
Log.d(TAG, "deleteActivity: Deleting " + name + " from table");
db.execSQL(query);
}
}
You can achieve the desired behaviour just by observing the SQLite data using content observer. I have a Github project here, that might help you to understand how this works.
The first step would be defining a content URI that is unique. The URI might look something as follows.
public static final Uri DB_TABLE_USER_URI = Uri
.parse("sqlite://" + com.package.your.app + "/" + "user_table");
Then use the LoaderManager.LoaderCallbacks<Cursor> in your ActivityListFragment to load the users in that fragment using CursorLoader callback functions (i.e. onCreateLoader, onLoadFinished, etc.). Also register for content observer in your onCreateLoader.
this.registerContentObserver(cursor, DBConstants.DB_TABLE_USER_URI);
And after you add/update a user in your DataBaseHelper class, you might also want to notify the observer that the data is changed in your database, so that it refreshes the data automatically in the RecyclerView.
context.getContentResolver().notifyChange(DBConstants.DB_TABLE_USER_URI, null);
I would recommend forking the Github project and run the code to see how it works.
I have a problem with deleting items from my database in listview. This is my code from my helper to delete data:
{
SQLiteDatabase db = this.getWritableDatabase();
String query = "DELETE FROM " + DB_TABLE + " WHERE " + COL1 + " = '" + id +"'" + " AND "
+ COL2 + " = '" + name +"'";
db.execSQL(query);
}
It views the data with this code
private void viewData() {
Cursor cursor = bh.viewData();
if (cursor.getCount() == 0) {
Toast.makeText(this, "Nothing to show", Toast.LENGTH_SHORT).show();
} else {
while (cursor.moveToNext()) {
listItem.add(cursor.getString(1));
}
adapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, listItem);
lv.setAdapter(adapter);
}
But the problem is I have no idea how to delete it from database
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
//It supposed to be deleted
}
});
Thank you in advance
In short you are presneting a list that is a single string extracted from the database.
Your delete is expecting two values. The id and the name (the listed value). Both values are not available from the single string that is listed.
If COL2 were UNIQUE (i.e. the same value would never be used) then you could easily just delete based upon this value but frequently names are not unique in which case it would be impossible to derive the id from the name. You would either have to use an ArrayList of objects (such an object containing both the id and the name) or have another array containing the id's that is in sync with the array of names.
I'd suggest using a CursorAdapter which :-
caters for Cursors and most especially provides the id as the 4th parameter to the onItemClick (for other adapters it is the same as the 3rd parameter i.e. the position).
NOTE the id column MUST be named _id.
Has all the rows in the Cursor used as the source available.
Has the Cursor appropriately positioned when onItemClick (and also onItemLongClick) is called.
Example
The following is an example based upon your code.
DatabaseHelper.java
public class DatabaseHelper extends SQLiteOpenHelper {
public static final String DBNAME = "mydb";
public static final int DBVERSION = 1;
public static final String DB_TABLE = "mytable";
public static final String COL1 = BaseColumns._ID; //<<<<<<<<<IMPORTANT uses the _id column
public static final String COL2 = "mynamecolumn";
public DatabaseHelper(#Nullable Context context) {
super(context, DBNAME, null, DBVERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE IF NOT EXISTS " + DB_TABLE +
"(" +
COL1 + " INTEGER PRIMARY KEY," +
COL2 + " TEXT " +
")"
);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
public long insert(String name) {
ContentValues cv = new ContentValues();
cv.put(COL2,name);
return this.getWritableDatabase().insert(DB_TABLE,null,cv);
}
public int delete(long id) {
SQLiteDatabase db = this.getWritableDatabase();
// ID WILL BE UNIQUE so that's enough to IDentify a row
return db.delete(DB_TABLE,COL1 + "=?", new String[]{String.valueOf(id)});
}
public Cursor viewData() {
SQLiteDatabase db = this.getWritableDatabase();
return db.query(DB_TABLE,null,null,null,null,null,null);
}
}
The above should be similar to what you have BUT note the name _id (obtained via the constant BaseColumns._ID) for COL1.
MainActivity.java
public class MainActivity extends AppCompatActivity {
DatabaseHelper bh;
Cursor csr;
ListView lv;
SimpleCursorAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lv = this.findViewById(R.id.myListView);
bh = new DatabaseHelper(this);
addSomeDataIfNone(); //<<<<< Add some testing data
manageListView(); //<<<<< Manage the LIstView
}
private void manageListView() {
csr = bh.viewData();
if (adapter == null) {
adapter = new SimpleCursorAdapter(
this,
android.R.layout.simple_list_item_1,
csr,
new String[]{DatabaseHelper.COL2},
new int[]{android.R.id.text1},
0
);
lv.setAdapter(adapter);
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
bh.delete(id); //<<<<< uses the 4th parameter
manageListView(); //<<<<< refresh the ListView as the data has changed
}
});
} else {
adapter.swapCursor(csr);
}
}
private void addSomeDataIfNone() {
if(DatabaseUtils.queryNumEntries(bh.getWritableDatabase(),DatabaseHelper.DB_TABLE) > 0) return;
bh.insert("Name 1");
bh.insert("Name 2");
bh.insert("Name 3");
}
#Override
protected void onDestroy() {
csr.close(); // Done with the Cursor so close it
bh.close(); // Done with the Database as this is the Main Activity
super.onDestroy();
}
}
Note how this is also quite similar BUT
uses the SimpleCursorAdapter as the source for the ListView. It iself uses a Cursor as the source for the data.
does not create a new Adapter each time the data is viewed
automatically refreshes the ListView when an item is clicked and thus deleted.
uses the id to delete the clicked item as that is all that is needed to unqiuely identify a row.
Results
When first run :-
When clicking Name 2 :-
I want to create a new table in my Database (meaning I will have two tables). In that table I will only have one and only value and the use of that only value is I will get it and I will perform addition or subtraction and inserting/updating it again for the new value that has been subtracted or added values (basically it is an integer value or boolean for decimals). I'm still new at sqlite and a beginner at android development.
My Question is that how will I have/insert only one value in the table BY DEFAULT and how will I get and update it. Because when I add INSERT query in the activity itself or in the button/fab it will add new values each time I will open the fragment itself or press the button/fab. How will I have only one data in there BY DEFAULT and how to get it so I can add or subtract values in to it and update it for the new value?
I created two tables:
#Override
public void onCreate(SQLiteDatabase db) {
final String SQL_CREATE_CASHFLOW_TABLE = "CREATE TABLE " + ItemEntry.TABLE_NAME2 + " (" +
ItemEntry._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
ItemEntry.COLUMN_INCOME + " INTEGER NOT NULL, " +
ItemEntry.COLUMN_SAVINGS + " INTEGER NOT NULL " +
");";
final String SQL_CREATE_ITEMLIST_TABLE = "CREATE TABLE " + ItemEntry.TABLE_NAME + " (" +
ItemEntry._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
ItemEntry.COLUMN_LABEL + " TEXT NOT NULL, " +
ItemEntry.COLUMN_DETAIL + " TEXT, " +
ItemEntry.COLUMN_AMOUNT + " INTEGER NOT NULL, " +
ItemEntry.COLUMN_DATE + " TEXT " +
");";
db.execSQL(SQL_CREATE_ITEMLIST_TABLE);
db.execSQL(SQL_CREATE_CASHFLOW_TABLE);
}
Codes I tried from bk7:
public void insertOrUpdateTheIncomeAndSavings(int income, int savings){
SQLiteDatabase sqLiteDatabase = this.getWritableDatabase();
Cursor cursor = sqLiteDatabase.rawQuery("SELECT * from "+ItemEntry.TABLE_NAME2,null);
if(cursor.moveToNext()){
//update the values of first row here
//update income
Cursor cursor2 = sqLiteDatabase.rawQuery("UPDATE "+ItemEntry.TABLE_NAME2+" SET "+ItemEntry.COLUMN_INCOME+
" = "+ income + " WHERE "+ItemEntry._ID +" = 1",null);
}else{
//insert the value here
ContentValues cv = new ContentValues();
cv.put(ItemEntry.COLUMN_INCOME, 0);
cv.put(ItemEntry.COLUMN_SAVINGS, 0);
}
if(cursor!=null){
cursor.close();
}
sqLiteDatabase.close();
}
How can I do it in income java:
package com.example.admin.test2;
import android.content.Context;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
/**
* A simple {#link Fragment} subclass.
*/
public class Income extends Fragment {
public Income() {
// Required empty public constructor
}
private EditText textInput;
private FloatingActionButton fabPlus;
private FloatingActionButton fabMinus;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate (R.layout.fragment_income, container, false);
textInput = (EditText) view.findViewById(R.id.editText2);
fabPlus = (FloatingActionButton) view.findViewById(R.id.fabPlus);
fabMinus = (FloatingActionButton) view.findViewById(R.id.fabMinus);
fabPlus.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
return view;
}
}
and get values from this editText:
textInput = (EditText) view.findViewById(R.id.editText2);
I want to display the input I inputted in the database in this textView but it does not work.. please check the code:
public void getIncome() {
Cursor cur = mDatabase.rawQuery("SELECT " + ItemContract.ItemEntry.COLUMN_INCOME + " as Income FROM " + ItemContract.ItemEntry.TABLE_NAME2
, null);
if (cur.moveToFirst()) {
int incomeTotal = cur.getInt(cur.getColumnIndex("Income"));// get final total
income.setText("₱ " + incomeTotal);
}
Here were inserting first row if it does not exist and updating the first row is exists.
public void insertOrUpdateTheIncomeAndSavings(int income, int savings){
SQLiteDatabase sqLiteDatabase = this.getWritableDatabase();
Cursor cursor = sqLiteDatabase.rawQuery("select * from "+ItemEntry.TABLE_NAME2,null);
if(cursor.moveToNext()){
//update the values of first row here
}else{
//insert the value here
}
if(cursor!=null){
cursor.close();
}
sqLiteDatabase.close();
}
Edit: Add this in Onclick
DBHelper dbhelper = new DBHelper(getActivity());
int income = Integer.valueOf(incomeEditText.getText().toString());
int savings = Integer.valueOf(savingsEditText.getText().toString());
dbhelper.insertOrUpdateTheIncomeAndSavings(income,savings);
public void updateEmployeeName(String empNo,String new_empname) {
Cursor cursor = null;
String empName = "";
try {
cursor = SQLiteDatabaseInstance_.rawQuery("SELECT EmployeeName
FROM Employee WHERE EmpNo=?", new String[] {empNo + ""});
if(cursor.getCount() > 0) {
cursor.moveToFirst();
empName = cursor.getString(cursor.getColumnIndex("EmployeeName"));
update(empname);
}else{
update(new_empname);
}
}finally {
cursor.close();
}
}
**Update single value use this query:-**
public void update(){
ContentValues cv = new ContentValues();
cv.put(ColumnName, newValue);
db.update(TABLE_NAME, cv, Column + "= ?", new String[] {rowId});
}
**delete single value use this query:-**
public void delete_singlevalue(String newValue) {
SQLiteDatabase db = getWritableDatabase();
db.execSQL("delete from TABLE_NAME where
ColumnName="+"'"+newValue+"'");
db.close();
}
This is a function that i call customer name from database for spinner. When i select the customer name, i also can obtain customer id. How to do it?
public List<String> getAllUsers(String userID) {
List<String> userlist = new ArrayList<>();
String status= "Active";
SQLiteDatabase db = this.getReadableDatabase();
String query = "select " + COLUMN_Customer_NAME + " from customer where " + COLUMN_Customer_USERID + "='" + userID + "'"+" AND " + COLUMN_Customer_STATUS + "='" + status + "'";
Cursor cursor = db.rawQuery(query, null);
if (cursor.moveToFirst()) {
do {
userlist.add(cursor.getString(0));
} while (cursor.moveToNext());
}
cursor.close();
db.close();
return userlist;
}
spinner_province.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
String item = parent.getItemAtPosition(position).toString();
province_id = position;
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
by using that , You get a selected item from spinner.
create your custom spinner and pass array of names and ids to spinner. and by using selecteditemposition get id from array at that position
create a custom adapter for spinner
class customAdapter(context : Context ,items: List<YourUserModel>) :
ArrayAdapter<YourUserModel>(context, resourceID)
with custom adapter on item click u can get the full object with will be holding name,id etc etc..
easier but not recommended way u can add the objects to hashmap or arraylist with the index/id of spinner position . then you can get it from there
I am trying to make an android application that allows the user to create a custom workout list from an already existing list of workouts. I decided to create an sqlite database to accomplish this task. In my database handler class "DBHandles.java" I have created and populated "Table_Workouts" with all the available workouts in the application. Also in "DBHandles.java" I have created another empty table "Table_User_List" for the purpose of holding specific entries from the "Table_Workouts" table that the user selects. "Table_User_List" needs to be populated at runtime.
public class DBhandles extends SQLiteOpenHelper {
private static final int DATABASE_VERSION = 1;
private static final String DATABASE_NAME = "Workouts.db";
public static final String TABLE_WORKOUTS = "Workouts";
public static final String TABLE_USER_LIST = "UserWorkouts";
public static final String COLUMN_ID = "_id";
public static final String COLUMN_NAME = "name";
public static final String COLUMN_DESCRIPTION = "description";
public static final String COLUMN_LINK = "link";
#Override
public void onCreate(SQLiteDatabase db) {
String CREATE_WORKOUTS_TABLE = "CREATE TABLE " +
TABLE_WORKOUTS + "("
+ COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
+ COLUMN_NAME + " TEXT,"
+ COLUMN_DESCRIPTION + " TEXT,"
+ COLUMN_LINK + " TEXT" + ")";
String CREATE_USER_TABLE ="CREATE TABLE " +
TABLE_USER_LIST + "("
+ COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
+ COLUMN_NAME + " TEXT,"
+ COLUMN_DESCRIPTION + " TEXT,"
+ COLUMN_LINK + " TEXT" + ")";
db.execSQL(CREATE_WORKOUTS_TABLE);
db.execSQL(CREATE_USER_TABLE);
db.execSQL("INSERT INTO " + TABLE_WORKOUTS + "(name, description, link) VALUES ('Shoulder Press', 'Shoulder PRess description', 'https://www.youtube.com/watch?v=qEwKCR5JCog')");
public void addWorkout(Workout workout) {
SQLiteDatabase db = this.getWritableDatabase();
db.beginTransaction();
try {
ContentValues values = new ContentValues();
values.put(COLUMN_NAME, workout.getWorkoutName());
values.put(COLUMN_DESCRIPTION, workout.getDescription());
values.put(COLUMN_LINK, workout.getLink());
db.insert(TABLE_USER_LIST, null, values);
} catch (Exception e){
Log.d(TAG, "Error while trying to add");
}
finally{
db.endTransaction();
}
//db.close();
}
public Workout findWorkout(String Workoutname) {
String query = "SELECT * FROM " + TABLE_WORKOUTS
+ " WHERE " + COLUMN_NAME
+ " = \"" + Workoutname + "\"";
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(query, null);
Workout workout = new Workout();
if (cursor.moveToFirst()) {
cursor.moveToFirst();
workout.setID(Integer.parseInt(cursor.getString(0)));
workout.setWorkoutName(cursor.getString(1));
workout.setDescription((cursor.getString(2)));
workout.setLink(cursor.getString(3));
cursor.close();
} else {
workout = null;
}
db.close();
return workout;
}
public boolean deleteWorkout(String Workoutname) {
boolean result = false;
String query = " SELECT * FROM " + TABLE_USER_LIST
+ " WHERE " + COLUMN_NAME
+ " = \"" + Workoutname + "\"";
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(query, null);
Workout workout = new Workout();
if (cursor.moveToFirst()) {
workout.setID(Integer.parseInt(cursor.getString(0)));
db.delete(TABLE_WORKOUTS, COLUMN_ID + " = ?",
new String[] { String.valueOf(workout.getID()) });
cursor.close();
result = true;
}
db.close();
return result;
}
public ArrayList getAllWorkoutNames (){
return genericGetSQL(TABLE_WORKOUTS, COLUMN_NAME);
}
public ArrayList genericGetSQL(String whichTable, String whichColumn){
ArrayList<String> wrkArray = new ArrayList<String>();
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.query(whichTable, new String[]{whichColumn}, null,null, null, null,null);
String fieldToAdd = null;
if(cursor.moveToFirst()){
while(cursor.isAfterLast()==false){
fieldToAdd = cursor.getString(0);
wrkArray.add(fieldToAdd);
cursor.moveToNext();
}
cursor.close();
}
return wrkArray;
}
As you can see I am returning an Arraylist from the DBHandles.class to display the name column of the "Table_Workouts" table. This ArrayList is accessed in my "DisplayAllWorkouts.java" class. The "DiplayAllWorkouts.java" class generates a tablerow for each entry in the "Table_Workouts" table and displays the name column to the user.
public class DisplayAllWorkouts extends AppCompatActivity implements YourListFrag.OnFragmentInteractionListener {
DBhandles db;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.displayworkoutlist);
yourListFrag = new YourListFrag();
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction().replace(R.id.LinLayDisplayYourList, yourListFrag, "ARG_PARAM1").
commit();
context = this;
TableLayout tableLayout = (TableLayout) findViewById(R.id.tableLayout);
TableRow rowHeader = new TableRow(context);
rowHeader.setBackgroundColor(Color.parseColor("#c0c0c0"));
rowHeader.setLayoutParams(new TableLayout.LayoutParams(TableLayout.LayoutParams.MATCH_PARENT,
TableLayout.LayoutParams.WRAP_CONTENT));
String[] headerText = {"NAME ", " ADD "};
for (String c : headerText) {
TextView tv = new TextView(this);
tv.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT,
TableRow.LayoutParams.WRAP_CONTENT));
tv.setTextSize(18);
tv.setPadding(5, 5, 5, 5);
tv.setText(c);
rowHeader.addView(tv);
}
tableLayout.addView(rowHeader);
db = yourListFrag.getDb();//new DBhandles(this, null, null, 1);
final ArrayList<String> arrNames = db.getAllWorkoutNames();
final ArrayList<String> arrDesc = db.getAllWorkoutDescription();
final ArrayList<String> arrLink = db.getAllWorkoutsLink();
for (int i = 0; i < arrNames.size(); i++) {
TableRow row = new TableRow(this);
final CheckBox AddBox = new CheckBox(this);
AddBox.setText("ADD");
final TextView nametv = new TextView(this);
//final TextView desctv = new TextView(this);
//final TextView linktv = new TextView(this);
nametv.setTextSize(30);
// desctv.setTextSize(30);
nametv.setText(arrNames.get(i));
//desctv.setText(arrDesc.get(i));
//linktv.setText(arrLink.get(i));
text = nametv.getText().toString();
row.addView(nametv);
row.addView(AddBox);
AddBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
// if(AddBox.isChecked()){
Workout wrk = (db.findWorkout(text));
db.addWorkout(wrk);
yourListFrag.refresh();
// yourListFrag.refresh();
// yourListFrag.refresh(text);
// }
// else{
// db.deleteWorkout(text);
//yourListFrag.delete(nametv.getText().toString());
// yourListFrag.refresh();
// }
}
});
row.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent i = new Intent(DisplayAllWorkouts.this, DisplaySingleWorkout.class);
i.putExtra("itemName", nametv.getText());
i.putStringArrayListExtra("everydesc", arrDesc);
i.putStringArrayListExtra("everyname", arrNames);
i.putStringArrayListExtra("everylink",arrLink);
startActivity(i);
}
});
tableLayout.addView(row);
}
}
#Override
public void onFragmentInteraction(int position) {
}
}
My problem is as follows. I want to be able to click on a table row displayed in the "DisplayAllWorkouts.java" class and have the corresponding row in "Table_Workouts" table be copied to the "Table_User_List" table. Once the row is copied I want the name column of "Table_User_List" displayed in "YourListFrag.java" class and inflated in the "DisplayAllWorkouts.java" class.
public class YourListFrag extends Fragment {
private ArrayAdapter<String> arrayAdapter;
private ListView lstView;
public ArrayList<String> holdNamesFromDB;
final DBhandles db = new DBhandles(getContext(), null, null, 1);
public DBhandles getDb(){
return this.db;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.your_list, container, false);
lstView = (ListView)rootView.findViewById(R.id.lstView);
holdNamesFromDB = db.getAllUserWorkouts();
arrayAdapter = new ArrayAdapter<String>(getContext(), android.R.layout.simple_list_item_1, holdNamesFromDB);
lstView.setAdapter(arrayAdapter);
public void refresh(){//String text){
//arrayAdapter.add(text);
// db.getAllUserWorkouts();
// arrayAdapter.notifyDataSetChanged();
holdNamesFromDB = db.getAllUserWorkouts();
//arrayAdapter = new ArrayAdapter<String>(getContext(), android.R.layout.simple_list_item_1, db.getAllUserWorkouts());
arrayAdapter.notifyDataSetChanged();
// arrayAdapter.notifyDataSetChanged();
//
}
I need the fragment to refresh its view everytime a new entry is added to the "Table_User_List" so the user can see every entry of the name column of "Table_User_List" in real time. I put logs in my program and the the flow seemed to successfully reach all the appropriate method calls without throwing an error or crashing. However, my program does not display the entries from Table_User_List in the "YourListFrag.java" class. I don't know if their is a problem copying the row from one sqlite table to the other, displaying and refershing the name column in the fragment or inflating the fragment into "DisplayAllWorkouts.java" class. I have been struggling with this problem for awhile now and I finally decided to reach out to the community that has always been there for me. I have referenced the following sqlite copy data from one table to another
and i can't tell if this approach actually works in my program because nothing is displayed in the fragment. Thank you for your time and effort. I apologize for the lines of code i commented out and posted. I have been trying everything i could think of.