I am pretty new to android development and this is my first really complex project I have begun working on. I am trying to create a listview in my main activity that displays a list of strings from a database. At the same time, I want the user to be able to add new strings from a separate activity along with having the ability to delete them. I have primarily followed this tutorial here. Here are my activities:
Main:
public class HabitMain extends Activity {
private DbHelper mHelper;
private SQLiteDatabase dataBase;
private Button newHabit;
private ListView listview;
private ArrayList<String> hId = new ArrayList<String>();
private ArrayList<String> hName = new ArrayList<String>();
final Context context = this;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.habit_main);
displayData();
mHelper = new DbHelper(this);
//Initialize Button
newHabit = (Button) findViewById(R.id.mbButton);
ListView listview = (ListView)findViewById(R.id.listview);
OnClickListener listener = new OnClickListener() {
#Override
public void onClick(View v) {
Intent CreateHabit = new Intent(HabitMain.this, CreateNewHabit.class);
startActivityForResult(CreateHabit, 1);
}
};
listview.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
Toast.makeText( getApplicationContext(), " Click Confirmed.", Toast.LENGTH_SHORT).show();
}
});
newHabit.setOnClickListener(listener);
}
#Override
protected void onResume() {
super.onResume();
}
private void displayData()
{
dataBase = mHelper.getWritableDatabase();
Cursor mCursor = dataBase.rawQuery("SELECT * FROM " + DbHelper.TABLE_NAME, null);
hId.clear();
hName.clear();
if (mCursor.moveToFirst()) {
do {
hId.add(mCursor.getString(mCursor.getColumnIndex(DbHelper.KEY_ID)));
hName.add(mCursor.getString(mCursor.getColumnIndex(DbHelper.KEY_NAME)));
} while (mCursor.moveToNext());
}
DisplayAdapter disadpt = new DisplayAdapter(HabitMain.this, hId, hName);
listview.setAdapter(disadpt);
mCursor.close();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.habit_main, menu);
return true;
}
Create New Item:
public class CreateNewHabit extends Activity{
private EditText newHabit;
private TextView fDate;
private String futuredate, habitName;
private Button newHabitButton;
private SQLiteDatabase dataBase;
private DbHelper mHelper;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.create_habit);
getActionBar().setDisplayHomeAsUpEnabled(true);
newHabit = (EditText)findViewById(R.id.editDialog);
newHabitButton = (Button)findViewById(R.id.dialogButton);
fDate = (TextView)findViewById(R.id.fDate);
mHelper = new DbHelper(this);
newHabitButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
habitName= newHabit.getText().toString();
if(habitName.length()>0)
{
addHabit();
}
else
{
AlertDialog.Builder alertBuilder=new AlertDialog.Builder(CreateNewHabit.this);
alertBuilder.setTitle("No Name");
alertBuilder.setMessage("You didn't enter a name!");
alertBuilder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
alertBuilder.create().show();
}
}
});
}
private void addHabit()
{
dataBase=mHelper.getWritableDatabase();
ContentValues values=new ContentValues();
values.put(DbHelper.KEY_NAME,habitName );
System.out.println("");
//insert data into database
dataBase.insert(DbHelper.TABLE_NAME, null, values);
//close database
dataBase.close();
finish();
}
Database Helper:
public class DbHelper extends SQLiteOpenHelper {
static String DATABASE_NAME="habits";
public static final String TABLE_NAME="habit";
public static final String KEY_NAME="hname";
public static final String KEY_ID="id";
public DbHelper(Context context) {
super(context, DATABASE_NAME, null, 1);
}
#Override
public void onCreate(SQLiteDatabase db) {
String CREATE_TABLE="CREATE TABLE "+TABLE_NAME+" ("+KEY_ID+" INTEGER PRIMARY KEY, "+KEY_NAME+" TEXT)";
db.execSQL(CREATE_TABLE);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS "+TABLE_NAME);
onCreate(db);
}
Display adapter:
public class DisplayAdapter extends BaseAdapter {
private Context mContext;
private ArrayList<String> id;
private ArrayList<String> Name;
public DisplayAdapter(Context c, ArrayList<String> id,ArrayList<String> Name) {
this.mContext = c;
this.id = id;
this.Name = Name;
}
public int getCount() {
// TODO Auto-generated method stub
return id.size();
}
public Object getItem(int position) {
// TODO Auto-generated method stub
return null;
}
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}
public View getView(int pos, View child, ViewGroup parent) {
Holder mHolder;
LayoutInflater layoutInflater;
if (child == null) {
layoutInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
child = layoutInflater.inflate(R.layout.habit_items, null);
mHolder = new Holder();
mHolder.txt_id = (TextView) child.findViewById(R.id.value);
mHolder.txt_Name = (TextView) child.findViewById(R.id.label);
child.setTag(mHolder);
} else {
mHolder = (Holder) child.getTag();
}
mHolder.txt_id.setText(id.get(pos));
mHolder.txt_Name.setText(Name.get(pos));
return child;
}
public class Holder {
TextView txt_id;
TextView txt_Name;
}
I'm not quite sure what is going wrong here. I usually can't even open the application without it responding. I get the error: E/AndroidRuntime(28415): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.habit/com.habit.HabitMain}: java.lang.NullPointerException. I take it by this that the activity is unable to even begin, which I cannot find what is causing this.
If anybody could please help me get this working that would be so helpful. I have been ripping my hair out for the last few days trying to get this working.
I think you call displayData() before creating the database helper..
so try to call it this way:
mHelper = new DbHelper(this);
displayData();
ADDITION:
call both lines above after you initialize your listview.. after this:
ListView listview = (ListView)findViewById(R.id.listview);
since you access listview before its initialization, it's null..
http://androidsolution4u.blogspot.kr/2013/09/android-populate-listview-from-sqlite.html
The author of the article has given you the source code in the end. Download the source code and work its working fine.
Related
I save my recyclerview with SQliteopenhelper . I use Itemtouchhelper and I can change items positions with itemtouchhelper on recycler view but I cant update positions on my database How Can I ?
todoactivity.java
public class todoactivity extends AppCompatActivity {
TextView title;
ImageButton gorevo;
RecyclerView recyclerView;
List<String>Listsx = new ArrayList<>();
TodoActivityAdpter adapterx;
DatabaseHelper4 myDBxxx;
TextView textView;
CheckBox checkBox;
long id;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_todoactivity);
recyclerView=findViewById(R.id.recyclerviewxx);
recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
adapterx=new TodoActivityAdpter(Listsx);
recyclerView.setAdapter(adapterx);
title=findViewById(R.id.titlex);
textView=findViewById(R.id.text_viewx);
gorevo = findViewById(R.id.gorevo);
myDBxxx = new DatabaseHelper4(this);
Cursor datax = myDBxxx.getListContents();
if(datax.getCount() == 0){
}else{
while(datax.moveToNext()){
Listsx.add(datax.getString(1));
ListAdapter listAdapterx = new ArrayAdapter<>(this,R.layout.todoactivity_item,R.id.textitem,Listsx);
adapterx.notifyItemInserted(Listsx.size()-1);
}
}
gorevo.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
BottomSheetDialog bottomSheetDialog = new BottomSheetDialog(todoactivity.this);
bottomSheetDialog.setContentView(R.layout.bottomsheetlayout3);
bottomSheetDialog.show();
InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
inputMethodManager.toggleSoftInput(InputMethodManager.SHOW_FORCED,0);
EditText editText = bottomSheetDialog.findViewById(R.id.editx);
Button ekle = bottomSheetDialog.findViewById(R.id.ekle);
ekle.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String text = editText.getText().toString();
Listsx.add(text);
AddDataxxx(text);
adapterx.notifyItemInserted(Listsx.size()-1);
bottomSheetDialog.hide();
inputMethodManager.hideSoftInputFromWindow(view.getWindowToken(),0);
}
});
}
});
back=findViewById(R.id.back);
back.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent i = new Intent(todoactivity.this, pomodoroscreen.class);
startActivity(i);
overridePendingTransition(0,0);
}
});
ItemTouchHelper.SimpleCallback move = new ItemTouchHelper.SimpleCallback(ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.START | ItemTouchHelper.END , 0) {
#Override
public boolean onMove(#NonNull RecyclerView recyclerView, #NonNull RecyclerView.ViewHolder viewHolder, #NonNull RecyclerView.ViewHolder target) {
int fromPosition = viewHolder.getAdapterPosition();
int toPosition = target.getAdapterPosition();
Collections.swap(Listsx,fromPosition,toPosition);
recyclerView.getAdapter().notifyItemMoved(fromPosition,toPosition);
// I want update items position on my SQliteOpenhelper in there
return false;
}
#Override
public void onSwiped(#NonNull RecyclerView.ViewHolder viewHolder, int direction) {
}
};
ItemTouchHelper itemTouchHelperx = new ItemTouchHelper(move);
itemTouchHelperx.attachToRecyclerView(recyclerView);
}
public void AddDataxxx(String newEntry) {
boolean insertDatax = myDBxxx.addDataxxx(newEntry);
}
}
DatabaseHelper.java
public class DatabaseHelper4 extends SQLiteOpenHelper {
public static final String DATABASE_NAME4 = "mylistxxx.db";
public static final String TABLE_NAME4 = "mylist_dataxxx";
public static final String COL14 = "iDxxx";
public static final String COL24 = "ITEM1xxx";
public DatabaseHelper4(Context context) {
super(context, DATABASE_NAME4, null, 1);
}
#Override
public void onCreate(SQLiteDatabase dbxxx) {
String createTable = "CREATE TABLE " + TABLE_NAME4 + " (iDxxx INTEGER PRIMARY KEY AUTOINCREMENT, " +
" ITEM1xxx TEXT)";
dbxxx.execSQL(createTable);
}
#Override
public void onUpgrade(SQLiteDatabase dbxxx, int oldVersion, int newVersion) {
dbxxx.execSQL("DROP IF TABLE EXISTS " + TABLE_NAME4);
onCreate(dbxxx);
}
public boolean addDataxxx(String textt) {
SQLiteDatabase dbxxx = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(COL24, textt);
long result = dbxxx.insert(TABLE_NAME4, null, contentValues);
if (result == -1) {
return false;
} else {
return true;
}
}
public Cursor getListContents() {
SQLiteDatabase dbxxx = this.getWritableDatabase();
Cursor dataxxx = dbxxx.rawQuery("SELECT * FROM " + TABLE_NAME4, null);
return dataxxx;
}
}
Adapter.java
public class TodoActivityAdpter extends RecyclerView.Adapter<TodoActivityAdpter.Holder> {
List<String>Listsx;
public TodoActivityAdpter(List<String>itemxxx){
this.Listsx = itemxxx;
}
#NonNull
#Override
public TodoActivityAdpter.Holder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.todoactivity_item,parent,false);
Holder holder = new Holder(view);
return holder;
}
#Override
public void onBindViewHolder(#NonNull TodoActivityAdpter.Holder holder, int position) {
holder.textView.setText(Listsx.get(position));
holder.checkBox.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (holder.checkBox.isChecked()) {
holder.textView.setTextColor(view.getResources().getColor(R.color.grey));
} else {
holder.textView.setTextColor(view.getResources().getColor(R.color.Color_black));
}
}
});
}
#Override
public int getItemCount() {
return Listsx.size();
}
public class Holder extends RecyclerView.ViewHolder {
CheckBox checkBox;
TextView textView;
List<String>Listsx;
RecyclerView recyclerView;
Context mContext;
public Holder(View view) {
super(view);
textView=view.findViewById(R.id.text_viewx);
checkBox=view.findViewById(R.id.checkbox);
recyclerView=view.findViewById(R.id.recyclerviewxx);
}
}
}
Thats my java classes . My activity is todoactivity . My SQliteopenhelper is DatabaseHelper.java . My Adapter is adapter.java . I can change items position on my recyclerview but ı cant update items position on my database . How can I
I suggest adding a column with the position to use for ordering.
Please close the cursor and return a list of objects. You can read your cursor using cursor.getString(cursor.getColumnIndex(colName)). Overriding close in your helper and closing the writableDatabase is also good practise. I myself open the writableDatabase only once (upon create) and close it at the end (upon close).
Regards, Mike
I am creating a todo app with SQLite and RecyclerView, but I am having trouble in removing a task on a click of an image, which is my ivDelete. I want to delete completed tasks. any idea how to delete? any help would be appreciated.
This is my MainActivity:
public class MainActivity extends AppCompatActivity
{
Button btn_tasks,btn_reminders,btn_about;
ImageView img_addtask;
RecyclerView contactView;
DBHelper dbHelper;
CustomAdapter mAdapter;
private ArrayList<TaskClass> allContacts;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn_tasks = findViewById(R.id.btn_task);
btn_reminders = findViewById(R.id.btn_reminder);
btn_about = findViewById(R.id.btn_about);
img_addtask = findViewById(R.id.imageView);
dbHelper = new DBHelper(this);
contactView = findViewById(R.id.list);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
contactView.setLayoutManager(layoutManager);
contactView.setHasFixedSize(true);
allContacts = new ArrayList<>();
allContacts = dbHelper.getTaskList();
loadTaskList();
img_addtask.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View view)
{
addTask();
}
});
btn_reminders.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View view)
{
addReminder();
}
});
}
private void loadTaskList()
{
ArrayList<TaskClass> taskList = dbHelper.getTaskList();
if(mAdapter == null)
{
contactView.setVisibility(View.VISIBLE);
mAdapter = new CustomAdapter(this,allContacts);
contactView.setAdapter(mAdapter);
}
else
{
contactView.setVisibility(View.GONE);
Toast.makeText(this, "There is no task in the database. Start
adding now", Toast.LENGTH_LONG).show();
}
}
private void addTask()
{
Intent intent = new Intent(this,AddTask.class);
startActivity(intent);
}
private void addReminder()
{
Intent intent = new Intent(this,AddReminder.class);
startActivity(intent);
}
}
This is my DBHelper Class:
public class DBHelper extends SQLiteOpenHelper
{
private static final String DB_NAME = "Demo.db";
private static final int DB_VER = 1;
private static final String DB_TABLE = "Task";
DBHelper(Context context)
{
super(context, DB_NAME, null, DB_VER);
}
#Override
public void onCreate(SQLiteDatabase db)
{
db.execSQL(" CREATE TABLE " +DB_TABLE+" (ID INTEGER PRIMARY KEY AUTOINCREMENT, TaskName TEXT, dateStr TEXT)");
}
#Override
public void onUpgrade(SQLiteDatabase db, int i, int i1)
{
db.execSQL("DROP TABLE IF EXISTS "+DB_TABLE);
onCreate(db);
}
void insertNewTask(TaskClass taskClass)
{
ContentValues values = new ContentValues();
SQLiteDatabase db= this.getWritableDatabase();
values.put("TaskName",taskClass.getTaskName());
values.put("dateStr", taskClass.getTaskDate());
db.insert(DB_TABLE,null,values);
db.close();
}
public ArrayList<TaskClass> getTaskList()
{
String selectQuery = "SELECT * FROM " + DB_TABLE;
SQLiteDatabase db = this.getReadableDatabase();
ArrayList<TaskClass> taskList = new ArrayList<>();
Cursor cursor = db.rawQuery(selectQuery, null);
if(cursor.moveToFirst())
{
do {
String name = cursor.getString(cursor.getColumnIndex("TaskName"));
String date = cursor.getString(cursor.getColumnIndex("dateStr"));
taskList.add(new TaskClass(name,date));
}while (cursor.moveToNext());
}
cursor.close();
return taskList;
}
}
This is CustomAdapter Class:
public CustomViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType)
{
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_layout, parent, false);
return new CustomViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull CustomViewHolder viewHolder, final int position)
{
viewHolder.txtTask.setText(taskClass.get(position).getTaskName());
viewHolder.txtDate.setText(taskClass.get(position).getTaskDate());
}
#Override
public int getItemCount() {
return taskClass.size();
}
public class CustomViewHolder extends RecyclerView.ViewHolder
{
TextView txtTask,txtDate;
ImageView ivDelete;
public CustomViewHolder(View itemView)
{
super(itemView);
txtTask = itemView.findViewById(R.id.task_title);
txtDate = itemView.findViewById(R.id.task_date);
ivDelete = itemView.findViewById(R.id.ivDelete);
}
}
You can put a listener on your ivDelete in the onBindViewHolder of the adapter, and
delete the task by the id from the database. You will have to create a method to do so on the DBHelper class.
viewHolder.ivDelete.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Call method to delete task
}
});
I am building a training log that holds two strings that the user adds in TrainingLogCreate, which are added to a custom listView (lv) in TrainingLog, utilizing my SQLite Database in DBAdapter. My issues is that I want to delete a row from my list view, and to do so I need to add a button through my custom list view adapter (TrainingAdapter). However, I'm not sure how I should access my button from TrainingLog (the main fragment), and implement the onClickListener method there. Any ideas on how to do this?
TrainingLog:
public class TrainingLog extends Fragment {
ListView lv;
ArrayList<String> players = new ArrayList<String>();
ArrayAdapter<String> adapter;
ArrayAdapter<String> clearAdapter;
ArrayList<String> details = new ArrayList<String>();
public TrainingLog() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootView = inflater.inflate(R.layout.fragment_training_log, container, false);
lv = (ListView) rootView.findViewById(R.id.myListView);
final DBAdapter db = new DBAdapter(this.getActivity());
setHasOptionsMenu(true);
players.clear();
//OPEN
db.openDB();
//RETRIEVE
Cursor c=db.getAllNames();
while(c.moveToNext())
{
String name=c.getString(1);
players.add(name);
String pos=c.getString(2);
details.add(pos);
}
db.close();
//TrainingAdapter adapter = new TrainingAdapter(this, players);
//adapter=new ArrayAdapter<String>(this.getActivity(),android.R.layout.simple_selectable_list_item,players);
//lv.setAdapter(adapter);
//ListAdapter myTrainingAdapter = new TrainingAdapter(this.getActivity(), players);
//lv.setAdapter(myTrainingAdapter);
String[] playerArray = new String[players.size()];
playerArray = players.toArray(playerArray);
String[] detailArray = new String[details.size()];
detailArray = details.toArray(detailArray);
ListAdapter myAdapter = new TrainingAdapter(this.getActivity(), playerArray, detailArray);
lv.setAdapter(myAdapter);
return rootView;
}
#Override
public void onResume() {
super.onResume();
final DBAdapter db = new DBAdapter(this.getActivity());
players.clear();
///OPEN
db.openDB();
//RETRIEVE
Cursor c=db.getAllNames();
while(c.moveToNext())
{
String name=c.getString(1);
players.add(name);
String pos=c.getString(2);
details.add(pos);
}
db.close();
/* adapter=new ArrayAdapter<String>(this.getActivity(),android.R.layout.simple_selectable_list_item,players);
lv.setAdapter(adapter); */
String[] playerArray = new String[players.size()];
playerArray = players.toArray(playerArray);
String[] detailArray = new String[details.size()];
detailArray = details.toArray(detailArray);
ListAdapter myAdapter = new TrainingAdapter(this.getActivity(), playerArray, detailArray);
lv.setAdapter(myAdapter);
}
private void loadFragment()
{
}
#Override
public void onCreateOptionsMenu(
Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.traning_menu_itemdetail, menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// handle item selection
switch (item.getItemId()) {
case R.id.action_add:
Intent trainingCreateIntent = new Intent (getContext(), TrainingLogCreate.class);
startActivity(trainingCreateIntent);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
}
TrainingLogCreate:
public class TrainingLogCreate extends AppCompatActivity {
EditText nameTxt;
EditText posTxt;
Button savebtn;
Context context = this;
public TrainingLogCreate() {
// Required empty public constructor
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.training_log_create);
savebtn = (Button) findViewById(R.id.saveButton);
nameTxt = (EditText) findViewById(R.id.exercizeActivity);
posTxt = (EditText) findViewById(R.id.exercizeDetails);
final DBAdapter db=new DBAdapter(this);
savebtn.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
//OPEN
db.openDB();
//INSERT
long result=db.add(nameTxt.getText().toString(), posTxt.getText().toString());
if(result > 0)
{
nameTxt.setText("");
posTxt.setText("");
}else
{
Toast.makeText(getApplicationContext(), "Failure", Toast.LENGTH_SHORT).show();
}
//CLOSE DB
db.close();
//Close Fragment
finish();
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater mif = getMenuInflater();
mif.inflate(R.menu.training_create_menu, menu);
getActionBar().show();
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// handle item selection
switch (item.getItemId()) {
case R.id.action_save:
//add save functionality
return true;
default:
return super.onOptionsItemSelected(item);
}
}
}
TrainingAdapter:
public class TrainingAdapter extends ArrayAdapter<String> {
private final String[] playerArray;
private final String[] detailArray;
Button removeButton;
TrainingAdapter(FragmentActivity context, String[] playerArray, String[] detailArray) {
super(context, R.layout.training_row, playerArray);
this.playerArray = playerArray;
this.detailArray = detailArray;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater JohnsInflater = LayoutInflater.from(getContext());
View customView = JohnsInflater.inflate(R.layout.training_row, parent, false);
TextView exercizeTextView = (TextView) customView.findViewById(R.id.exercizeTextView);
TextView detailTextView = (TextView) customView.findViewById(R.id.detailTextView);
Button removeButton = (Button) customView.findViewById(R.id.deleteButton);
removeButton.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
final DBAdapter db = new DBAdapter();
}
});
exercizeTextView.setText(playerArray[position]);
detailTextView.setText(detailArray[position]);
return customView;
}
}
DBAdapter:
public class DBAdapter {
//COLUMNS
static final String ROWID="id";
static final String NAME = "name";
static final String POSITION = "position";
//DB PROPERTIES
static final String DBNAME="m_DB";
static final String TBNAME="m_TB";
static final int DBVERSION='1';
static final String CREATE_TB="CREATE TABLE m_TB(id INTEGER PRIMARY KEY AUTOINCREMENT,"
+ "name TEXT NOT NULL,position TEXT NOT NULL);";
final Context c;
SQLiteDatabase db;
DBHelper helper;
public DBAdapter(FragmentActivity ctx) {
// TODO Auto-generated constructor stub
this.c=ctx;
helper=new DBHelper(c);
}
// INNER HELPER DB CLASS
private static class DBHelper extends SQLiteOpenHelper
{
public DBHelper(Context context ) {
super(context, DBNAME, null, DBVERSION);
// TODO Auto-generated constructor stub
}
#Override
public void onCreate(SQLiteDatabase db) {
try
{
db.execSQL(CREATE_TB);
} catch (SQLException e) {
e.printStackTrace();
}
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
Log.w("DBAdapetr","Upgrading DB");
db.execSQL("DROP TABLE IF EXISTS m_TB");
onCreate(db);
}
}
// OPEN THE DB
public DBAdapter openDB()
{
try
{
db=helper.getWritableDatabase();
}catch(SQLException e)
{
Toast.makeText(c, e.getMessage(), Toast.LENGTH_LONG).show();
}
return this;
}
//CLOSE THE DB
public void close()
{
helper.close();
}
//INSERT INTO TABLE
public long add(String name,String pos)
{
try
{
ContentValues cv=new ContentValues();
cv.put(NAME, name);
cv.put(POSITION, pos);
return db.insert(TBNAME, ROWID, cv);
}catch(SQLException e)
{
e.printStackTrace();
}
return 0;
}
//REMOVE FROM TABLE
public long remove(String name,String pos)
{
try
{
ContentValues cv=new ContentValues();
cv.remove(name);
cv.remove(pos);
return db.insert(TBNAME, ROWID, cv);
}catch(SQLException e)
{
e.printStackTrace();
}
return 0;
}
//GET ALL VALUES
public Cursor getAllNames()
{
String[] columns={ROWID,NAME,POSITION};
return db.query(TBNAME, columns, null, null, null, null, null);
}
}
Using Interface or broadcast you can do that.
Create an interface and it will do the trick.
private View.OnClickListener delete;
public void setDelete(View.OnClickListener delete){
this.delete= delete;
}
removeButton.setTag(position);
removeButton.setOnClickListener(delete);
Now in your activity class implement onClickListener and call adapter's methosd
public class TrainingLogCreate extends AppCompatActivity implements View.OnClickListener{
#Override
public void onClick(View view) {
Object tag = (Integer) view.getTag();
switch (view.getId()){
case R.id.deleteButton:
if (tag != null && tag instanceof Integer) {
int position = (Integer) tag;
SQLiteDatabase dataBase = db.getWritableDatabase();
dataBase.delete(DBAdapter.TABLE_NAME,
DBAdapter.POSITION +"="+position, null);
yourlistAdapter.notifyDataSetChanged();
Try it let me know if any problem occurs.
I'm working on a class project in Java, exploring the use of the ContentProvider class for moving data between apps. We're making a basic CRUD app, with SQLite storage and a ContentProvider to move data to a second app. My debugging shows that my SQLite inserts seem to be working and building my database, but my ListView will not populate. It gives a spinning loading ring forever, which is not an issue I usually see with ListView. I've double- and tripple- checked that the adapter is in place, and I use a part of my loadData() method to create a list of item objects from the database which I can't find a problem with. I'm not sure where else the issue could be coming from.
MainActivity:
public static DatabaseHelper helper;
public static ItemProvider provider;
static Button addNew;
public static final int NEXT_REQUESTCODE = 1;
static ListFragment frag;
static ArrayList<ItemObject> items = new ArrayList<ItemObject>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
helper = new DatabaseHelper(this);
provider = new ItemProvider(helper);
FragmentManager mgr = getFragmentManager();
FragmentTransaction trans = mgr.beginTransaction();
final Context context = this.getApplicationContext(); //to pass as context
frag = ListFragment.newInstance(context, items);
frag.loadData();
trans.replace(R.id.fragment_container, frag, ListFragment.TAG);
addNew = (Button) findViewById(R.id.addNew);
addNew.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent addActivity = new Intent(context, FormActivity.class); //sets intent for addactivity
startActivityForResult(addActivity, NEXT_REQUESTCODE); //starts activity expecting response
}
});
}
//handles response from addactivity
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
if(resultCode == RESULT_OK && requestCode == NEXT_REQUESTCODE) {
Bundle result = data.getExtras();
ItemObject placeholder = new ItemObject(result.getString("weight"), result.getInt("steps"), result.getString("date")); //builds the object to be added to the list from addactivity response
frag.addObject(placeholder); //adds the object to the list
}
}
Context getContext() {
return this.getContext();
}
}
SQLiteOpenHelper class
public class DatabaseHelper extends SQLiteOpenHelper {
private static final String DATABASE_FILE = "database.db";
private static final int DATABASE_VERSION = 1;
public static SQLiteDatabase db;
SQLiteDatabase.CursorFactory factory;
private static final String DROP_TABLE = "DROP TABLE IF EXISTS item_table";
private static final String CREATE_TABLE = "CREATE TABLE IF NOT EXISTS item_table ( _id INTEGER PRIMARY KEY AUTOINCREMENT, date TEXT, steps INTEGER, weight TEXT)";
public DatabaseHelper(Context c) {
super(c, DATABASE_FILE, null, DATABASE_VERSION);
db = getWritableDatabase();
// db.execSQL(DROP_TABLE);
db.execSQL(CREATE_TABLE);
//db.openOrCreateDatabase(DATABASE_FILE, factory);
}
#Override
public void onCreate(SQLiteDatabase _db) {
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
public void addItem(ContentValues v)
{
}
}
ListFragment class
public class ListFragment extends Fragment {
public static final String TAG = "ListFragment.TAG";
public static ArrayList<ItemObject> items = new ArrayList<ItemObject>();
static ListView itemList;
static ItemAdapter adapter;
static int selectedPosition;
public static final int NEXT_REQUESTCODE = 2;
static Context context;
static ArrayList<ItemObject> placeholder;
static MainActivity activity;
static Uri uri = Uri.EMPTY;
//constructor
public static ListFragment newInstance(Context _context, ArrayList<ItemObject> _items) {
ListFragment fragment = new ListFragment();
return fragment;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
View theView = inflater.inflate(R.layout.list_fragment_layout, parent, false);
//create and attach custom adapter
MainActivity activity = (MainActivity) getActivity();
context = activity.getContext();
itemList = (ListView) theView.findViewById(R.id.itemList);
adapter = new ItemAdapter(context, items);
itemList.setAdapter(adapter);
itemList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapter, View v, int position, long arg3) {
selectedPosition = position;
openView(items.get(position));
}
});
loadData();
adapter.notifyDataSetChanged();
return theView;
}
//function for opening the "View details" view
public void openView(ItemObject selected) {
Intent detailActivity = new Intent(getActivity(), DetailActivity.class);
detailActivity.putExtra("weight", selected.getWeight());
detailActivity.putExtra("steps", selected.getSteps());
detailActivity.putExtra("date", selected.getDate());
detailActivity.putExtra("position", selectedPosition);
startActivityForResult(detailActivity, NEXT_REQUESTCODE);
}
public void saveItem(ItemObject _item) {
ContentValues v = new ContentValues();
v.put("weight", _item.getWeight());
v.put("steps", _item.getSteps());
v.put("date", _item.getDate());
activity.provider.insert(uri, v);
loadData();
}
#TargetApi(Build.VERSION_CODES.JELLY_BEAN)
public void loadData() {
String[] columns = new String[]{"weight","steps","date"};
Uri destination = Uri.parse(Environment.getDataDirectory().toString()+"/data/ContentProviderApp/database.db");
Cursor c = activity.provider.query(destination, columns, null, null, null, null);
if(c != null)
{
c.moveToFirst();
ArrayList<ItemObject> placeholder = new ArrayList<ItemObject>();
for(int i = 0; i < c.getCount(); i++)
{
int x = c.getCount();
ItemObject newItem = new ItemObject(c.getString(3),c.getInt(2), c.getString(1));
placeholder.add(newItem);
c.moveToNext();
}
items = placeholder;
}
}
public void deleteData() {
}
public void updateData() {
}
//handles a delete request from "view" activity
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == getActivity().RESULT_OK && requestCode == NEXT_REQUESTCODE) {
Bundle result = data.getExtras();
adapter.notifyDataSetChanged();
}
}
//Mandatory empty constructor for the fragment manager to instantiate the fragment (e.g. upon screen orientation changes).
public ListFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
//adds an object passed in from the activity
public void addObject(ItemObject _item) {
saveItem(_item);
//items.add(_item);
//adapter.notifyDataSetChanged();
//saveData();
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
// mListener = (OnFragmentInteractionListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement OnFragmentInteractionListener");
}
}
#Override
public void onDetach() {
super.onDetach();
// mListener = null;
}
}
ContentProvider class
public class ItemProvider extends ContentProvider {
DatabaseHelper helper;
public ItemProvider() {
}
public ItemProvider(DatabaseHelper _helper) {
helper = _helper;
}
#Override
public boolean onCreate() {
return false;
}
#Nullable
#Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
return helper.db.query("item_table", null, null, null, null, null, null, null);
}
#Nullable
#Override
public String getType(Uri uri) {
return null;
}
#Nullable
#Override
public Uri insert(Uri uri, ContentValues values) {
helper.db.insert("item_table", null, values);
return null;
}
#Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
helper.db.delete("item_table", selection, selectionArgs);
return 0;
}
#Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
helper.db.update("item_table", values, selection, selectionArgs);
return 0;
}
}
ItemAdapter class
public class ItemAdapter extends BaseAdapter {
private Context context;
private static final long ID_CONSTANT = 0x666666L;
private ArrayList<ItemObject> items;
public ItemAdapter()
{
}
public ItemAdapter(Context _context, ArrayList<ItemObject> _items)
{
context = _context;
items = _items;
}
#Override
public int getCount() {return items.size();}
#Override
public ItemObject getItem(int _position) {return items.get(_position);}
#Override
public long getItemId(int _position) { return ID_CONSTANT + _position;}
#Override
public View getView (int _position, View _convertView, ViewGroup _parent) {
if(_convertView == null) {
_convertView = LayoutInflater.from(context).inflate(R.layout.item_layout, _parent, false);
}
ItemObject item = getItem(_position);
TextView text = (TextView) _convertView.findViewById(R.id.weight);
text.setText(item.getWeight().toString());
text = (TextView) _convertView.findViewById(R.id.steps);
text.setText(Integer.toString(item.getSteps()));
text = (TextView) _convertView.findViewById(R.id.date);
text.setText(item.getDate().toString());
return _convertView;
}
}
I believe the problem is in the loadData method:
items = placeholder;
It should be items.addAll(placeholder).
Did you get a chance to test this?
In loadData() after the line item = placeholder add adapter.notifyDataSetChanged();.
Adding and removing items from RecyclerView is working, but i don't know if i have written a good method in database for deleting rows because only i'm saving condition when item is added and when it is removed and if i leave from app and come back, but previosly i have deleted some items, i'm seeing them there. So i need some help about this method in database for removing items and also implementing it in activity.
Here are my code:
DATABASE:
public class DBHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "items.db";
private static final int DATABASE_VERSION = 1;
private final String TABLE_ITEMS = "items";
private final String COLUMN_ID = "id";
private final String COLUMN_ITEM = "item";
private static DBHelper dbh;
private DBHelper(Activity activity) {
super(activity, DATABASE_NAME, null, DATABASE_VERSION);
}
public static synchronized DBHelper getConnection(Activity activity) {
if (dbh == null)
dbh = new DBHelper(activity);
return dbh;
}
#Override
public void onCreate(SQLiteDatabase db) {
String upitZaPravljanjeBaze =
"CREATE TABLE "+TABLE_ITEMS+"("+COLUMN_ID+" INTEGER PRIMARY KEY, "+COLUMN_ITEM+" TEXT);";
db.execSQL(upitZaPravljanjeBaze);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
if (newVersion > oldVersion) {
db.execSQL("DROP TABLE" + "TABLE_ITEMS");
onCreate(db);
}
}
public ArrayList<String> getAllItems() {
ArrayList<String> toRet = new ArrayList<String>();
SQLiteDatabase db = getReadableDatabase();
Cursor c = db.rawQuery("SELECT * FROM " + TABLE_ITEMS, null);
c.moveToFirst();
while(c.isAfterLast() == false) {
toRet.add(c.getString(c.getColumnIndex(COLUMN_ITEM)));
c.moveToNext();
}
return toRet;
}
public long saveItem(String item) {
SQLiteDatabase db = getWritableDatabase();
ContentValues cv = new ContentValues();
cv.put(COLUMN_ITEM, item);
return db.insert(TABLE_ITEMS, null, cv);
}
public boolean deleteItem(long rowId) {
SQLiteDatabase db = getReadableDatabase();
return db.delete(TABLE_ITEMS, COLUMN_ID + "=" + rowId, null) > 0;
}
}
ADAPTER:
public class AdapterRecyclerAnimators extends RecyclerView.Adapter<AdapterRecyclerAnimators.Holder> {
private ArrayList<String> mListData = new ArrayList<>();
private LayoutInflater mLayoutInflater;
public AdapterRecyclerAnimators(Context context) {
mLayoutInflater = LayoutInflater.from(context);
}
#Override
public Holder onCreateViewHolder(ViewGroup parent, int viewType) {
View row = mLayoutInflater.inflate(R.layout.custom_row_item, parent, false);
Holder holder = new Holder(row);
return holder;
}
#Override
public void onBindViewHolder(Holder holder, final int position) {
String data = mListData.get(position);
holder.textDataItem.setText(data);
holder.buttonDelete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
removeItem(position);
}
});
}
public void addItem(String item) {
mListData.add(item);
notifyItemInserted(mListData.size());
}
public void addAll(ArrayList<String> newList){
mListData = newList;
notifyDataSetChanged();
}
public void removeItem(String item) {
int position = mListData.indexOf(item);
if (position != -1) {
mListData.remove(item);
notifyItemRemoved(position);
}
}
public void removeItem(int position) {
mListData.remove(position);
notifyItemRemoved(position);
}
#Override
public int getItemCount() {
return mListData.size();
}
public static class Holder extends RecyclerView.ViewHolder {
TextView textDataItem;
ImageButton buttonDelete;
public Holder(View itemView) {
super(itemView);
textDataItem = (TextView) itemView.findViewById(R.id.text_item);
buttonDelete = (ImageButton) itemView.findViewById(R.id.button_delete);
}
}
}
MAIN ACTIVITY:
public class MainActivity extends BaseActivity {
//int containing the duration of the animation run when items are added or removed from the RecyclerView
public static final int ANIMATION_DURATION = 2000;
//edit text letting the user type item name to be added to the recylcerview
private EditText mInput;
//itemcounter for recyclerview
private TextView mItemCounter;
//recyclerview showing all items added by the user
private RecyclerView mRecyclerView;
private AdapterRecyclerAnimators mAdapter;
ArrayList<String> mListData = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initViews();
if(savedInstanceState != null){
ArrayList<String> items = savedInstanceState.getStringArrayList("items");
mListData.addAll(items);
mAdapter.notifyDataSetChanged();
}
}
#Override
public void onSaveInstanceState(Bundle outState) {
outState.putStringArrayList("items", mListData);
}
private void initViews(){
mInput = (EditText) findViewById(R.id.text_input);
mRecyclerView = (RecyclerView) findViewById(R.id.recyclerAnimatedItems);
mItemCounter = (TextView) findViewById(R.id.itemCounter);
mItemCounter.setText(String.valueOf(mRecyclerView.getChildCount()));
mAdapter = new AdapterRecyclerAnimators(this);
//set an animator on the RecyclerView that works only when items are added or removed
mRecyclerView.setItemAnimator(new SlideInLeftAnimator());
mRecyclerView.getItemAnimator().setAddDuration(ANIMATION_DURATION);
mRecyclerView.getItemAnimator().setRemoveDuration(ANIMATION_DURATION);
mAdapter.addAll(DBHelper.getConnection(MainActivity.this).getAllItems());
mRecyclerView.setAdapter(mAdapter);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
}
public void addItem(View view) {
//check if the EditText has valid contents
if (Util.hasValidContents(mInput)) {
DBHelper.getConnection(MainActivity.this)
.saveItem(mInput.getText().toString());
ArrayList<String> allItems = DBHelper.getConnection(MainActivity.this).getAllItems();
mAdapter.addAll(allItems);
mInput.setText("");
}
}
#Override
protected int getLayoutResourceId() {
return R.layout.activity_main;
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
These are your delete methode:
public void removeItem(String item) {
int position = mListData.indexOf(item);
if (position != -1) {
mListData.remove(item);
notifyItemRemoved(position);
}
}
public void removeItem(int position) {
mListData.remove(position);
notifyItemRemoved(position);
}
You remove the items from your list but you never remove them from your database. Call your delete method in both of of these methods and see if it works.
Don't necessarily think this will fix your problem but thought I would point it out, In your database delete method you have:
SQLiteDatabase db = getReadableDatabase();
You probably want to switch that:
SQLiteDatabase db = getWritableDatabase();