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
Related
I am just trying to make a list by using RecyclerView where each of the list Item will contain a checkbox button. So when user will click on checkbox, it will replace the value of a Table column such as column country get value "A", on the other hand, uncheck will replace the country column value from "A" to "B" or anything.
Can anyone please help me with this? any suggestion regarding this and other similar ways to add data in SQLite database by using Recyclable will be highly a lot helpful.
Below I have added my code for your reference and Thanks in advance.
My DatabaseHelper Class
package com.hfad.ressql;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import com.hfad.ressql.DatabaseContractor.*;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.List;
public class DatabaseHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "workers.db";
private static final int DATABASE_VERSION =7;
SQLiteDatabase db;
public DatabaseHelper( Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
this.db=db;
final String SQL_CREATE_TBALE="CREATE TABLE " + EmployeeDetails.TABLE_NAME + "(" + EmployeeDetails._ID +" INTEGER PRIMARY KEY AUTOINCREMENT, "+
EmployeeDetails.COLUMN_FIRSTNAME+" TEXT, "+EmployeeDetails.COLUMN_LASTNAME+" TEXT, "+EmployeeDetails.COLUMN_COUNTRY+" TEXT)";
db.execSQL(SQL_CREATE_TBALE);
fillquestion();
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + EmployeeDetails.TABLE_NAME);
onCreate(db);
}
public void fillquestion(){
DataModel o4 = new DataModel("Earth","Soil","B");
IntertData(o4);
DataModel o5 = new DataModel("Sun","Light","B");
IntertData(o5);
DataModel o6 = new DataModel("Moon","Rock","B");
IntertData(o6);
}
public void IntertData (DataModel data){
ContentValues contentValues = new ContentValues();
contentValues.put(EmployeeDetails.COLUMN_FIRSTNAME, data.getFirstName());
contentValues.put(EmployeeDetails.COLUMN_LASTNAME, data.getLastName());
contentValues.put(EmployeeDetails.COLUMN_COUNTRY, data.country);
db.insert(EmployeeDetails.TABLE_NAME,null,contentValues);
}
public List<DataModel> object1() {
ArrayList<DataModel> details = new ArrayList<DataModel>();
db = getReadableDatabase();
Cursor cursor = db.rawQuery("SELECT * FROM " + EmployeeDetails.TABLE_NAME, null );
if (cursor.moveToFirst()) {
do {
DataModel object2 = new DataModel();
object2.setFirstName(cursor.getString(cursor.getColumnIndex(EmployeeDetails.COLUMN_FIRSTNAME)));
object2.setLastName(cursor.getString(cursor.getColumnIndex(EmployeeDetails.COLUMN_LASTNAME)));
object2.setCountry(cursor.getString(cursor.getColumnIndex(EmployeeDetails.COLUMN_COUNTRY)));
details.add(object2);
} while (cursor.moveToNext());
}
cursor.close();
return details;
}
}
Here is my DataModel Class
package com.hfad.ressql;
public class DataModel {
public String FirstName;
public String LastName;
public String country;
public DataModel() {
}
public DataModel(String firstName, String lastName, String country) {
this.FirstName = firstName;
this.LastName = lastName;
this.country = country;
}
public String getFirstName() {
return FirstName;
}
public void setFirstName(String firstName) {
FirstName = firstName;
}
public String getLastName() {
return LastName;
}
public void setLastName(String lastName) {
LastName = lastName;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
}
Database Constructor
public final class DatabaseContractor {
private DatabaseContractor (){}
public static class EmployeeDetails implements BaseColumns {
public static final String TABLE_NAME="employy";
public static final String COLUMN_FIRSTNAME="First_Name";
public static final String COLUMN_LASTNAME="Last_Name";
public static final String COLUMN_COUNTRY="Country";
public static final String COLUMN_FAVO="mfav";
}
}
Recycler Adapter
Here I am struggling hard to sort it out. All I need is, if I click on check box, one pre-given value will be updated in the database, at the same time check box will be checked until user uncheck it. And when user will uncheck it, database will replace previous value with a new value. Actually, I have just trying to have values in a table column, so that I can use it as a favorite or bookmark list.
public class RecycAdapter extends
RecyclerView.Adapter<RecycAdapter.ViewHolder> {
List<DataModel> dotamodeldataArraylist;
Context context;
SQLiteDatabase db;
DatabaseHelper helper;
ContentValues contentValues;
Cursor cursor;
public RecycAdapter(List<DataModel> dotamodeldataArraylist,Context context) {
this.dotamodeldataArraylist=dotamodeldataArraylist;
this.context=context;
}
#Override
public ViewHolder onCreateViewHolder( ViewGroup parent, int ViewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.itemlist,parent,false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(final RecycAdapter.ViewHolder holder, final int position) {
DataModel obj3= dotamodeldataArraylist.get(position);
holder.Fnam.setText(obj3.getFirstName());
holder.Lname.setText(obj3.getLastName());
holder.Country.setText(obj3.getCountry());
holder.fav.();
holder.fav.setChecked(fav);
final int currentPosition = position;
final boolean fav = 0==0;
holder.fav.setChecked(fav);
final int currentPosition = position;
holder.fav.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(holder.fav.isChecked()){
try {
contentValues = new ContentValues();
contentValues.put(DatabaseContractor.EmployeeDetails.COLUMN_COUNTRY, "B");
db.update("DRINK", contentValues, "id_=?", new String[]{Integer.toString(currentPosition)});
} catch (SQLException e){
Toast.makeText(context,"error" + position , Toast.LENGTH_LONG).show();
}
Toast.makeText(context,"checked " + position , Toast.LENGTH_LONG).show();
} if(!holder.fav.isChecked()){
Toast.makeText(context,"not checked" + position , Toast.LENGTH_LONG).show();
}
}
});
}
#Override
public int getItemCount() {
return dotamodeldataArraylist.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView Fnam,Lname,Country;
CheckBox fav;
RelativeLayout relativeLayout;
public ViewHolder(View itemView) {
super(itemView);
Fnam = itemView.findViewById(R.id.name1);
Lname = itemView.findViewById(R.id.city1);
Country = itemView.findViewById(R.id.country1);
fav=itemView.findViewById(R.id.chk);
relativeLayout = (RelativeLayout) itemView.findViewById(R.id.layout);
}
}
}
View Class
view all class
public class Viewall extends AppCompatActivity {
RecyclerView recyclerView;
DatabaseHelper databaseHelper;
RecycAdapter recycAdapter;
List<DataModel> dotamodeldataArraylist;
Context context;
Button show;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.viewall);
show = findViewById(R.id.view);
recyclerView=findViewById(R.id.recycle);
databaseHelper =new DatabaseHelper(this);
dotamodeldataArraylist = new ArrayList<DataModel>();
dotamodeldataArraylist=databaseHelper.object1();
recycAdapter =new RecycAdapter(dotamodeldataArraylist,this);
RecyclerView.LayoutManager reLayoutManager =new
LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(reLayoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(recycAdapter);
I believe the following will do as you wish.
The were quite a few issues with code. One of the major issues is that you expected the position to correlate with the id (aka your _id column).
The position of the first item in the list is 0, unless you force/specifically set the value of 0, an alias of the rowid column (your _id column is an alias of the rowid column), the first value assigned will be 1, then likely 2, then likely 3 ...........
So at best position will be 1 less than the id.
If a row is deleted, other than the last row then position will be one less except up until the deleted row is passed and then position will be 2 less than the rowid. More deletions and an even more complex correlation between position and id. I guess somebody could come up with a fool proof conversion BUT the simpe way is to ensure that the DataModel has the vale of the respective _id column.
As such DataModel.java should be changed to include a member/variable for the id therefore the following was used :-
public class DataModel {
public String FirstName;
public String LastName;
public String country;
public long id; //<<<<<<<<<< ADDED also added gettter and setter
public DataModel() {
}
public DataModel(String firstName, String lastName, String country) {
this(firstName,lastName,country,-1);
}
//<<<<<<<<<< ADDED so ID can be set
public DataModel(String firstName, String lastName, String country, long id) {
this.FirstName = firstName;
this.LastName = lastName;
this.country = country;
this.id = id;
}
public String getFirstName() {
return FirstName;
}
public void setFirstName(String firstName) {
FirstName = firstName;
}
public String getLastName() {
return LastName;
}
public void setLastName(String lastName) {
LastName = lastName;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public void setId(long id) {
this.id = id;
}
public long getId() {
return id;
}
}
see comments for changes
As you need to extract the id from the database, the object1 method was changed in DatabaseHelper.java (a few other changes have also been made) the following was used :-
public class DatabaseHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "workers.db";
private static final int DATABASE_VERSION =7;
SQLiteDatabase db;
public DatabaseHelper( Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
db = this.getWritableDatabase();
}
#Override
public void onCreate(SQLiteDatabase db) {
this.db=db; //<<<<<<< WRONG PLACE as onCreate only ever runs when there is no database
final String SQL_CREATE_TBALE="CREATE TABLE " + DatabaseContractor.EmployeeDetails.TABLE_NAME + "(" + DatabaseContractor.EmployeeDetails._ID +" INTEGER PRIMARY KEY AUTOINCREMENT, "+
DatabaseContractor.EmployeeDetails.COLUMN_FIRSTNAME+" TEXT, "+ DatabaseContractor.EmployeeDetails.COLUMN_LASTNAME+" TEXT, "+ DatabaseContractor.EmployeeDetails.COLUMN_COUNTRY+" TEXT)";
db.execSQL(SQL_CREATE_TBALE);
fillquestion();
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + DatabaseContractor.EmployeeDetails.TABLE_NAME);
onCreate(db);
}
public void fillquestion(){
IntertData(new DataModel("Earth","Soil","B"));
IntertData(new DataModel("Sun","Light","B"));
IntertData(new DataModel("Moon","Rock","B"));
}
public void IntertData (DataModel data){
ContentValues contentValues = new ContentValues();
contentValues.put(DatabaseContractor.EmployeeDetails.COLUMN_FIRSTNAME,data.getFirstName());
contentValues.put(DatabaseContractor.EmployeeDetails.COLUMN_LASTNAME,data.getLastName());
contentValues.put(DatabaseContractor.EmployeeDetails.COLUMN_COUNTRY,data.country);
db.insert(DatabaseContractor.EmployeeDetails.TABLE_NAME,null,contentValues);
}
public List<DataModel> object1() {
ArrayList<DataModel> details = new ArrayList<>();
//db = getReadableDatabase(); db has already been set when database was instantiated/constructed
Cursor cursor = db.rawQuery("SELECT * FROM " + DatabaseContractor.EmployeeDetails.TABLE_NAME, null );
while (cursor.moveToNext()) {
details.add(new DataModel(
cursor.getString(cursor.getColumnIndex(DatabaseContractor.EmployeeDetails.COLUMN_FIRSTNAME)),
cursor.getString(cursor.getColumnIndex(DatabaseContractor.EmployeeDetails.COLUMN_LASTNAME)),
cursor.getString(cursor.getColumnIndex(DatabaseContractor.EmployeeDetails.COLUMN_COUNTRY)),
cursor.getLong(cursor.getColumnIndex(DatabaseContractor.EmployeeDetails._ID)) //<<<<<<<<< Added so id is available
));
}
cursor.close();
return details;
}
}
Pretty extensive changes were made to RecycAdapter.java, the following was used :-
public class RecycAdapter extends RecyclerView.Adapter<RecycAdapter.ViewHolder> {
List<DataModel> dotamodeldataArraylist;
Context context;
SQLiteDatabase db;
DatabaseHelper helper;
ContentValues contentValues;
public RecycAdapter(List<DataModel> dotamodeldataArraylist,Context context) {
this.dotamodeldataArraylist=dotamodeldataArraylist;
this.context=context;
helper = new DatabaseHelper(context);
db = helper.getWritableDatabase();
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int ViewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.itemlist,parent,false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(final RecycAdapter.ViewHolder holder, final int position) {
//DataModel obj3= dotamodeldataArraylist.get(position); //<<<<<<<<<< NOT NEEDED
holder.Fnam.setText(dotamodeldataArraylist.get(position).getFirstName());
holder.Lname.setText(dotamodeldataArraylist.get(position).getLastName());
holder.Country.setText(dotamodeldataArraylist.get(position).getCountry());
holder.fav.setChecked(false); //<<<<<<<<< not stored so initially set to false
holder.fav.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String newcountry = "B";
if(holder.fav.isChecked()){
if (dotamodeldataArraylist.get(position).getCountry().equals("B")) {
newcountry = "A";
}
contentValues = new ContentValues();
contentValues.put(DatabaseContractor.EmployeeDetails.COLUMN_COUNTRY, newcountry);
if (db.update(
DatabaseContractor.EmployeeDetails.TABLE_NAME,
contentValues,
DatabaseContractor.EmployeeDetails._ID +"=?",
new String[]{String.valueOf(dotamodeldataArraylist.get(position).getId())}
) > 0) {
dotamodeldataArraylist.get(position).setCountry(newcountry);
notifyItemChanged(position);
Toast.makeText(context,
"checked and updated " +
position+ dotamodeldataArraylist.get(position).getFirstName() +
" ID is " + String.valueOf(dotamodeldataArraylist.get(position).getId()),
Toast.LENGTH_LONG
).show();
} else {
Toast.makeText(context,"error" + position , Toast.LENGTH_LONG).show();
}
} else {
Toast.makeText(context,"not checked" + position , Toast.LENGTH_LONG).show();
}
}
});
}
#Override
public int getItemCount() {
return dotamodeldataArraylist.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView Fnam,Lname,Country;
CheckBox fav;
public ViewHolder(View itemView) {
super(itemView);
Fnam = itemView.findViewById(R.id.name1);
Lname = itemView.findViewById(R.id.city1);
Country = itemView.findViewById(R.id.country1);
fav = itemView.findViewById(R.id.chk);
}
}
}
lastly a few minor changes were made to Viewall.java, the following was used :-
public class Viewall extends AppCompatActivity {
RecyclerView recyclerView;
DatabaseHelper databaseHelper;
RecycAdapter recycAdapter;
List<DataModel> dotamodeldataArraylist;
Button show;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.viewall);
show = findViewById(R.id.view);
recyclerView = findViewById(R.id.recycle);
databaseHelper = new DatabaseHelper(this);
dotamodeldataArraylist = databaseHelper.object1();
recycAdapter = new RecycAdapter(dotamodeldataArraylist, this);
RecyclerView.LayoutManager reLayoutManager = new
LinearLayoutManager(this);
recyclerView.setLayoutManager(reLayoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(recycAdapter);
}
}
Result
Note the layout(s) may be different, but your's should probably work and alter the presentation accordingly
When first run :-
After clicking the checkbox for Sun
Click again and back to Country B and so on.
Note the check box isn't flipped, that's a bit of an issue as to correctly display the changed data (country) notifyItemChanged is used, which will reprocess the list and thus set the checkbox to false. You'd need to store the checkbox value somewhere (in short you should really use checkboxes in this way).
Closing the app and restarting maintains the changes made, thus confirming that the changes to the database have been made.
On top of #MiKe's code, i have just made some changes in my RecyclerAdapter inside onClickListener to save checkbox Status and added isChecked as a boolean value inside dataModel class. now its working perfectly.
holder.chkbox.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Values = new ContentValues();
Values.put(DatabaseContractor.EmployeeDetails.COLUMN_FAVORITE,holder.chkbox.isChecked());
try{ db.update(DatabaseContractor.EmployeeDetails.TABLE_NAME,
Values,
DatabaseContractor.EmployeeDetails._ID + "=?",
new String[]{String.valueOf(dotamodeldataArraylist.get(position).getId())});
} catch (SQLException e){
Toast.makeText(context,"Error"+position,Toast.LENGTH_LONG).show();
}
}
});
Thanks again mike for your awesome guideline. Now, i can directly save checkbox status in sqlite Database.
I have coded a RecyclerView where I search for data from my SQLiteDatabase with the SearchAdapter. The MaterialSearchBar (PlaceHolder) only shows the names of the data from the Database. Now I want to select one item, which i choose in the searchbar and get all the other columns of that one row and store the data in a listview in another activity.
So my first question is, how can i get all data from one row, if i only have the name? Should I do it with a cursor?
And my second question is, how should i store all the data from that one row in a listview in another activity?
Thank you for your help!
enter cclass SearchViewHolder extends RecyclerView.ViewHolder{
public TextView medid,name,menge,art,nummer;
public SearchViewHolder(View itemView) {
super(itemView);
medid = (TextView) itemView.findViewById(R.id.medid);
name = (TextView) itemView.findViewById(R.id.name);
menge = (TextView) itemView.findViewById(R.id.menge);
art = (TextView) itemView.findViewById(R.id.art);
nummer = (TextView) itemView.findViewById(R.id.nummer);
}
}
public class SearchAdapter extends RecyclerView.Adapter<SearchViewHolder> {
private Context context;
private List<Drugs> drugs;
public SearchAdapter(Context context, List<Drugs> drugs) {
this.context = context;
this.drugs = drugs;
}
public SearchAdapter() {
}
#Override
public SearchViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater =LayoutInflater.from(parent.getContext());
View itemView = inflater.inflate(R.layout.medikamentensuche,parent,false);
return new SearchViewHolder(itemView);
}
#Override
public void onBindViewHolder(SearchViewHolder holder, int position) {
//String pharmaId,name,menge,art,preis,code,bezeichnung;
holder.medid.setText(toString().valueOf(drugs.get(position).getMedID()));
holder.name.setText(drugs.get(position).getName());
holder.menge.setText(drugs.get(position).getMenge());
holder.art.setText(drugs.get(position).getArt());
holder.nummer.setText(drugs.get(position).getNummer());
}
#Override
public int getItemCount() {
return drugs.size();
}
}
DataBaseOpenhelper class
public class DatabaseOpenHelper extends SQLiteAssetHelper {
private static final String DB_NAME = "medikamente.db";
private static final String TABLE = "Medikamente";
private static final int DB_VER = 1;
public static final String ID = "MedID";
public static final String NAME = "Handelsname";
public static final String MENGE = "Mengenangabe";
public static final String ART = "Mengenart";
public static final String NUMMER = "Pharmanummer";
public DatabaseOpenHelper(Context context) {
super(context, DB_NAME, null, DB_VER);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE);
onCreate(db);
}
//neues Medikament hinzufügen
public boolean insertNewEntry (String name, String mengenangabe, String mengenart, String pharmanummer) {
SQLiteDatabase db = getWritableDatabase();
ContentValues values = new ContentValues();
values.put(NAME,name);
values.put(MENGE,mengenangabe);
values.put(ART,mengenart);
values.put(NUMMER,pharmanummer);
long result = db.insert("Medikamente",null,values);
if (result == -1)
return false;
else
return true;
}
public List<Drugs> getDrug() {
SQLiteDatabase db = getReadableDatabase();
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
Log.d("in der DrugDatabases", "SQLiteQueryBuilder successful");
//Kathi habe hier: "ATCCode", "BezeichnungATCCode" gelöscht
String [] sqlSelect = {"MedID", "Handelsname", "Mengenangabe", "Mengenart", "Pharmanummer"};
String tableName = "Medikamente";
Log.d("in der DrugDatabases", " successful" + sqlSelect);
qb.setTables(tableName);
Cursor cursor = qb.query(db, sqlSelect, null, null, null, null, null);
List<Drugs> result = new ArrayList<>();
if(cursor.moveToFirst()) {
do{
Drugs drug = new Drugs();
drug.setMedID(cursor.getInt(cursor.getColumnIndex("MedID")));
drug.setName(cursor.getString(cursor.getColumnIndex("Handelsname")));
drug.setMenge(cursor.getString(cursor.getColumnIndex("Mengenangabe")));
drug.setArt(cursor.getString(cursor.getColumnIndex("Mengenart")));
drug.setNummer(cursor.getString(cursor.getColumnIndex("Pharmanummer")));
result.add(drug);
}while (cursor.moveToNext());
}return result;
}
public List<String> getNames() {
SQLiteDatabase db = getReadableDatabase();
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
String [] sqlSelect = {"Handelsname" };
String tableName = "Medikamente";
qb.setTables(tableName);
Cursor cursor = qb.query(db, sqlSelect, null, null, null, null, null);
List<String> result = new ArrayList<>();
if(cursor.moveToFirst()) {
do{
result.add(cursor.getString(cursor.getColumnIndex("Handelsname" )));
}while (cursor.moveToNext());
}return result;
}
public List<Drugs> getDrugsByName(String name) {
SQLiteDatabase db = getReadableDatabase();
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
String [] sqlSelect = {"MedID" ,"Handelsname" ,"Mengenangabe" ,"Mengenart" ,"Pharmanummer"};
String tableName = "Medikamente";
qb.setTables(tableName);
Cursor cursor = qb.query(db, sqlSelect, "Handelsname LIKE ?",new String[]{"%"+name+"%"}, null, null, null);
List<Drugs> result = new ArrayList<>();
if(cursor.moveToFirst()) {
do{
Drugs drug = new Drugs();
drug.setMedID(cursor.getInt(cursor.getColumnIndex("MedID")));
drug.setName(cursor.getString(cursor.getColumnIndex("Handelsname")));
drug.setMenge(cursor.getString(cursor.getColumnIndex("Mengenangabe")));
drug.setArt(cursor.getString(cursor.getColumnIndex("Mengenart")));
drug.setNummer(cursor.getString(cursor.getColumnIndex("Pharmanummer")));
result.add(drug);
}while (cursor.moveToNext());
}return result;
}
}
MedSucheActivity
public class MedSucheActivity extends AppCompatActivity {
RecyclerView recyclerView;
RecyclerView.LayoutManager layoutManager;
SearchAdapter adapter;
TextView textView;
MaterialSearchBar materialSearchBar;
List<String> suggestList = new ArrayList<>();
DatabaseOpenHelper database;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_medsuchen);
Button button = (Button) findViewById(R.id.hinzufügen);
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(getApplicationContext(),MedTableActivity.class);
TextView suche = (TextView) findViewById(R.id.SuchMedikament);
intent.putExtra("weitergabe",suche.getText().toString());
startActivityForResult(intent,1);
//wichtig wenn man Daten zurück geben will von der 2.Activity
}
});
textView = (TextView) findViewById(R.id.SuchMedikament);
recyclerView = (RecyclerView) findViewById(R.id.recycler_search);
layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setHasFixedSize(true);
materialSearchBar = (MaterialSearchBar) findViewById(R.id.search_bar);
//textView = (TextView) findViewById(R.id.versuch);
//Datenbank
database = new DatabaseOpenHelper(this);
//Searchbar
materialSearchBar.setHint("Search");
materialSearchBar.setCardViewElevation(10);
loadSuggestList();
materialSearchBar.addTextChangeListener(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) {
List<String> suggest = new ArrayList<>();
for(String search:suggestList) {
if (search.toLowerCase().contains(materialSearchBar.getText().toLowerCase()))
suggest.add(search);
}
materialSearchBar.setLastSuggestions(suggest);
}
#Override
public void afterTextChanged(Editable s) {
}
});
materialSearchBar.setOnSearchActionListener(new MaterialSearchBar.OnSearchActionListener() {
#Override
public void onSearchStateChanged(boolean enabled) {
if(!enabled)
recyclerView.setAdapter(adapter);
}
#Override
public void onSearchConfirmed(CharSequence text) {
startSearch(text.toString());
}
#Override
public void onButtonClicked(int buttonCode) {
}
});
//init Adapter default set all result
adapter = new SearchAdapter(this,database.getDrug());
recyclerView.setAdapter(adapter);
}
private void startSearch(String text) {
adapter = new SearchAdapter(this,database.getDrugsByName(text));
recyclerView.setAdapter(adapter);
}
private void loadSuggestList() {
suggestList = database.getNames();
materialSearchBar.setLastSuggestions(suggestList);
}
public void onHinzuClick(View v) {
Log.d("msg","Auf Hinzufügen Button geklickt");
Intent intent = new Intent (getBaseContext(),MedikamentHinzufugenActivity.class);
startActivity(intent);
}
}
So my first question is, how can i get all data from one row, if i
only have the name?
And my second question is, how should i store all the data from that
one row in a listview in another activity?
If name is definitely going to be unique, which it appears that it may not be, then you can use that in conjunction with the getDrugsByName method to obtain a list of Drug objects (1 if the name is unique). So name is all that would be required and this can be passed to another activity via an Intent Extra and thus retrieved from that Intent Extra, you can then use the getDrugsbyName method in that activity to then get all the data for the row (for 2.). Of course you could also pass all values via Intent Extras.
If name isn't necessarily unique then you could use MedId (column ID) (assuming that it's the PRIMARY KEY of the table and thus unique) instead of the name. You would probably have a method getDrugById in the DatabaseHelper class along the lines of (for 2.) :-
public Drugs getDrugById(long id) {
SQLiteDatabase db = getReadableDatabase();
Drugs rv = new Drugs();
rv.setMedID(-1); // set so that drug not found can be determined
String whereclause = ID + "=?";
String[] whereargs = new String[]{String.valueOf(id)};
Cursor csr = db.query(TABLE,null,whereclause,whereargs,null,null,null);
if (csr.moveToFirst()) {
rv.setMedID(id);
rv.setName(csr.getString(csr.getColumnIndex(NAME)));
rv.setMenge(csr.getString(csr.getColumnIndex(MENGE)));
rv.setArt(csr.getString(csr.getColumnIndex(ART)));
rv.setNummer(csr.getString(csr.getColumnIndex(NUMMER)));
}
csr.close();
return rv;
}
Notes
The returned value should be checked for the MedID being -1, this indicating that there is no such row that matches the passed id.
Rather than risking mistyping names the CONSTANTS defined in the class have been used (you may wish to adopt this throughout).
Cursors should ALWAYS be closed when done with, otherwise an exception can occur.
The above assumes that the ID column is the PRIMARY KEY and that it is an alias of the rowid column. That is you have ID INTEGER PRIMARY KEY or ID INTEGER,..other columns.., PRIMARY KEY (ID)
The above assumes the correct usage of the ID column i.e. that it is treated as a long not an int (int is ok as long as the rows are limited, however SQLite allows rowid's as high as 9223372036854775807, which cannot be handled by an int).
This is the usual method, as using an alias of rowid will likely be the most efficient.
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 have one RecyclerView and my method in RecyclerView adapter is working, but only for position i select and for example, when i click image with sign X i'm deleting first item which i positioned in remove method, but i want this to happens when user click image with sign X, to give him ability to select what item from the list he will delete.
Also i would like to delete that item from SQLite, but my method isn't good probably in helper class.
Here is MainActivity:
public class MainActivity extends AppCompatActivity {
RecyclerView mRecyclerView;
RecyclerView.LayoutManager mLayoutManager;
GridAdapter mGridAdapter;
DBHelper dbh;
String firstName;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
initAddImage();
dbh = new DBHelper(this);
initRecyclerView();
initDeleteImage();
}
public List<Birthday> getData() {
List<Birthday> birthdays = new ArrayList<>();
Birthday birthday = null;
Cursor c = dbh.getBirthdayData();
if (c != null) {
while (c.moveToNext()) {
int nameIndex = c.getColumnIndex(dbh.BIRTHDAY_NAME);
String nameText = c.getString(nameIndex);
this.firstName = nameText;
int lastNameIndex = c.getColumnIndex(dbh.BIRTHDAY_LAST_NAME);
String lastNameText = c.getString(lastNameIndex);
birthday = new Birthday();
birthday.setNAME(nameText);
birthday.setLAST_NAME(lastNameText);
birthdays.add(birthday);
}
}
return birthdays;
}
private void initRecyclerView(){
mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view);
mRecyclerView.setItemAnimator(new ScaleInAnimator());
// The number of Columns
mRecyclerView.setHasFixedSize(true);
mLayoutManager = new GridLayoutManager(this, 3);
mRecyclerView.setLayoutManager(mLayoutManager);
mGridAdapter = new GridAdapter(getData());
mRecyclerView.setAdapter(mGridAdapter);
}
private void initAddImage(){
ImageView addImage = (ImageView) findViewById(R.id.add_image);
addImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, AddBirthday.class);
startActivity(intent);
}
});
}
private void initDeleteImage(){
ImageView deleteImage = (ImageView) findViewById(R.id.delete_image);
deleteImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mGridAdapter.removeItem(0);
}
});
}
#Override
protected void onResume() {
super.onResume();
initRecyclerView();
}
}
Here is my RecyclerView Adapter:
public class GridAdapter extends RecyclerView.Adapter<GridAdapter.MyViewHolder> {
private List<Birthday> birthdays;
DBHelper dbh;
public GridAdapter(List<Birthday> birthdays){
this.birthdays = birthdays;
}
public class MyViewHolder extends RecyclerView.ViewHolder {
CustomTextView firstName, lastName;
TextView dateOfBirthday;
public MyViewHolder(View itemView) {
super(itemView);
firstName = (CustomTextView) itemView.findViewById(R.id.first_name);
lastName = (CustomTextView) itemView.findViewById(R.id.last_name);
dateOfBirthday = (TextView) itemView.findViewById(R.id.date_of_birthday);
}
}
public void removeItem(int position) {
birthdays.remove(position);
notifyItemRemoved(position);
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.grid_item, parent, false);
MyViewHolder holder = new MyViewHolder(v);
return holder;
}
#Override
public void onBindViewHolder(final MyViewHolder holder, final int position) {
holder.firstName.setText(birthdays.get(position).getNAME());
holder.lastName.setText(birthdays.get(position).getLAST_NAME());
}
#Override
public int getItemCount() {
return birthdays.size();
}
}
And here is my Database: Method for deleting item is at the bottom of class
public class DBHelper extends SQLiteOpenHelper {
private static final int DATABASE_VERSION = 1;
private static final String DATABASE_NAME = "_database";
private static final String BIRTHDAY_TABLE_NAME = "birthday_table";
public static final String BIRTHDAY_ID = "birthday_id";
public static final String BIRTHDAY_NAME = "birthday_name";
public static final String BIRTHDAY_LAST_NAME = "birthday_last_name";
private static final String CREATE_BIRTHDAY_TABLE = "CREATE TABLE " + BIRTHDAY_TABLE_NAME +
" ( " + BIRTHDAY_ID + " INTEGER PRIMARY KEY,"
+ BIRTHDAY_NAME + " TEXT," + BIRTHDAY_LAST_NAME + " TEXT );";
SQLiteDatabase database;
public DBHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_BIRTHDAY_TABLE);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + BIRTHDAY_TABLE_NAME);
onCreate(db);
}
public void setBirthdayData(String birthdayName, String birthdayLastName) {
database = getWritableDatabase();
ContentValues cv = new ContentValues();
cv.put(BIRTHDAY_NAME, birthdayName);
cv.put(BIRTHDAY_LAST_NAME, birthdayLastName);
database.insert(BIRTHDAY_TABLE_NAME, null, cv);
}
public Cursor getBirthdayData() {
database = getReadableDatabase();
String[] columns = {BIRTHDAY_ID, BIRTHDAY_NAME, BIRTHDAY_LAST_NAME};
Cursor c = database.query(BIRTHDAY_TABLE_NAME, columns, null, null, null, null, BIRTHDAY_ID + " DESC");
return c;
}
public Cursor getBirthdayName(String[] args) {
database = getReadableDatabase();
String query = "SELECT " + BIRTHDAY_NAME + " FROM " + BIRTHDAY_TABLE_NAME + " WHERE " + BIRTHDAY_NAME + " =?";
Cursor c = database.rawQuery(query, args);
return c;
}
public boolean deleteItem(long rowId) {
SQLiteDatabase db = getWritableDatabase();
return db.delete(BIRTHDAY_TABLE_NAME, BIRTHDAY_ID + "=" + rowId, null) > 0;
}
}
Assume your X sign is an ImageButton
Add the ImageButton in your grid_item.xml
In your MyViewHolder add ImageView as item named deleteItem
In OnBindViewHolder
`holder.deleteItem.setOnclickListener(new OnClickListener(){
#Override
public void onClick(View v){
dbHelper.deleteItem(birthdays.get(position).getItemId); /* you pass birthday id to a method deleteItem() in your DBHelper.java */
birthdays.remove(position);
GridAdapter.this.notifyDataSetChanged();
});`
deleteItem(long birthdayId) method
deleteItem(long birthdayId){
return database.delete(BIRTHDAY_TABLE_NAME, BIRTHDAY_ID + " = '" + birthdayId +"'", null, null, null, null);
}
I am building an app that displays items in a ListFragment. Right now each item displays the title and creation date. There are two other fragments. One that creates an item and has a EditText field where i can edit the title. Another simply displays an individual items contents.
The issue I am having is that every time I enter a character in the EditText field the app closes. The error messages indicate that the error occurs at onTextChanged in the TextChangedListener. Since I had this feature working when I was storing everything as a JSON file the error must occur because of the way i am updating the database and updating my model layer.
This file performs all the database operations and creates a custom Cursor.
public class SnapDatabaseHelper extends SQLiteOpenHelper {
private static final String TAG = "FeedFragment";
private static final String DB_NAME = "snap.sqlite";
private static final int VERSION = 1;
private static final String TABLE_SNAP = "snap";
private static final String COLUMN_SNAP_ID = "_id";
private static final String COLUMN_SNAP_DATE = "snap_date";
private static final String COLUMN_SNAP_UUID = "snap_uuid";
private static final String COLUMN_SNAP_TITLE = "snap_title";
public SnapDatabaseHelper(Context context){
super(context, DB_NAME, null, VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
// Create SNAP table
db.execSQL("create table snap(" +
"_id integer primary key autoincrement, " +
//"snap_uuid text, " +
"snap_date integer, " +
"snap_title text) ");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
//
}
public long insertSnap(Snap snap){
ContentValues cv = new ContentValues();
//cv.put(COLUMN_SNAP_UUID, snap.getUniqueId().toString());
cv.put(COLUMN_SNAP_DATE, snap.getDate().getTime());
cv.put(COLUMN_SNAP_TITLE, "");
return getWritableDatabase().insert(TABLE_SNAP, null, cv);
}
public boolean updateTitle(long snapId, String text)
{
ContentValues cv = new ContentValues();
cv.put(COLUMN_SNAP_ID, snapId);
cv.put(COLUMN_SNAP_TITLE, text);
int i= getWritableDatabase().update(TABLE_SNAP, cv, COLUMN_SNAP_ID+ "=" + snapId, null);
return i>0;
}
public SnapCursor querySnap(long id) {
Cursor wrapped = getReadableDatabase().query(TABLE_SNAP,
null, // all columns
COLUMN_SNAP_ID + " = ?", // look for a run ID
new String[]{ String.valueOf(id) }, // with this value
null, // group by
null, // order by
null, // having
"1"); // limit 1 row
return new SnapCursor(wrapped);
}
public SnapCursor querySnaps() {
// equivalent to "select * from run order by start_date asc"
Cursor wrapped = getReadableDatabase().query(TABLE_SNAP,
null, null, null, null, null, COLUMN_SNAP_DATE + " asc");
return new SnapCursor(wrapped);
}
public static class SnapCursor extends CursorWrapper{
public SnapCursor(Cursor c){
super(c);
}
public Snap getSnap() {
if (isBeforeFirst() || isAfterLast())
return null;
Snap s = new Snap();
s.setId(getLong(getColumnIndex(COLUMN_SNAP_ID)));
//s.setUniqueId(UUID(getString(getColumnIndex(COLUMN_SNAP_UUID))));
s.setDate(new Date(getLong(getColumnIndex(COLUMN_SNAP_DATE))));
s.setTitle(getString(getColumnIndex(COLUMN_SNAP_TITLE)));
return s;
}
}
}
This file links the fragments to the DatabaseHelper.
public class SnapLab {
private static SnapLab sSnapLab;
private Context mAppContext;
private SnapDatabaseHelper mHelper;
// private constructor
private SnapLab(Context appContext){
mAppContext = appContext;
mHelper = new SnapDatabaseHelper(mAppContext);
}
public static SnapLab get(Context c){
if(sSnapLab == null){
sSnapLab = new SnapLab(c.getApplicationContext());
}
return sSnapLab;
}
public Snap insertSnap() {
Snap s = new Snap();
s.setId(mHelper.insertSnap(s));
return s;
}
public boolean updateTitle(long snapId, String text){
return mHelper.updateTitle(snapId, text);
}
public SnapCursor querySnaps() {
return mHelper.querySnaps();
}
public Snap getSnap(long id) {
Snap s = null;
SnapCursor cursor = mHelper.querySnap(id);
cursor.moveToFirst();
// if we got a row, get a run
if (!cursor.isAfterLast())
s = cursor.getSnap();
cursor.close();
return s;
}
}
Here is the fragment with the EditText field
public class EditPageFragment extends Fragment {
private static final String TAG = "EditPageFragment";
public static final String EXTRA_SNAP_ID = "SNAP_ID";
private SnapLab mSnapLab;
private Snap mSnap;
private SnapDatabaseHelper mHelper;
private EditText mSnapText;
private Button mUploadButton;
private TextView mDateText;
private Long snapId;
public static EditPageFragment newInstance(Long snapId){
Bundle args = new Bundle();
args.putLong(EXTRA_SNAP_ID, snapId);
EditPageFragment fragment = new EditPageFragment();
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
mSnapLab = SnapLab.get(getActivity());
Bundle args = getArguments();
if (args != null){
long snapId = args.getLong(EXTRA_SNAP_ID, -1);
if (snapId != -1){
mSnap = mSnapLab.getSnap(snapId);
}
}
mSnap = new Snap();
mSnap = mSnapLab.insertSnap();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState){
View v = inflater.inflate(R.layout.edit_fragment, parent, false);
mDateText = (TextView)v.findViewById(R.id.edit_dateText);
mDateText.setText(mSnap.getDate().toString());
mSnapText = (EditText)v.findViewById(R.id.edit_snapText);
mSnapText.addTextChangedListener(new TextWatcher(){
#Override
public void afterTextChanged(Editable s) {
//leave blank for now
}
#Override
public void beforeTextChanged(CharSequence c, int start, int count,
int after) {
//leave blank for now
}
#Override
public void onTextChanged(CharSequence c, int start, int before,
int count) {
mSnap.setTitle(c.toString());
mSnapLab.updateTitle(snapId, c.toString());
Log.i(TAG, "text saved");
}
});
return v;
}
}
The import bits of code are the updateTitle() functions. What could I be doing wrong. Do you have a suggestion on how to better update a database. Everything works great except for the updating of the title. I appreciate any bit of help.
Looks like snapId is not assigned
private Long snapId; //field
few lines later
long snapId = args.getLong(EXTRA_SNAP_ID, -1); //local variable
few lines later
mSnapLab.updateTitle(snapId, c.toString()); //field
Please add stacktrace next time.