I'm trying to create a patient registration app in android but I'm currently stuck on how to achieved a multiple table to relate with and add to loader callback method.
The First table is for patient fullname.
And the Second table is for patient information foreign key to the id of the patient_fullname table.
Can someone here explain or help me on how to achieved this output?
Appreciate for any help.
PatienDBOpenHelper.java
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
public class PatientDBOpenHelper extends SQLiteOpenHelper{
//Constants for db name and version
private static final String LOGTAG = "DENTALAPP";
private static final String DATABASE_NAME = "dental.db";
private static final int DATABASE_VERSION = 1;
//Constants for identifying table and columns
public static final String TABLE_PATIENT = "patient";
public static final String PATIENT_ID = "_id";
public static final String PATIENT_NAME = "nameInfo";
public static final String PATIENT_GENDER = "genderInfo";
public static final String PATIENT_CREATED = "patientCreated";
/*I will put my desired table structure here
_id
patientId
address
occupation
etc....
*/
public static final String[] ALL_COLUMNS = {PATIENT_ID, PATIENT_NAME, PATIENT_GENDER,PATIENT_CREATED};
//SQL to create table
private static final String TABLE_CREATE_PATIENT =
"CREATE TABLE " + TABLE_PATIENT + " (" +
PATIENT_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
PATIENT_NAME + " TEXT, " +
PATIENT_GENDER + " TEXT, " +
PATIENT_CREATED + " TEXT default CURRENT_TIMESTAMP" +
")";
/*
Will also add query statement here for another table.
*/
public PatientDBOpenHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
/*
Add the creation of other table.
*/
sqLiteDatabase.execSQL(TABLE_CREATE_PATIENT);
Log.i(LOGTAG,"Table Created!");
}
#Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
/*
Add the query of my additional drop table.
*/
sqLiteDatabase.execSQL("DROP TABLE IF EXIST " + TABLE_PATIENT);
onCreate(sqLiteDatabase);
}
}
PatientDataSource.java
import android.content.ContentValues;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
import com.bloxofcode.multipletabs.model.Patient;
public class PatientDataSource {
private static final String LOGTAG = "DENTALAPP";
SQLiteOpenHelper dbhelper;
SQLiteDatabase database;
public PatientDataSource(Context context){
dbhelper = new PatientDBOpenHelper(context);
}
public void open(){
Log.i(LOGTAG,"Database open");
database = dbhelper.getWritableDatabase();
}
public void close(){
Log.i(LOGTAG,"Database close");
dbhelper.close();
}
public Patient create(Patient patient){
ContentValues values = new ContentValues();
values.put(PatientDBOpenHelper.PATIENT_NAME,patient.getPatientFullName());
values.put(PatientDBOpenHelper.PATIENT_GENDER,patient.getPatientGender());
long id = database.insert(PatientDBOpenHelper.TABLE_PATIENT,null,values);
patient.setId(id);
return patient;
}
}
Tab1.java
public class Tab1 extends Fragment implements LoaderManager.LoaderCallbacks<Cursor>{
private ImageButton imgButton;
private CustomDialog customDialog;
private TextView tvNoRecord;
private ImageView imgNoRecord;
private CursorAdapter cursorAdapter;
PatientDataSource patientDataSource;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
patientDataSource = new PatientDataSource(getActivity());
patientDataSource.open();
final View v =inflater.inflate(R.layout.tab_1,container,false);
imgButton = (ImageButton) v.findViewById(R.id.imageButton);
imgNoRecord = (ImageView) v.findViewById(R.id.imgNoRecord);
tvNoRecord = (TextView) v.findViewById(R.id.tvNoRecord);
//Creating ImageButton
imgButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
customDialog = new CustomDialog(getActivity());
customDialog.setDialogResult(new OnMyDialogResult() {
#Override
public void finish(String resultName, String resultGender) {
if (!resultName.isEmpty()){
Log.d("TestingUnit","asdadasdsa");
Patient patient = new Patient();
patient.setPatientFullName(resultName);
patient.setPatientGender(resultGender);
patientDataSource.create(patient);
restartLoader();
}
listPatient(v);
}
});
customDialog.show();
}
});
listPatient(v);
return v;
}
private void listPatient(View v){
cursorAdapter = new PatientCursorAdapter(getActivity(),null,0 );
ListView list = (ListView) v.findViewById(android.R.id.list);
list.setAdapter(cursorAdapter);
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String info = ((TextView) view.findViewById(R.id.tvName)).getText().toString();
Intent i = new Intent(getContext(), UserInfoActivity.class);
i.putExtra("PersonName", info);
startActivity(i);
}
});
getLoaderManager().initLoader(0,null,this);
}
private void restartLoader(){
getLoaderManager().restartLoader(0,null,this);
}
#Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
return new CursorLoader(getActivity(), PatientProvider.CONTENT_URI,null,null,null,null);
}
#Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
if(data.getCount() > 0){
imgNoRecord.setVisibility(View.INVISIBLE);
tvNoRecord.setVisibility(View.INVISIBLE);
}else{
imgNoRecord.setVisibility(View.VISIBLE);
tvNoRecord.setVisibility(View.VISIBLE);
}
cursorAdapter.swapCursor(data);
}
#Override
public void onLoaderReset(Loader<Cursor> loader) {
cursorAdapter.swapCursor(null);
}
#Override
public void onResume() {
super.onResume();
patientDataSource.open();
}
#Override
public void onPause() {
super.onPause();
patientDataSource.close();
}
}
This is where i will get the 1st table(patient full name):
This is where the 2nd table will show its data(patient info):
Related
I was trying to get the values which i have entered in edit text using recycler view. On click of submit i want to save the text given in the editetxt to the table.
using Json stored the data to the table - Success
upto array adapter i got the data
now how to move the data from adapter to the main activity to save the data into table on single submit button. [enter image description here][1]
Activity
public class fertlizerRequest extends AppCompatActivity {
Button submit_btn,view_btn;
RecyclerView material_lv;
ArrayList<ProductData> arrayList;
ProductsAdapter myAdapterP;
private RecyclerView.LayoutManager mLayoutManager;
DBHelperClass dbHelperClass = new DBHelperClass(this);
Integer[] enteredNumber = new Integer[1000];
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fertlizer_request);
datacasting();
view_btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
PlantLocationAssy plantLocationAssy = new PlantLocationAssy();
plantLocationAssy.execute();
}
});
submit_btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(fertlizerRequest.this, "Edited Item are ", Toast.LENGTH_SHORT).show();
}
});
}
void datacasting(){
material_lv = (RecyclerView) findViewById(R.id.materialreq_lv);
submit_btn = (Button) findViewById(R.id.sbt_btn);
view_btn = (Button) findViewById(R.id.vie_btn);
mLayoutManager = new LinearLayoutManager(this);
material_lv.setLayoutManager(mLayoutManager);
}
void fetchProductData(){
arrayList = dbHelperClass.getProductsDataFromDB();
myAdapterP = new ProductsAdapter(fertlizerRequest.this, arrayList, new ProductsAdapter.onEditTextChanged() {
#Override
public void onTextChanged(int position, String charSeq) {
enteredNumber[position] = Integer.valueOf(charSeq);
System.out.println("==================================== " + position);
Toast.makeText(fertlizerRequest.this, "Entered value is " + myAdapterP.getItemId(position), Toast.LENGTH_SHORT).show();
}
});
material_lv.setAdapter(myAdapterP);
myAdapterP.notifyDataSetChanged();
System.out.println("==================================== " + myAdapterP.getItemCount() );
}
private class PlantLocationAssy extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... voids) {
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
fetchProductData();
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
}
}
Adapter
package com.example.fertlizertrackerapp.Adapter;
import android.content.Context;
import android.content.Intent;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.example.fertlizertrackerapp.Model.ProductData;
import com.example.fertlizertrackerapp.R;
import java.io.Serializable;
import java.util.ArrayList;
public class ProductsAdapter extends RecyclerView.Adapter<ProductsAdapter.Holder> {
private Context context;
private ArrayList<ProductData> arrayList;
private onEditTextChanged onEditTextChanged;
public ProductsAdapter(Context context, ArrayList<ProductData> arrayList, onEditTextChanged onEditTextChanged) {
this.context = context;
this.arrayList = arrayList;
this.onEditTextChanged = onEditTextChanged;
}
#NonNull
#Override
public Holder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.cust_lv_fertilizer_request, parent, false);
return new Holder(view);
}
#Override
public void onBindViewHolder(#NonNull final Holder holder, final int position) {
final ProductData productData = arrayList.get(position);
// get for view
String productId = productData.getProductId();
final String material = productData.getMaterial();
String materialCode = productData.getMaterialCode();
//set view
holder.productId.setText(productId);
holder.material.setText(material);
holder.materialCode.setText(materialCode);
holder.quantity.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) {
onEditTextChanged.onTextChanged(position,s.toString());
String qty = holder.quantity.getText().toString();
Toast.makeText(context, "Value Changed is " + material + " : " + qty, Toast.LENGTH_SHORT).show();
}
#Override
public void afterTextChanged(Editable s) {
}
});
}
#Override
public int getItemCount() {
return arrayList.size();
}
class Holder extends RecyclerView.ViewHolder{
TextView productId, material,materialCode;
EditText quantity;
public Holder(#NonNull View itemView) {
super(itemView);
productId = itemView.findViewById(R.id.productId_tv);
material = itemView.findViewById(R.id.materialName_tv);
materialCode = itemView.findViewById(R.id.materialCode_tv);
quantity = (itemView).findViewById(R.id.materialQuantity_edt);
}
}
#Override
public int getItemViewType(int position) {
return super.getItemViewType(position);
}
public interface onEditTextChanged{
void onTextChanged(int position, String charSeq);
}
}
Model
package com.example.fertlizertrackerapp.Model;
public class ProductData {
String ProductId, Material,MaterialCode;
int quantity = 0;
public ProductData(String productId, String material,String materialCode) {
this.ProductId = productId;
this.Material = material;
this.MaterialCode = materialCode;
}
public String getProductId() {
return ProductId;
}
public void setProductId(String productId) {
ProductId = productId;
}
public String getMaterial() {
return Material;
}
public void setMaterial(String material) {
Material = material;
}
public String getMaterialCode() {
return MaterialCode;
}
public void setMaterialCode(String materialCode) {
MaterialCode = materialCode;
}
public int getQuantity() {
return quantity;
}
public void setQuantity(int quantity) {
this.quantity = quantity;
}
}
DBHelperClass
package com.example.fertlizertrackerapp;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import com.example.fertlizertrackerapp.Model.PlantData;
import com.example.fertlizertrackerapp.Model.ProductData;
import com.example.fertlizertrackerapp.Model.ProductRateData;
import java.util.ArrayList;
public class DBHelperClass extends SQLiteOpenHelper {
public static final int DBVersion = 1;
public static final String DB_Godown = "FertlizerApp.db";
public static final String DB_ProductListTABLE = "ProductDetails";
public static final String DB_ProductId = "ProductId";
public static final String DB_productStatus = "productStatus";
public static final String DB_Material = "Material";
public static final String DB_MaterialCode = "MaterialCode";
public static final String DB_MaterialStatus = "Status";
public static final String DB_MaterialCreatedBy = "CreatedBy";
public static final String DB_MaterialCreatedOn = "CreatedOn";
public static final String DB_MaterialUpdatedBy = "UpdatedBy";
public static final String DB_MaterialUpdatedOn = "UpdatedOn";
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(" CREATE TABLE " + DB_ProductListTABLE + "(" + DB_ProductId + " TEXT, "
+ DB_productStatus + " TEXT, "
+ DB_Material + " TEXT, "
+ DB_MaterialCode + " TEXT NOT NULL PRIMARY KEY, "
+ DB_MaterialStatus + " TEXT, "
+ DB_MaterialCreatedBy + " TEXT, "
+ DB_MaterialCreatedOn + " TEXT, "
+ DB_MaterialUpdatedBy + " TEXT, "
+ DB_MaterialUpdatedOn + " TEXT)");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + DB_ProductListTABLE);
}
public Boolean insertProductDetails(String v_ProductId, String v_productStatus, String v_Material, String v_MaterialCode, String v_MaterialStatus, String v_MaterialCreatedBy, String v_MaterialCreatedOn, String v_MaterialUpdatedBy, String v_MaterialUpdatedOn) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValue = new ContentValues();
contentValue.put("ProductId", v_ProductId);
contentValue.put("productStatus", v_productStatus);
contentValue.put("Material", v_Material);
contentValue.put("MaterialCode", v_MaterialCode);
contentValue.put("Status", v_MaterialStatus);
contentValue.put("CreatedBy", v_MaterialCreatedBy);
contentValue.put("CreatedOn", v_MaterialCreatedOn);
contentValue.put("UpdatedBy", v_MaterialUpdatedBy);
contentValue.put("UpdatedOn", v_MaterialUpdatedOn);
long result = db.insert(DB_ProductListTABLE, null, contentValue);
if (result == -1)
return false;
else
return true;
}
public DBHelperClass(Context context) {
super(context, DB_Godown, null, DBVersion);
}
public ArrayList<ProductData> getProductsDataFromDB(){
ArrayList<ProductData> arrayList = new ArrayList<>();
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery("select * from " + DB_ProductListTABLE, null);
while (cursor.moveToNext()) {
String productId = cursor.getString(0);
String material = cursor.getString(2);
String materialCode = cursor.getString(3);
ProductData productData = new ProductData(productId,material,materialCode);
arrayList.add(productData);
System.out.println("00000000000000000000 Product 00000000000000000000000000000 " + material);
}
return arrayList;
}
}
[1]: https://i.stack.imgur.com/ikNRR.jpg
i want to call stespRecord constructor in stepsDone where should i place the constructor call like StepsRecord rec = new StepsRecord(this);
public class stepsDone extends AppCompatDialogFragment {
public Padomet data;
public StepsRecord rec;
private static final String TAG = "stepsDone";
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
LayoutInflater inflater = getActivity().getLayoutInflater();
View view = inflater.inflate(R.layout.activity_steps_done, null);
rec= new StepsRecord(this);
builder.setView(view)
.setNegativeButton("Do more", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
}
})
.setPositiveButton("Add to the List", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
float g =data.get();
int d = data.getc();
Log.d(TAG, "HELLLOOOO1111"+g+" uuuuuuuuuuuuuuu "+d);
AddData(g,d);
}
});
ImageView imageView = view.findViewById(R.id.imageView);
Glide.with(this).load(R.drawable.tick2).into(imageView);
return builder.create();
}
public void AddData(float arg1,int arg2) {
rec.addData(arg1, arg2);
}
}
this is the class whose constructor i want to call
public class StepsRecord extends SQLiteOpenHelper {
private static final String TABLE_NAME = "PreviousRecord";
private static final String COL1 = "Goal";
private static final String COL2= "stepsTaken";
public StepsRecord(Context context) {
super(context, TABLE_NAME, null, 1);
}
#Override
public void onCreate(SQLiteDatabase db) {
String createTable = "CREATE TABLE " + TABLE_NAME + "("+ COL1 + " TEXT,"
+ COL2 + " TEXT" + ")";
db.execSQL(createTable);
}
#Override
public void onUpgrade(SQLiteDatabase db, int i, int i1) {
db.execSQL(String.format("DROP IF TABLE EXISTS %s", TABLE_NAME));
onCreate(db);
}
public void addData(float goal, int steps) {
SQLiteDatabase db = this.getWritableDatabase();
String gooals = String.valueOf(goal);
String stepstaken = String.valueOf(steps);
ContentValues contentValues = new ContentValues();
//contentValues.put(COL1, strDate);
contentValues.put(COL1, gooals);
contentValues.put(COL2, stepstaken);
db.insert(TABLE_NAME, null, contentValues);
}
public Cursor getData(){
SQLiteDatabase db = this.getWritableDatabase();
String query = "SELECT * FROM " + TABLE_NAME;
Cursor data = db.rawQuery(query, null);
return data;
}
}
Your help would be appreciated... i have searched on this a lot but have not found any solution may be this is not possible or may be its possible .. if this is possible then please let me know or any other solution of doing.
Now the constructor of StepsRecord needs a context as a parameter, and you are passing this which is referring to your stepsDone object which is a child of Fragment.
Now Fragment class doesn't extend Context, but the Activity class does.
Keeping that in mind you can override onAttach() method in your stepsDone class and you will get a reference to the activity associated with your stepsDone class:
public class stepsDone extends AppCompatDialogFragment {
public Padomet data;
public StepsRecord rec;
private static final String TAG = "stepsDone";
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
.......
.......
}
//here override the onAttach() and initialize the StepsRecord
#Override
public void onAttach(Context context){
super.onAttach(context);
//initialize here
rec= new StepsRecord(context);
}
.........
.........
}
I'm getting crazy right now with a problem, while saving an object in a SQLite database. I've got an UI in which you can insert some data in TextEdits and Checkboxes.
This is the BaseListFragment, which handles the UI for different types:
package de.financeplanner.ui.fragment;
import android.app.ListFragment;
import android.os.Bundle;
import android.app.FragmentTransaction;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ImageButton;
import java.util.ArrayList;
import de.financeplanner.R;
import de.financeplanner.constant.TabConstants;
import de.financeplanner.model.Category;
import de.financeplanner.model.Finance;
import de.financeplanner.model.Model;
import de.financeplanner.util.adapter.list.CategoryListAdapter;
import de.financeplanner.util.adapter.list.FinanceListAdapter;
import de.financeplanner.util.db.DBHelperCategory;
import de.financeplanner.util.db.DBHelperFinance;
/**
* Created by Christian on 20.01.2017.
*/
public class BaseListFragment extends ListFragment implements AdapterView.OnItemClickListener, AdapterView.OnItemLongClickListener {
private ArrayList<? extends Model> listData;
private short type;
public static BaseListFragment newInstance(short type){
BaseListFragment fragment = new BaseListFragment();
Bundle arguments = new Bundle();
arguments.putShort("type", type);
fragment.setArguments(arguments);
return fragment;
}
#Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_base_list, container, false);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
type = getArguments().getShort("type");
listData = loadListData(type);
initList();
initAddButton();
// getListView().setOnItemClickListener(this);
}
private ArrayList<? extends Model> loadListData(short type){
switch (type) {
case TabConstants.OVERVIEW:
return loadFinances();
case TabConstants.REVENUE:
return loadRevenues();
case TabConstants.EXPENSE:
return loadExpenses();
case TabConstants.CATEGORY:
return loadCategories();
}
return null;
}
private ArrayList<Finance> loadFinances() {
DBHelperFinance dbHelper = new DBHelperFinance(getContext());
return dbHelper.getAll();
}
private ArrayList<Finance> loadRevenues() {
DBHelperFinance dbHelper = new DBHelperFinance(getContext());
return dbHelper.getRevenues();
}
private ArrayList<Finance> loadExpenses() {
DBHelperFinance dbHelper = new DBHelperFinance(getContext());
return dbHelper.getExpanse();
}
private ArrayList<Category> loadCategories() {
DBHelperCategory dbHelper = new DBHelperCategory(getContext());
return dbHelper.getAll();
}
private void initList() {
ArrayAdapter adapter = null;
if (listData != null) {
if (type != TabConstants.CATEGORY) {
adapter = new FinanceListAdapter(getContext(), (ArrayList<Finance>)listData);
}else{
adapter = new CategoryListAdapter(getContext(), (ArrayList<Category>)listData);
}
setListAdapter(adapter);
}
}
private void initAddButton() {
ImageButton addButton = (ImageButton) getActivity().findViewById(R.id.add_button);
addButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
FragmentTransaction trans = getFragmentManager().beginTransaction();
if(type != TabConstants.CATEGORY){
trans.replace(R.id.fragment_container, AddFinanceFragment.newInstance());
trans.addToBackStack(null).commit();
}else{
trans.replace(R.id.fragment_container, AddCategoryFragment.newInstance());
trans.addToBackStack(null).commit();
}
}
});
}
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
}
#Override
public boolean onItemLongClick(AdapterView<?> adapterView, View view, int i, long l) {
return false;
}
}
For explanation:
You cann choose 4 different tabs (overview, revenue, expense and category). The UI is every time the same, only the data inside changes.
Now, when I click on the addButton inside the category tab and insert data, the data is saved inside the database and the listview is correctly updated.
This is the called method to save the category.
private void onSaveRequest(){
Category category = new Category();
category.setTitle(title.getText().toString());
category.setDescription(description.getText().toString());
DBHelperCategory dbHelper = new DBHelperCategory(getContext());
dbHelper.saveOrUpdate(category);
getFragmentManager().popBackStack();
}
And this is the DBHelper method, which is called to save the category:
public void saveOrUpdate(Category category){
ContentValues values = new ContentValues();
values.put("title", category.getTitle());
values.put("description", category.getDescription());
if(category.getId() == 0){
save(values);
} else {
update(values);
}
}
private void save(ContentValues values){
SQLiteDatabase db = getWritableDatabase();
db.insert("category", null, values);
}
This is the method, to get categories from the database:
public ArrayList<Category> getAll(){
ArrayList<Category> categories = new ArrayList<Category>();
SQLiteDatabase db = this.getReadableDatabase();
Cursor rows = db.rawQuery(GET_ALL_QUERY, null);
rows.moveToFirst();
while(!rows.isAfterLast()){
Category category = new Category();
category.setId(rows.getInt(0));
category.setTitle(rows.getString(1));
category.setDescription(rows.getString(2));
categories.add(category);
rows.moveToNext();
}
return categories;
}
The problem is, when I click the addButton inside the overview, revenue or expense tab, no data is insert into database and the listview is not updated.
And this the method, which is called, when the saveButton is pressed:
private void onSaveRequest(){
Finance finance = new Finance();
finance.setTitle(title.getText().toString());
finance.setCategoryID(0);
finance.setDescription(description.getText().toString());
finance.setPayment(Double.parseDouble(payment.getText().toString()));
finance.setExpense(expense.isChecked());
finance.setDate(date.getText().toString());
DBHelperFinance dbHelper = new DBHelperFinance(getContext());
dbHelper.saveOrUpdate(finance);
getFragmentManager().popBackStack();
}
And this is the method inside the DBHelper, which should insert the data in the database:
public void saveOrUpdate(Finance finance){
ContentValues values = new ContentValues();
values.put("title", finance.getTitle());
values.put("categoryID", finance.getCategoryID());
values.put("description", finance.getDescription());
values.put("payment", finance.getPayment());
values.put("expense", finance.isExpense() ? 1 : 0);
values.put("date", finance.getDate());
if(finance.getId() == 0){
save(values);
} else {
update(values);
}
}
private void save(ContentValues values){
SQLiteDatabase db = getWritableDatabase();
db.insert("finance", null, values);
}
This are the methods, to get the finances from the database:
private ArrayList<Finance> getAll(short condition){
ArrayList<Finance> finances = new ArrayList<Finance>();
SQLiteDatabase db = this.getReadableDatabase();
String whereClause = new String();
final String join = " INNER JOIN CATEGORY ON FINANCE.categoryID = CATEGORY.ID ";
if(condition != 0){
whereClause = condition == 1 ? " WHERE EXPENSE = 0 " : "WHERE EXPENSE = 1";
}
String query = GET_ALL_QUERY + join + whereClause;
Cursor rows = db.rawQuery(query, null);
rows.moveToFirst();
while(!rows.isAfterLast()){
Finance finance = new Finance();
finance.setId(rows.getInt(0));
finance.setTitle(rows.getString(1));
finance.setCategoryID(rows.getInt(2));
finance.setCategory(rows.getString(3));
finance.setDescription(rows.getString(4));
finance.setPayment(rows.getDouble(5));
finance.setExpense(rows.getInt(6) == 1);
finance.setDate(rows.getString(7));
finances.add(finance);
rows.moveToNext();
}
return finances;
}
To complete this, here is the super class for every DBHelper:
package de.financeplanner.util.db;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
/**
* Created by Christian on 20.01.2017.
*/
public class DBHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "financeDB";
public DBHelper(Context context) {
super(context, DATABASE_NAME , null, 1);
}
#Override
public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
db.execSQL("CREATE TABLE FINANCE " +
"(ID INTEGER PRIMARY KEY AUTOINCREMENT, TITLE VARCHAR(50), CATEGORYID INTEGER," +
"DESCRIPTION VARCHAR(240), PAYMENT DECIMAL(8,2), EXPENSE BOOLEAN," +
"DATE STRING); ");
db.execSQL("CREATE TABLE CATEGORY " +
"(ID INTEGER PRIMARY KEY AUTOINCREMENT, TITLE VARCHAR(50), DESCRIPTION VARCHAR(240));");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
db.execSQL("DROP TABLE IF EXISTS FINANCE");
db.execSQL("DROP TABLE IF EXISTS CATEGORY");
onCreate(db);
}
}
I've debugged the app and can't find anything wrong. (Just, that every ArrayList is empty, so nothing is insert into database). Even there is no exception or other error shown, so I think the Syntax and the fields for the database is also right. Strange is also, that in the morning everything worked and I really don't know, what I've changed that everything goes wrong right now.
I am facing this problem whenever i run the app 1st time data in database remain single time but when i close the App and restart again data goes twice(means two same row in table).Similarly for 3rd, 4th time and so on. How do i get rid of this problem? I even put datas.clear in DataList.java but don't whether i have add the datas.clear() line in correct place or not.
PLz help if there is any other problem in my code.
MainActivity.java code
public class MainActivity extends AppCompatActivity {
Button listButton, addButton;
DatabaseHelper df;
private final static String TAG = "TestActivity";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
df = new DatabaseHelper(this);
addButton = (Button) findViewById(R.id.addbutton);
uploadList();
}
public void uploadList(){
DatabaseHelper df=new DatabaseHelper(this);
df.open();
try{
InputStream im=getResources().getAssets().open("testdata.csv");
BufferedReader br=new BufferedReader(new InputStreamReader(im));
String data=br.readLine();
while(data != null){
String t[]=data.split(",");
Product p=new Product();
p.setFirst(t[0]);
p.setSec(t[1]);
p.setThird(t[2]);
df.insert(p);
data=br.readLine();
}
}catch(Exception e){
}
}
}
DatabaseHelper.java code
public class DatabaseHelper extends SQLiteOpenHelper{
private static final String FIRST="Name";
private static final String SECOND="Issn";
private static final String THIRD="ImpactFactor";
private static final String DATABASE="journal2016";
private static final String TABLENAME="journal";
private static final int VERSION=1;
SQLiteDatabase sd;
public void open(){
sd=getWritableDatabase();
}
public void close(){
sd.close();
}
public DatabaseHelper(Context context) {
super(context, DATABASE, null, VERSION);
}
#Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
sqLiteDatabase.execSQL("DROP TABLE IF EXISTS " + TABLENAME );
sqLiteDatabase.execSQL("CREATE TABLE " + TABLENAME + " ( NAME TEXT, ISSN TEXT, IMPACTFACTOR REAL)");
}
#Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
sqLiteDatabase.execSQL("DROP TABLE IF EXISTS " + TABLENAME );
}
public long insert(Product p){
ContentValues cv=new ContentValues();
cv.put(FIRST, p.getFirst());
cv.put(SECOND, p.getSec());
cv.put(THIRD, p.getThird());
return sd.insertWithOnConflict(TABLENAME, null, cv,SQLiteDatabase.CONFLICT_REPLACE);
}
public List<Product> getAllProduct(){
ArrayList<Product> list=new ArrayList<Product>();
SQLiteDatabase db = this.getWritableDatabase();
Cursor c=db.rawQuery("SELECT * FROM " + TABLENAME, null);
while(c.moveToNext()){
Product p=new Product();
p.setFirst(c.getString(0));
p.setSec(c.getString(1));
p.setThird(c.getString(2));
list.add(p);
}
db.close();
return list;
}
}
DataList.java code
public class DataList extends Activity{
List<Product> datas = new ArrayList<Product>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.list);
datas.clear();
DatabaseHelper d=new DatabaseHelper(this);
d.open();
datas = d.getAllProduct();
ListView lv=(ListView)findViewById(R.id.listView1);
lv.setAdapter(new ArrayAdapter(this, android.R.layout.simple_list_item_1, datas));
}
}
Product.java
public class Product {
private String first;
private String second;
private String third;
public String getFirst() {
return first;
}
public void setFirst(String first) {
this.first = first;
}
public String getSec() {
return second;
}
public void setSec(String sec) {
this.second = sec;
}
public String getThird() {
return third;
}
public void setThird(String third) {
this.third = third;
}
#Override
public String toString() {
return first + second + third;
}
}
Remove this line from your onCreate() method:
df = new DatabaseHelper(this);
as no need of it because you are create object of your DatabaseHelper class inside uploadList() method.
And also you are calling uploadList() method inside onCreate() thats why every time you launch the app, the onCreate() method executes and you uploadList() also execute. Try to put its calling statement in an onClickListener so it happens when you click a button or your choice of stuff.
I'm trying to update a listview with user entries into two text inputs. Once the save button is clicked, the user's entry should appear. Based on my code, the listview updates the first time I fill out the two text inputs and I hit save, but the second time I hit save, the listview does not update. Here's my code:
Home.java
public class Home extends AppCompatActivity implements AdapterView.OnItemSelectedListener {
EditText inputOne;
EditText inputTwo;
MyDBHandler dbHandler;
Button saveButton;
MyCursorAdapter cursorAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
inputOne = (EditText) findViewById(R.id.inputOne);
inputTwo = (EditText) findViewById(R.id.inputTwo);
dbHandler = new MyDBHandler(this, null, null, 1);
saveButton = (Button) findViewById(R.id.saveButton);
MyDBHandler myDBHandler = new MyDBHandler(this);
Cursor c = myDBHandler.getCursor();
cursorAdapter = new MyCursorAdapter(this,c,1);
ListView notes = (ListView) findViewById(R.id.notes);
notes.setAdapter(cursorAdapter);
public void saveClicked(View view) {
Test test = new Test( inputOne.getText().toString(), inputTwo.getText().toString() );
dbHandler.addTest(test);
inputOne.setText("");
inputTwo.setText("");
cursorAdapter.notifyDataSetChanged();
}
MyDBHandler.java
public class MyDBHandler extends SQLiteOpenHelper {
private static final int DATABASE_VERSION = 1;
private static final String DATABASE_NAME = "Database.db";
public static final String TABLE_TEST = "test";
public static final String COLUMN_ID = "_id";
public static final String COLUMN_ONE = "one";
public static final String COLUMN_TWO = "two";
public MyDBHandler(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
super(context, DATABASE_NAME, factory, DATABASE_VERSION);
}
public void onCreate(SQLiteDatabase db) {
String query = "CREATE TABLE " + TABLE_TEST + "(" +
COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
COLUMN_ONE + " TEXT," +
COLUMN_TWO + " TEXT" + ");";
db.execSQL(query);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_TEST);
onCreate(db);
}
public void addTest(Test test){
ContentValues values = new ContentValues();
values.put(COLUMN_ONE, test.get_one());
values.put(COLUMN_TWO, test.get_two());
SQLiteDatabase db = getWritableDatabase();
db.insert(TABLE_TEST, null, values);
db.close();
}
public Cursor getCursor(){
SQLiteDatabase db = getWritableDatabase();
String query = "SELECT * FROM " + TABLE_ACTIVITIES + " WHERE 1";
Cursor c = db.rawQuery(query, null);
return c;
}
}
MyCursorAdapter.java
public class MyCursorAdapter extends CursorAdapter {
public MyCursorAdapter(Context context, Cursor c, int flags) {
super(context, c, 1);
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
return LayoutInflater.from(context).inflate(R.layout.custom_row, parent, false);
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
TextView one = (TextView) view.findViewById(R.id.one);
TextView two = (TextView) view.findViewById(R.id.two);
String one_string = cursor.getString(cursor.getColumnIndexOrThrow(MyDBHandler.COLUMN_ONE));
one.setText(one_string);
String two_string = cursor.getString(cursor.getColumnIndexOrThrow(MyDBHandler.COLUMN_TWO));
two.setText(two_string);
}
}
Test.java
public class Test {
private int _id;
private String _one;
private String _two;
public Test(){
}
public Test(int id){
this._id = id;
}
public Test(String one, String two){
this._one = one;
this._two = two;
}
public int get_id() {
return _id;
}
public void set_id(int _id) {
this._id = _id;
}
public String get_one() {
return _one;
}
public void set_one(String _one) {
this._one = _one;
}
public String get_two() {
return _two;
}
public void set_two(String _two) {
this._two = _two;
}
The correct way to refresh a ListView backed by a Cursor is to call cursorAdapter.notifyDatasetChanged(), without needing to recreate and reset the adapter.
So in your saveClicked method you just update the db and let the Adapter know there has been a change.
To do this, you'll need to keep a reference to the adapter as an instance field instead of declaring it as a local variable.
Turns out my ListView was populating, but I made the mistake of putting a ListView inside of a ScrollView - so I wasn't able to see the addition of entries. It worked once I used the solution from this: Android - ListView's height just fits 1 ListView item