Todo app doesn't show the added task...its like not refreshing the added task. When i close and open the app again, then it shows. I am a beginner so i can,t guess out the problem.
Here is MainActivity.java
package com.ashtiv.dooo;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import android.content.ContentValues;
import android.content.DialogInterface;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import com.ashtiv.dooo.db.TaskContract;
import com.ashtiv.dooo.db.TaskDbHelper;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
private TaskDbHelper mHelper;
private ListView mTaskListView;
private ArrayAdapter<String> mAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mHelper = new TaskDbHelper(this);
mTaskListView = (ListView) findViewById(R.id.list_todo);
updateUI();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main_menu, menu);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_add_task:
final EditText taskEditText = new EditText(this);
AlertDialog dialog = new AlertDialog.Builder(this)
.setTitle("Add a new task")
.setMessage("What do you want to do next?")
.setView(taskEditText)
.setPositiveButton("Add", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
String task = String.valueOf(taskEditText.getText());
SQLiteDatabase db = mHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(TaskContract.TaskEntry.COL_TASK_TITLE, task);
db.insertWithOnConflict(TaskContract.TaskEntry.TABLE,
null,
values,
SQLiteDatabase.CONFLICT_REPLACE);
db.close();
}
})
.setNegativeButton("Cancel", null)
.create();
dialog.show();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
public void deleteTask(View view) {
View parent = (View) view.getParent();
TextView taskTextView = (TextView) parent.findViewById(R.id.task_title);
String task = String.valueOf(taskTextView.getText());
SQLiteDatabase db = mHelper.getWritableDatabase();
db.delete(TaskContract.TaskEntry.TABLE,
TaskContract.TaskEntry.COL_TASK_TITLE + " = ?",
new String[]{task});
db.close();
updateUI();
}
private void updateUI() {
ArrayList<String> taskList = new ArrayList<>();
SQLiteDatabase db = mHelper.getReadableDatabase();
Cursor cursor = db.query(TaskContract.TaskEntry.TABLE,
new String[]{TaskContract.TaskEntry._ID, TaskContract.TaskEntry.COL_TASK_TITLE},
null, null, null, null, null);
while (cursor.moveToNext()) {
int idx = cursor.getColumnIndex(TaskContract.TaskEntry.COL_TASK_TITLE);
taskList.add(cursor.getString(idx));
}
if (mAdapter == null) {
mAdapter = new ArrayAdapter<>(this,
R.layout.item_todo,
R.id.task_title,
taskList);
mTaskListView.setAdapter(mAdapter);
} else {
mAdapter.clear();
mAdapter.addAll(taskList);
mAdapter.notifyDataSetChanged();
}
cursor.close();
db.close();
}
}
Here is TaskContract.java
package com.ashtiv.dooo.db;
import android.provider.BaseColumns;
public class TaskContract {
public static final String DB_NAME = "com.ashtiv.dooo.db";
public static final int DB_VERSION = 1;
public class TaskEntry implements BaseColumns {
public static final String TABLE = "tasks";
public static final String COL_TASK_TITLE = "title";
}
}
Here is TaskDbHelper.java
package com.ashtiv.dooo.db;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class TaskDbHelper extends SQLiteOpenHelper {
public TaskDbHelper(Context context) {
super(context, TaskContract.DB_NAME, null, TaskContract.DB_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
String createTable = "CREATE TABLE " + TaskContract.TaskEntry.TABLE + " ( " +
TaskContract.TaskEntry._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
TaskContract.TaskEntry.COL_TASK_TITLE + " TEXT NOT NULL);";
db.execSQL(createTable);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TaskContract.TaskEntry.TABLE);
onCreate(db);
}
}
hERE is actvity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:tools="http://schemas.android.com/tools"
tools:context="com.ashtiv.dooo.MainActivity">
<ListView
android:id="#+id/list_todo"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
Here is item_todo.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center_vertical">
<TextView
android:id="#+id/task_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:text="Hello"
android:textSize="20sp" />
<Button
android:id="#+id/task_delete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:text="Done"
android:onClick="deleteTask"/>
</RelativeLayout>
The issue was you are not updating the UI after adding a new Todo.
To tackle the issue modify your code as follows.
Edit your onOptionsItemSelected to
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_add_task:
addTodo();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
and add this function.
private void addTodo() {
final EditText taskEditText = new EditText(this);
AlertDialog dialog = new AlertDialog.Builder(this)
.setTitle("Add a new task")
.setMessage("What do you want to do next?")
.setView(taskEditText)
.setPositiveButton("Add", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
String task = String.valueOf(taskEditText.getText());
SQLiteDatabase db = mHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(TaskContract.TaskEntry.COL_TASK_TITLE, task);
db.insertWithOnConflict(TaskContract.TaskEntry.TABLE,
null,
values,
SQLiteDatabase.CONFLICT_REPLACE);
db.close();
}
})
.setNegativeButton("Cancel", null)
.create();
dialog.show();
updateUI();
}
The issue you are seeing is because function updateUI() only gets called when your activity is created. You would have to devise a method where updateUI() gets called for each time you make an update to the table.
You could try calling updateUI() whenever you add or remove some tasks. For example:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_add_task:
final EditText taskEditText = new EditText(this);
AlertDialog dialog = new AlertDialog.Builder(this)
.setTitle("Add a new task")
.setMessage("What do you want to do next?")
.setView(taskEditText)
.setPositiveButton("Add", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
String task = String.valueOf(taskEditText.getText());
SQLiteDatabase db = mHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(TaskContract.TaskEntry.COL_TASK_TITLE, task);
db.insertWithOnConflict(TaskContract.TaskEntry.TABLE,
null,
values,
SQLiteDatabase.CONFLICT_REPLACE);
db.close();
//NEW LINE
updateUI();
}
})
.setNegativeButton("Cancel", null)
.create();
dialog.show();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
Related
Book Library Link
Currently, I am creating a note application with reference to the above link, but when I move from MainActivity to UpdateAcitivity, the content of the note I should have clicked is not displayed
Since the data is displayed in MainActivity, there is no problem in saving the data itself. However, the reason why the data is not displayed in UpdateActivity is that the withdrawal from the DB has failed. not. Please help.
UpdateActivity
package com.example.noteapp;
import android.content.DialogInterface;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.MultiAutoCompleteTextView;
import android.widget.Toast;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
public class UpdateActivity extends AppCompatActivity {
EditText title_input;
Button update_button, delete_button;
//↓What I Add
MultiAutoCompleteTextView message_input;
//MultiAutoCompleteTextView message_input = (MultiAutoCompleteTextView)findViewById(R.id.me);
String id, title;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_update);
title_input = findViewById(R.id.title_input2);
update_button = findViewById(R.id.ub);
delete_button = findViewById(R.id.db);
//↓What I add
message_input = findViewById(R.id.me);
//First we call this
getAndSetIntentData();
//Set actionbar title after getAndSetIntentData method
ActionBar ab = getSupportActionBar();
if (ab != null) {
ab.setTitle(title);
}
update_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//And only then we call this
MyDatabaseHelper myDB = new MyDatabaseHelper(UpdateActivity.this);
title = title_input.getText().toString().trim();
String message = message_input.getText().toString().trim();
myDB.updateData(id, title, message);
}
});
delete_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
confirmDialog();
}
});
}
void getAndSetIntentData(){
if(getIntent().hasExtra("id") && getIntent().hasExtra("title") && getIntent().hasExtra("message")){
//Getting Data from Intent
id = getIntent().getStringExtra("id");
title = getIntent().getStringExtra("title");
String message = getIntent().getStringExtra("message");
//Setting Intent Data
title_input.setText(title);
message_input.setText(message);
Log.d("stev", title);
}else{
Toast.makeText(this, "No data.", Toast.LENGTH_SHORT).show();
}
}
void confirmDialog(){
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Delete " + title + " ?");
builder.setMessage("Are you sure you want to delete " + title + " ?");
builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
MyDatabaseHelper myDB = new MyDatabaseHelper(UpdateActivity.this);
myDB.deleteOneRow(id);
finish();
}
});
builder.setNegativeButton("No", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
}
});
builder.create().show();
}
}
activity_updateXML
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="30dp"
tools:context=".UpdateActivity">
<EditText
android:id="#+id/title_input2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="84dp"
android:ems="10"
android:hint="Title"
android:inputType="textPersonName"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.266"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<MultiAutoCompleteTextView
android:id="#+id/me"
android:layout_width="355dp"
android:layout_height="148dp"
android:layout_marginTop="16dp"
android:ems="10"
android:hint="Message"
android:inputType="textPersonName"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/title_input2" />
<Button
android:id="#+id/ub"
android:layout_width="match_parent"
android:layout_height="70dp"
android:text="Update"
android:textAllCaps="false"
android:textSize="20sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
tools:layout_editor_absoluteY="321dp" />
<Button
android:id="#+id/db"
android:layout_width="match_parent"
android:layout_height="70dp"
android:background="#color/red"
android:text="Delete"
android:textSize="20sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.483"
app:layout_constraintStart_toStartOf="parent"
tools:layout_editor_absoluteY="421dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
MyDatabaseHelper
package com.example.noteapp;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.widget.Toast;
import androidx.annotation.Nullable;
class MyDatabaseHelper extends SQLiteOpenHelper {
private Context context;
private static final String DATABASE_NAME = "note.db";
private static final int DATABASE_VERSION = 1;
private static final String TABLE_NAME = "my_note";
private static final String COLUMN_ID = "_id";
private static final String COLUMN_TITLE = "title";
private static final String COLUMN_MESSAGE = "message";
MyDatabaseHelper(#Nullable Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
this.context = context;
}
#Override
public void onCreate(SQLiteDatabase db) {
String query = "CREATE TABLE " + TABLE_NAME +
" (" + COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
COLUMN_TITLE + " TEXT, " +
COLUMN_MESSAGE + " TEXT);";
db.execSQL(query);
}
#Override
public void onUpgrade(SQLiteDatabase db, int i, int i1) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
onCreate(db);
}
void addNote(String title, String message){
SQLiteDatabase db = this.getWritableDatabase();
ContentValues cv = new ContentValues();
cv.put(COLUMN_TITLE, title);
cv.put(COLUMN_MESSAGE, message);
long result = db.insert(TABLE_NAME,null, cv);
if(result == -1){
Toast.makeText(context, "Failed", Toast.LENGTH_SHORT).show();
}else {
Toast.makeText(context, "Added Successfully!", Toast.LENGTH_SHORT).show();
}
}
Cursor readAllData(){
String query = "SELECT * FROM " + TABLE_NAME;
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = null;
if(db != null){
cursor = db.rawQuery(query, null);
}
return cursor;
}
void updateData(String row_id, String title, String message){
SQLiteDatabase db = this.getWritableDatabase();
ContentValues cv = new ContentValues();
cv.put(COLUMN_TITLE, title);
cv.put(COLUMN_MESSAGE, message);
long result = db.update(TABLE_NAME, cv, "_id=?", new String[]{row_id});
if(result == -1){
Toast.makeText(context, "Failed", Toast.LENGTH_SHORT).show();
}else {
Toast.makeText(context, "Updated Successfully!", Toast.LENGTH_SHORT).show();
}
}
void deleteOneRow(String row_id){
SQLiteDatabase db = this.getWritableDatabase();
long result = db.delete(TABLE_NAME, "_id=?", new String[]{row_id});
if(result == -1){
Toast.makeText(context, "Failed to Delete.", Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(context, "Successfully Deleted.", Toast.LENGTH_SHORT).show();
}
}
void deleteAllData(){
SQLiteDatabase db = this.getWritableDatabase();
db.execSQL("DELETE FROM " + TABLE_NAME);
}
}
MainActivity
package com.example.noteapp;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
RecyclerView recyclerView;
FloatingActionButton add_button;
ImageView empty_imageview;
TextView no_data;
MyDatabaseHelper myDB;
ArrayList<String> note_id, note_title, note_message;
//CustomAdapter customAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = findViewById(R.id.recyclerView);
add_button = findViewById(R.id.add_button);
empty_imageview = findViewById(R.id.empty_imageview);
no_data = findViewById(R.id.no_data);
add_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(MainActivity.this, InsertActivity.class);
startActivity(intent);
}
});
myDB = new MyDatabaseHelper(MainActivity.this);
note_id = new ArrayList<>();
note_title = new ArrayList<>();
note_message = new ArrayList<>();
storeDataInArrays();
CustomAdapter customAdapter = new CustomAdapter(MainActivity.this, this, note_id, note_title, note_message);
recyclerView.setAdapter(customAdapter);
recyclerView.setLayoutManager(new LinearLayoutManager(MainActivity.this));
}
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == 1){
recreate();
}
}
void storeDataInArrays(){
Cursor cursor = myDB.readAllData();
if(cursor.getCount() == 0){
empty_imageview.setVisibility(View.VISIBLE);
no_data.setVisibility(View.VISIBLE);
}else{
while (cursor.moveToNext()){
note_id.add(cursor.getString(0));
note_title.add(cursor.getString(1));
note_message.add(cursor.getString(2));
}
empty_imageview.setVisibility(View.GONE);
no_data.setVisibility(View.GONE);
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.my_menu, menu);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if(item.getItemId() == R.id.delete_all){
confirmDialog();
}
return super.onOptionsItemSelected(item);
}
void confirmDialog(){
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Delete All?");
builder.setMessage("Are you sure you want to delete all Data?");
builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
MyDatabaseHelper myDB = new MyDatabaseHelper(MainActivity.this);
myDB.deleteAllData();
//Refresh Activity
Intent intent = new Intent(MainActivity.this, MainActivity.class);
startActivity(intent);
finish();
}
});
builder.setNegativeButton("No", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
}
});
builder.create().show();
}
}
================CustomeAdapter====================
CustomeAdapter
package com.example.noteapp;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.MyViewHolder> {
private Context context;
private Activity activity;
private ArrayList note_id, note_title, note_message;
CustomAdapter(Activity activity, Context context, ArrayList note_id, ArrayList note_title, ArrayList note_message){
this.activity = activity;
this.context = context;
this.note_id = note_id;
this.note_title = note_title;
this.note_message = note_message;
}
#NonNull
#Override
public MyViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(R.layout.my_row, parent, false);
return new MyViewHolder(view);
}
#RequiresApi(api = Build.VERSION_CODES.M)
#Override
public void onBindViewHolder(#NonNull final MyViewHolder holder, final int position) {
holder.note_id_txt.setText(String.valueOf(note_id.get(position)));
holder.note_title_txt.setText(String.valueOf(note_title.get(position)));
holder.note_message_txt.setText(String.valueOf(note_message.get(position)));
//Recyclerview onClickListener
holder.mainLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(context, UpdateActivity.class);
intent.putExtra("id", String.valueOf(note_id.get(position)));
intent.putExtra("title", String.valueOf(note_title.get(position)));
intent.putExtra("author", String.valueOf(note_message.get(position)));
activity.startActivityForResult(intent, 1);
}
});
}
#Override
public int getItemCount() {
return note_id.size();
}
class MyViewHolder extends RecyclerView.ViewHolder {
TextView note_id_txt, note_title_txt, note_message_txt;
LinearLayout mainLayout;
MyViewHolder(#NonNull View itemView) {
super(itemView);
note_id_txt = itemView.findViewById(R.id.note_id_txt);
note_title_txt = itemView.findViewById(R.id.note_title_txt);
note_message_txt = itemView.findViewById(R.id.note_message_txt);
mainLayout = itemView.findViewById(R.id.mainLayout);
//Animate Recyclerview
Animation translate_anim = AnimationUtils.loadAnimation(context, R.anim.translate_anim);
mainLayout.setAnimation(translate_anim);
}
}
}
I think your problem in the CustomeAdapter exactly in onBindViewHolder.
replace this code from onBindViewHolder:
holder.mainLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(context, UpdateActivity.class);
intent.putExtra("id", holder.note_id_txt.getText().toString());
intent.putExtra("title",holder.note_title_txt.getText().toString() );
intent.putExtra("author", holder.note_message_txt.getText().toString());
activity.startActivityForResult(intent, 1);
}
});
and put this inside your viewHolder class:
MyViewHolder(#NonNull View itemView) {
super(itemView);
note_id_txt = itemView.findViewById(R.id.note_id_txt);
note_title_txt = itemView.findViewById(R.id.note_title_txt);
note_message_txt = itemView.findViewById(R.id.note_message_txt);
mainLayout = itemView.findViewById(R.id.mainLayout);
//Animate Recyclerview
Animation translate_anim = AnimationUtils.loadAnimation(context, R.anim.translate_anim);
mainLayout.setAnimation(translate_anim);
mainLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(context, UpdateActivity.class);
intent.putExtra("id", note_id_txt.getText().toString());
intent.putExtra("title",note_title_txt.getText().toString() );
intent.putExtra("author", note_message_txt.getText().toString());
activity.startActivityForResult(intent, 1);
}
});
}
My app has a registration screen for blood donors and the blood type field is a spinner. I save all the donor information in an SQLite database. Now I need to retrieve it and show it for a list showing all the registered blood donors with their blood types.
How can I do that?
I've attached all my code below. The main problems appear in RegisterActivity.java and DonorList.java.
RegisterActivity.java
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.Toast;
public class RegisterActivity extends AppCompatActivity {
EditText edtname, edtnumber;
Spinner spblood;
Button btnregister, btnlist;
public static SQLiteHelper sqLiteHelper;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_register);
init();
Spinner spinner = findViewById(R.id.blood_selector);
// Create an ArrayAdapter using the string array and a default spinner layout
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,
R.array.blood_type, android.R.layout.simple_spinner_item);
// Specify the layout to use when the list of choices appears
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
// Apply the adapter to the spinner
spinner.setAdapter(adapter);
sqLiteHelper = new SQLiteHelper(this, "Donors.sqlite", null, 1);
sqLiteHelper.queryData("CREATE TABLE IF NOT EXISTS DONORS (Id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR, number VARCHAR, blood VARCHAR)");
btnregister.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
try {
sqLiteHelper.insertData(
edtname.getText().toString().trim(),
edtnumber.getText().toString().trim(),
spblood
);
}
catch (Exception e) {
e.printStackTrace();
}
}
});
btnlist.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(RegisterActivity.this, DonorList.class);
startActivity(intent);
}
});
}
private void init() {
edtname = findViewById(R.id.name_input);
edtnumber = findViewById(R.id.numberinput);
spblood = findViewById(R.id.blood_selector);
btnregister = findViewById(R.id.register_button);
btnlist = findViewById(R.id.list_button);
}
}
DonorList.java
import android.database.Cursor;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.widget.ListView;
import android.widget.Spinner;
import java.util.ArrayList;
public class DonorList extends AppCompatActivity {
ListView listView;
ArrayList<Donor> list;
DonorListAdapter adapter = null;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView) findViewById(R.id.contacts_list);
list = new ArrayList<>();
adapter = new DonorListAdapter(this, R.layout.activity_main, list);
listView.setAdapter(adapter);
Cursor cursor = RegisterActivity.sqLiteHelper.getData("SELECT * FROM DONORS");
list.clear();
while (cursor.moveToNext()) {
String name = cursor.getString(1);
String number = cursor.getString(2);
String blood = cursor.getString(3);
list.add(new Donor(name, number, blood));
}
adapter.notifyDataSetChanged();
}
}
Donor.java
import android.widget.Spinner;
public class Donor {
private String name;
private String number;
private Spinner blood;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
public Spinner getBlood() {
return blood;
}
public void setBlood(Spinner blood) {
this.blood = blood;
}
public Donor(String name, String number, Spinner blood) {
this.name = name;
this.number = number;
this.blood = blood;
}
}
SQLiteHelper.java
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteStatement;
import android.widget.Spinner;
public class SQLiteHelper extends SQLiteOpenHelper {
public SQLiteHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
super(context, name, factory, version);
}
public void queryData(String sql) {
SQLiteDatabase database = getWritableDatabase();
database.execSQL(sql);
}
public void insertData(String name, String number, Spinner blood) {
SQLiteDatabase database = getWritableDatabase();
String sql = "INSERT INTO DONORS (name, number, blood) values (?, ?, ?)";
SQLiteStatement statement = database.compileStatement(sql);
statement.clearBindings();
statement.bindString(1, name);
statement.bindString(2, number);
statement.bindString(3, blood.getSelectedItem().toString());
statement.executeInsert();
}
public Cursor getData(String sql) {
SQLiteDatabase database = getReadableDatabase();
return database.rawQuery(sql, null);
}
}
DonorListAdapter.java
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
import java.util.ArrayList;
public class DonorListAdapter extends BaseAdapter {
private Context context;
private int layout;
private ArrayList<Donor> donorList;
public DonorListAdapter(Context context, int layout, ArrayList<Donor> donorList) {
this.context = context;
this.layout = layout;
this.donorList = donorList;
}
#Override
public int getCount() {
return donorList.size();
}
#Override
public Object getItem(int position) {
return donorList.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
private class ViewHolder {
TextView txtname, txtnumber, txtblood;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
ViewHolder holder = new ViewHolder();
if (row == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (inflater != null) {
row = inflater.inflate(layout, null);
}
if (row != null) {
holder.txtname = row.findViewById(R.id.name_input);
}
if (row != null) {
holder.txtnumber = row.findViewById(R.id.numberinput);
}
if (row != null) {
holder.txtblood = (TextView) row.findViewById(R.id.blood_selector);
}
if (row != null) {
row.setTag(holder);
}
}
else {
holder = (ViewHolder) row.getTag();
}
Donor donor = donorList.get(position);
holder.txtname.setText(donor.getName());
holder.txtnumber.setText(donor.getNumber());
holder.txtblood.setText(donor.getBlood().toString());
return row;
}
}
activity_main.xml
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.lumen.dayem.blooddonor.MainActivity">
<ListView
android:id="#+id/contacts_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:choiceMode="singleChoice">
</ListView>
</LinearLayout>
activity_register.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<EditText
android:id="#+id/name_input"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/person_name"
android:ems="10"
android:inputType="textCapWords"
android:layout_marginBottom="5sp" />
<EditText
android:id="#+id/numberinput"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/hint"
android:ems="10"
android:inputType="phone"
android:layout_marginBottom="5sp" />
<TextView
android:id="#+id/blood"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/blood_type"
android:layout_marginBottom="10sp"/>
<Spinner
android:id="#+id/blood_selector"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:entries="#array/blood_type"
android:prompt="#string/blood_select"
android:layout_marginBottom="5sp"/>
<Button
android:id="#+id/register_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/register" />
<Button
android:id="#+id/list_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/show_donors" />
</LinearLayout>
contact_item.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/contact_name"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="#string/contact_name"
android:textSize="22sp"/>
<TextView
android:id="#+id/contact_number"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textAppearance="?android:textAppearanceSmall"
android:text="#string/contact_number"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginLeft="29sp"
android:layout_marginStart="29sp"
android:layout_marginTop="31sp" />
<TextView
android:id="#+id/contact_blood"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textAppearance="?android:textAppearanceMedium"
android:text="#string/blood_type"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginLeft="300sp"
android:layout_marginStart="300sp"
android:layout_marginTop="30sp"/>
</RelativeLayout>
Your class Donor seems to have a field blood of type Spinner. I changed the type to String because a data class should not contain any Views:
public class Donor
{
private String name;
private String number;
private String blood;
// Getters and Setters here...
public Donor(String name, String number, String blood) {
this.name = name;
this.number = number;
this.blood = blood;
}
}
The SQLiteHelper should have a static getInstance() method so you can avoid having it as a static field in RegisterActivity. Also, I think that the database setup should be encapsulated. The Activity does not need to know anything about the database implementation. So I moved the DDL to the SQLiteHelper's onCreate() and dropped queryData(). For the same reason, I changed getData(String sql) to getDonors(). Lastly, insertData() should take data as parameters not Views. So one should not pass the Spinner but the selected item's value.
My version of SQLiteHelper.java:
public class SQLiteHelper extends SQLiteOpenHelper{
private static SQLiteHelper sqliteHelper;
private static String dbName = "Donors.sqlite";
private static int version = 1;
private static final String CREATE_TABLE_DONORS = "CREATE TABLE IF NOT EXISTS DONORS (Id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR, number VARCHAR, blood VARCHAR)";
/**
* We use the application Context under the hood because this helps to avoid Exceptions
* #param ctx
*/
private SQLiteHelper(Context ctx){
super(ctx.getApplicationContext(), dbName, null, version);
}
/**
* SQLiteHelper as a Singleton
* #param ctx any Context
* #return x
*/
public static SQLiteHelper getInstance(Context ctx)
{
if(sqliteHelper == null){
sqliteHelper = new SQLiteHelper(ctx);
}
return sqliteHelper;
}
#Override
public void onCreate(SQLiteDatabase db)
{
db.execSQL(CREATE_TABLE_DONORS);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{
// necessary if you have a new database version
}
public void insertData(String name, String number, String blood) {
SQLiteDatabase database = getWritableDatabase();
String sql = "INSERT INTO DONORS (name, number, blood) values (?, ?, ?)";
SQLiteStatement statement = database.compileStatement(sql);
statement.clearBindings();
statement.bindString(1, name);
statement.bindString(2, number);
statement.bindString(3, blood);
statement.executeInsert();
}
public Cursor getDonors() {
String sql = "SELECT * FROM DONORS";
SQLiteDatabase database = getReadableDatabase();
return database.rawQuery(sql, null);
}
}
The updated RegisterActivity.java (note that I got rid of the local variable spinner and only used spblood):
public class RegisterActivity extends AppCompatActivity
{
private EditText edtname, edtnumber;
private Spinner spblood;
private Button btnregister, btnlist;
private SQLiteHelper sqLiteHelper;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_register);
init();
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,
R.array.blood_type, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spblood.setAdapter(adapter);
sqLiteHelper = SQLiteHelper.getInstance(this);
btnregister.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
try {
sqLiteHelper.insertData(
edtname.getText().toString().trim(),
edtnumber.getText().toString().trim(),
spblood.getSelectedItem().toString()
);
}
catch (Exception e) {
e.printStackTrace();
}
}
});
btnlist.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(RegisterActivity.this, DonorList.class);
startActivity(intent);
}
});
}
private void init() {
edtname = findViewById(R.id.name_input);
edtnumber = findViewById(R.id.numberinput);
spblood = findViewById(R.id.blood_selector);
btnregister = findViewById(R.id.register_button);
btnlist = findViewById(R.id.list_button);
}
}
The changes to DonorList and the Adapter are due to the changes I made to SQLiteHelper and Donor. In addition to that, you need to pass the resource id of the list row to the Adapter's Constructor not the resource id of the Activity's layout. Similarly, the R.id.... values for the TextViews in the list row have to match those in contact_item.xml
DonorList.java
public class DonorList extends AppCompatActivity
{
private ListView listView;
private ArrayList<Donor> list;
private DonorListAdapter adapter = null;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView) findViewById(R.id.contacts_list);
list = new ArrayList<>();
adapter = new DonorListAdapter(this, R.layout.contact_item, list);
listView.setAdapter(adapter);
Cursor cursor = SQLiteHelper.getInstance(this).getDonors();
list.clear();
while (cursor.moveToNext()) {
String name = cursor.getString(1);
String number = cursor.getString(2);
String blood = cursor.getString(3);
list.add(new Donor(name, number, blood));
}
adapter.notifyDataSetChanged();
}
}
And finally, the Adapter:
public class DonorListAdapter extends BaseAdapter
{
private Context context;
private int layout;
private ArrayList<Donor> donorList;
public DonorListAdapter(Context context, int layout, ArrayList<Donor> donorList) {
this.context = context;
this.layout = layout;
this.donorList = donorList;
}
#Override
public int getCount() {
return donorList.size();
}
#Override
public Object getItem(int position) {
return donorList.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
private class ViewHolder {
TextView txtname, txtnumber, txtblood;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
if (row == null) {
ViewHolder holder = new ViewHolder();
row = LayoutInflater.from(context).inflate(layout, null);
holder.txtname = (TextView)row.findViewById(R.id.contact_name);
holder.txtnumber = (TextView)row.findViewById(R.id.contact_number);
holder.txtblood = (TextView) row.findViewById(R.id.contact_blood);
row.setTag(holder);
}
ViewHolder viewHolder = (ViewHolder) row.getTag();
Donor donor = donorList.get(position);
viewHolder.txtname.setText(donor.getName());
viewHolder.txtnumber.setText(donor.getNumber());
viewHolder.txtblood.setText(donor.getBlood());
return row;
}
}
Enjoy!
Im trying to make mp3 player in android studio, i have loaded all songs from my phone in arraylist called audioList but i cant make recyclerView, can anyone find mistake?
MainActivity.java
import android.Manifest;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.IBinder;
import android.provider.MediaStore;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.Toast;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
private MediaPlayerService player;
private boolean serviceBound = false;
private ArrayList<Audio> audioList;
private RWAdapter adapt;
RecyclerView recyclerView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.M){
requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 0);
}
RecyclerView rv = (RecyclerView) findViewById(R.id.myRecyclerView);
assert rv != null;
rv.setLayoutManager(new LinearLayoutManager(this));;
loadAudio();
RWAdapter rwa = new RWAdapter(audioList);
rv.setAdapter(rwa);
playAudio(audioList.get(22).getData());
}
//ulozi sa instancia
#Override
protected void onSaveInstanceState(Bundle outState) {
outState.putBoolean("ServiceState", serviceBound);
super.onSaveInstanceState(outState);
}
//obnovi sa instancia tam kde bola naposledy ulozena
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
serviceBound = savedInstanceState.getBoolean("ServiceState");
}
//znici instanciu
#Override
protected void onDestroy() {
super.onDestroy();
if(serviceBound){
unbindService(serviceConnection);
player.stopSelf();
}
}
//viaze tuto triedu s prehravacom, nastavi hodnotu serviceBound na true ked sa vytvori spojenie
private ServiceConnection serviceConnection = new ServiceConnection(){
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
MediaPlayerService.LocalBinder binder = (MediaPlayerService.LocalBinder) service;
player = binder.getService();
serviceBound = true;
Toast.makeText(MainActivity.this, "Service bound", Toast.LENGTH_SHORT).show();
}
#Override
public void onServiceDisconnected(ComponentName name) {
serviceBound = false;
}
};
//Metoda dava spravu,intnet druhej aktivite o spusteni hudby
private void playAudio(String media){
if(!serviceBound){
Intent playerIntent = new Intent(this,MediaPlayerService.class);
playerIntent.putExtra("media",media);
startService(playerIntent);
bindService(playerIntent, serviceConnection, Context.BIND_AUTO_CREATE);
} else {
}
}
//nacita pesnicky z mobilu
private void loadAudio() {
ContentResolver contentResolver = getContentResolver();
Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
String selection = MediaStore.Audio.Media.IS_MUSIC + "!= 0";
String sortOrder = MediaStore.Audio.Media.TITLE + " ASC";
Cursor cursor = contentResolver.query(uri, null, selection, null, sortOrder);
if(cursor != null && cursor.getCount() > 0) {
audioList = new ArrayList<>();
while (cursor.moveToNext()){
String data = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DATA));
String title = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.TITLE));
String album = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM));
String artist = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST));
audioList.add(new Audio(data, title, album, artist));
}
}
cursor.close();
}
}
RecyclerViewAdapter
package com.example.rsabo.mp3player;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.Collections;
import java.util.List;
/**
* Created by RSabo on 15-Apr-17.
*/
public class RWAdapter extends RecyclerView.Adapter<RWAdapter.MyViewHolder>{
private List<Audio> list;
private Context context;
public class MyViewHolder extends RecyclerView.ViewHolder {
TextView title;
ImageView play_pause;
MyViewHolder(View itemView) {
super(itemView);
title = (TextView) itemView.findViewById(R.id.title);
play_pause = (ImageView) itemView.findViewById(R.id.play_pause);
itemView.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
Audio currentAudio = list.get(getAdapterPosition());
}
});
}
}
public RWAdapter(List<Audio> list) {
this.list = list;
this.context = context;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
//Inflate the layout, initialize the View Holder
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_songov, parent, false);
return new MyViewHolder(v);
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
//Use the provided View Holder on the onCreateViewHolder method to populate the current row on the RecyclerView
holder.title.setText(list.get(position).getTitle());
}
#Override
public int getItemCount() {
//returns the number of elements the RecyclerView will display
return list.size();
}
}
activity_main.xml
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.example.rsabo.mp3player.MainActivity">
<include layout="#layout/list_songov" />
list_songov.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="#+id/myRecyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
Check following code in your adapter .
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
//Inflate the layout, initialize the View Holder
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_songov, parent, false);
return new MyViewHolder(v);
}
Now , inside list_songov.xml layout file , there is no TextView , ImageView for Title and play_pause .
Please check if you have set the correct layout inside onCreateViewHolder() .
You are not calling the function loadAudio() , you should call this function when instatiating your adapter class
Basically your loadAudio() method should be AsyncTask (Background process) you have to wait while it load, so use AsyncTask and set adapter in onPostExecute method see example AsyncTask Android example or this https://developer.android.com/reference/android/os/AsyncTask.html
//nacita pesnicky z mobilu
private void loadAudio() {
ContentResolver contentResolver = getContentResolver();
Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
String selection = MediaStore.Audio.Media.IS_MUSIC + "!= 0";
String sortOrder = MediaStore.Audio.Media.TITLE + " ASC";
Cursor cursor = contentResolver.query(uri, null, selection, null, sortOrder);
if(cursor != null && cursor.getCount() > 0) {
audioList = new ArrayList<>();
while (cursor.moveToNext()){
String data = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DATA));
String title = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.TITLE));
String album = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM));
String artist = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST));
audioList.add(new Audio(data, title, album, artist));
}
}
cursor.close();
}
In my note app for Android, if I press long on a note then chose "Delete" to delete the note, the note still exists in the list, then after I close the app then return to it, the note is gone!
Hint: I am uses the onContextItemSelected method to show the "Delete" option.
How I can delete the note from the list and from the database?!
The MainActivity class which contains the onContextItemSelected method:
package com.twitter.i_droidi.mynotes;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import java.util.List;
public class MainActivity extends ActionBarActivity implements AdapterView.OnItemClickListener {
ListView lv;
NotesDataSource nDS;
List<NotesModel> notesList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
nDS = new NotesDataSource(this);
lv = (ListView) findViewById(R.id.lv);
nDS.open();
notesList = nDS.getAllNotes();
nDS.close();
String[] notes = new String[notesList.size()];
for (int i = 0; i < notesList.size(); i++) {
notes[i] = notesList.get(i).getTitle();
}
ArrayAdapter<String> adapter = new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_1,
android.R.id.text1, notes);
lv.setAdapter(adapter);
registerForContextMenu(lv);
lv.setOnItemClickListener(this);
}
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent nView = new Intent(this, Second2.class);
nView.putExtra("id", notesList.get(position).getId());
nView.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(nView);
}
#Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_delete, menu);
super.onCreateContextMenu(menu, v, menuInfo);
}
#Override
public boolean onContextItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.delete:
nDS.open();
nDS.deleteNote("id"); // Check...!!!
nDS.close();
Toast nDelete = Toast.makeText(this, R.string.deleted, Toast.LENGTH_LONG);
nDelete.show();
}
return super.onContextItemSelected(item);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.mainMenuNewNote:
Intent nNote = new Intent(this, Second.class);
startActivity(nNote);
return true;
case R.id.mainMenuAbout:
AlertDialog.Builder aboutDialog = new AlertDialog.Builder(this);
aboutDialog.setTitle(getString(R.string.about_title));
aboutDialog.setMessage(R.string.about_body);
aboutDialog.setIcon(R.drawable.my_notes);
aboutDialog.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface aboutDialog, int witch) {
// Do Not Do Anything.
}
});
aboutDialog.show();
return true;
case R.id.mainMenuExit:
AlertDialog.Builder exDialog = new AlertDialog.Builder(this);
exDialog.setTitle(R.string.exit_title);
exDialog.setMessage(R.string.exit_body);
exDialog.setIcon(R.drawable.my_notes);
exDialog.setNegativeButton(R.string.yes, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface exDialog, int which) {
finish();
}
});
exDialog.setPositiveButton(R.string.no, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface exDialog, int which) {
// Do Not Do Anything.
}
});
exDialog.show();
return true;
}
return super.onOptionsItemSelected(item);
}
}
The DB class:
package com.twitter.i_droidi.mynotes;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class DB extends SQLiteOpenHelper {
private static final String DB_NAME = "MyNotes";
private static final int DB_VERSION = 1;
public static final String TABLE_NAME = "MyNotes";
public static final String ID = "id";
public static final String TITLE = "title";
public static final String BODY = "body";
private static final String DB_CREATE = "create table " + TABLE_NAME + " (" + ID + " integer primary key autoincrement, " +
TITLE + " text not null, " + BODY + " text not null)";
public DB(Context context) {
super(context, DB_NAME, null, DB_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(DB_CREATE);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
onCreate(db);
}
}
The NotesDataSource class:
package com.twitter.i_droidi.mynotes;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;
import java.util.ArrayList;
import java.util.List;
public class NotesDataSource {
DB myDB;
SQLiteDatabase sql;
String[] getAllColumns = new String[]{DB.ID, DB.TITLE, DB.BODY};
public NotesDataSource(Context context) {
myDB = new DB(context);
}
public void open() {
try {
sql = myDB.getWritableDatabase();
} catch (Exception ex) {
Log.d("Error in your database!", ex.getMessage());
}
}
public void close() {
sql.close();
}
public void createNote(String title, String body) {
ContentValues note = new ContentValues();
note.put(myDB.TITLE, title);
note.put(myDB.BODY, body);
sql.insert(myDB.TABLE_NAME, null, note);
}
public NotesModel getNote(int id) {
NotesModel note = new NotesModel();
Cursor cursor = sql.rawQuery("SELECT * FROM " + DB.TABLE_NAME + " WHERE " + DB.ID + " = ?", new String[]{id + ""});
if (cursor.getCount() > 0) {
cursor.moveToFirst();
note.setId(cursor.getInt(0));
note.setTitle(cursor.getString(1));
note.setBody(cursor.getString(2));
cursor.close();
}
return note;
}
public void updateNote(int id, String title, String body) {
ContentValues note = new ContentValues();
note.put(myDB.TITLE, title);
note.put(myDB.BODY, body);
sql.update(myDB.TABLE_NAME, note, myDB.ID + " = " + id, null);
}
public void deleteNote(Object id) {
sql.delete(myDB.TABLE_NAME, myDB.ID + " = " + id, null);
}
public List<NotesModel> getAllNotes() {
List<NotesModel> notesList = new ArrayList<NotesModel>();
StringBuffer selectQuery = new StringBuffer();
selectQuery.append("SELECT * FROM "+ myDB.TABLE_NAME +"");
Cursor cursor = sql.rawQuery(selectQuery.toString(), null);
if(cursor != null && cursor.moveToFirst()) {
do {
NotesModel notes = new NotesModel();
notes.setId(cursor.getInt(0));
notes.setTitle(cursor.getString(1));
notes.setBody(cursor.getString(2));
notesList.add(notes);
} while (cursor.moveToNext());
}
cursor.close();
return notesList;
}
}
After removing item from database
Remove the deleted item from
String[] notes
by using
notes.remove(position);
nd call
adapter.notifyDataSetChanged();
I would like to implement a database which consists of 2 tables, number and receivernumber. In fact, I have 2 xml files, one using number table, another using receivernumber. However, the code below only allows the first table to be used for both of the xmls.
Previously, I have tried implementing 2 different sets of class files, as stated below. But it crashes the entire app instead. So I tried changing to using the same class file with the receivernumber table being number2 instead. Now, both of the activity/xml file uses the first database but not the second. Please advice. Thanks in advance.
Note: there are no error logs available as it is working. Just that the table used for both activities are the same, but it's supposed to be different.
Set_numbers_to_forward.java
import java.util.ArrayList;
import java.util.List;
import com.example.awkwardpanda_redirectcall.DBAdapter;
import com.example.awkwardpanda_redirectcall.CallAdapter;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.database.Cursor;
public class Set_numbers_to_forward extends Activity {
Context mContext;
ArrayAdapter<String> adapter;
List<String> adapterData;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.set_numbers_to_forward);
mContext = this;
ListView list = (ListView) findViewById(R.id.number_list);
adapterData = new ArrayList<String>();
DBAdapter db = new DBAdapter(this);
// ---get all contacts---
db.open();
Cursor c = db.getAllContacts();
if (c.moveToFirst()) {
do {
adapterData.add(c.getString(1));
} while (c.moveToNext());
}
db.close();
adapter = new CallAdapter(this,
R.layout.set_numbers_to_forward_editable, adapterData);
list.setAdapter(adapter);
} // end onCreate
public void onCreate2(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.set_number_to_receive);
mContext = this;
ListView list = (ListView) findViewById(R.id.receiver_number);
adapterData = new ArrayList<String>();
DBAdapter db = new DBAdapter(this);
// ---get all contacts---
db.open();
Cursor c = db.getAllContacts();
if (c.moveToFirst()) {
do {
adapterData.add(c.getString(1));
} while (c.moveToNext());
}
db.close();
adapter = new CallAdapter(this,
R.layout.set_number_to_receive_editable, adapterData);
list.setAdapter(adapter);
} // end onCreate
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.addbtn, menu);
return true;
}
public boolean onCreateOptionsMenu2(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.addbtn2, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("New Phone Number");
builder.setMessage("Enter Phone Number :");
final EditText input = new EditText(Set_numbers_to_forward.this);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT);
input.setLayoutParams(lp);
builder.setView(input);
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
DBAdapter db = new DBAdapter(mContext);
db.open();
db.insertContact(input.getText().toString());
db.close();
adapterData.add(input.getText().toString());
adapter.notifyDataSetChanged();
}
});
builder.create().show();
return true;
}
public boolean onOptionsItemSelected2(MenuItem item) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("New Phone Number");
builder.setMessage("Enter Phone Number :");
final EditText input = new EditText(Set_numbers_to_forward.this);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT);
input.setLayoutParams(lp);
builder.setView(input);
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
DBAdapter db = new DBAdapter(mContext);
db.open();
db.insertContact2(input.getText().toString());
db.close();
adapterData.add(input.getText().toString());
adapter.notifyDataSetChanged();
}
});
builder.create().show();
return true;
}
}
DBAdapter.java
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
public class DBAdapter {
public static final String KEY_ROWID = "hpnumberID";
public static final String KEY_NAME = "hpNumber";
private static final String TAG = "DBAdapter";
public static final String KEY_ROWID2 = "hpnumberID";
public static final String KEY_NAME2 = "hpNumber";
private static final String DATABASE_NAME = "HPnumberDB";
private static final String DATABASE_TABLE = "number";
private static final String DATABASE_TABLE2 = "receivernumber";
private static final int DATABASE_VERSION = 2;
private static final String DATABASE_CREATE =
"create table number (hpnumberID integer primary key autoincrement, "
+ "hpNumber text not null);";
private static final String DATABASE_CREATE2 =
"create table receivernumber (hpnumberID integer primary key autoincrement, "
+ "hpNumber text not null);";
private final Context context;
private DatabaseHelper DBHelper;
private SQLiteDatabase db;
public DBAdapter(Context ctx)
{
this.context = ctx;
DBHelper = new DatabaseHelper(context);
}
private static class DatabaseHelper extends SQLiteOpenHelper
{
DatabaseHelper(Context context)
{
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db)
{
try {
db.execSQL(DATABASE_CREATE);
db.execSQL(DATABASE_CREATE2);
} catch (SQLException e) {
e.printStackTrace();
}
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{
Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
+ newVersion + ", which will destroy all old data");
db.execSQL("DROP TABLE IF EXISTS " + DATABASE_TABLE);
db.execSQL("DROP TABLE IF EXISTS " + DATABASE_TABLE2);
onCreate(db);
}
} // end DatabaseHelper class
//---opens the database---
public DBAdapter open() throws SQLException
{
db = DBHelper.getWritableDatabase();
return this;
}
//---closes the database---
public void close()
{
DBHelper.close();
}
//---insert a contact into the database---
public long insertContact(String hpNumber)
{
ContentValues initialValues = new ContentValues();
initialValues.put(KEY_NAME, hpNumber);
return db.insert(DATABASE_TABLE, null, initialValues);
}
public long insertContact2(String hpNumber)
{
ContentValues initialValues = new ContentValues();
initialValues.put(KEY_NAME2, hpNumber);
return db.insert(DATABASE_TABLE2, null, initialValues);
}
//---deletes a particular contact---
public boolean deleteContact(long hpnumberID)
{
return db.delete(DATABASE_TABLE, KEY_ROWID + "=" + hpnumberID, null) > 0;
}
public boolean deleteContact2(long hpnumberID)
{
return db.delete(DATABASE_TABLE2, KEY_ROWID2 + "=" + hpnumberID, null) > 0;
}
//---retrieves all the contacts---
public Cursor getAllContacts()
{
return db.query(DATABASE_TABLE, new String[] {KEY_ROWID, KEY_NAME}, null, null,
null, null, null);
}
public Cursor getAllContacts2()
{
return db.query(DATABASE_TABLE2, new String[] {KEY_ROWID2, KEY_NAME2}, null, null,
null, null, null);
}
//---retrieves a particular contact---
public Cursor getContact(long hpnumberID) throws SQLException
{
Cursor mCursor =
db.query(true, DATABASE_TABLE, new String[] {KEY_ROWID,
KEY_NAME}, KEY_ROWID + "=" + hpnumberID, null,
null, null, null, null);
if (mCursor != null) {
mCursor.moveToFirst();
}
return mCursor;
}
public Cursor getContact2(long hpnumberID) throws SQLException
{
Cursor mCursor =
db.query(true, DATABASE_TABLE2, new String[] {KEY_ROWID2,
KEY_NAME2}, KEY_ROWID2 + "=" + hpnumberID, null,
null, null, null, null);
if (mCursor != null) {
mCursor.moveToFirst();
}
return mCursor;
}
//---updates a contact---
public boolean updateContact(long hpnumberID, String hpNumber)
{
ContentValues args = new ContentValues();
args.put(KEY_NAME, hpNumber);
return db.update(DATABASE_TABLE, args, KEY_ROWID + "=" + hpnumberID, null) > 0;
}
public boolean updateContact2(long hpnumberID, String hpNumber)
{
ContentValues args = new ContentValues();
args.put(KEY_NAME2, hpNumber);
return db.update(DATABASE_TABLE2, args, KEY_ROWID2 + "=" + hpnumberID, null) > 0;
}
} // end DBAdapter class
CallAdapter.java
import java.util.List;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
public class CallAdapter extends ArrayAdapter<String> {
Context mContext;
List<String> list;
public CallAdapter(Context context, int resource, List<String> list) {
super(context, resource, list);
// TODO Auto-generated constructor stub
mContext = context;
this.list = list;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = inflater
.inflate(R.layout.set_numbers_to_forward_editable, parent,
false);
TextView hpNumber = (TextView) rowView.findViewById(R.id.hp_Number);
ImageView discardButton = (ImageView) rowView
.findViewById(R.id.number_discard_button);
ImageView editButton = (ImageView) rowView
.findViewById(R.id.number_edit_button);
hpNumber.setText(list.get(position));
discardButton.setTag(position);
editButton.setTag(position);
editButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
String position = v.getTag().toString();
createDialog(position, list);
}
});
discardButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
createDeleteDialog(v.getTag().toString(), list);
}
});
return rowView;
}
public View getView2(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = inflater
.inflate(R.layout.set_number_to_receive_editable, parent,
false);
TextView hpNumber = (TextView) rowView.findViewById(R.id.hp_Number);
ImageView discardButton = (ImageView) rowView
.findViewById(R.id.number_discard_button);
ImageView editButton = (ImageView) rowView
.findViewById(R.id.number_edit_button);
hpNumber.setText(list.get(position));
discardButton.setTag(position);
editButton.setTag(position);
editButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
String position = v.getTag().toString();
createDialog(position, list);
}
});
discardButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
createDeleteDialog(v.getTag().toString(), list);
}
});
return rowView;
}
public void createDialog(String position, List<String> list) {
final long hpnumberID = Long.parseLong(position) + 1;
final int viewPosition = Integer.parseInt(position);
AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
builder.setTitle("Edit");
final EditText input = new EditText(mContext);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT);
input.setLayoutParams(lp);
input.setText(list.get(viewPosition));
builder.setView(input);
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
DBAdapter db = new DBAdapter(mContext);
db.open();
db.updateContact(hpnumberID, input.getText().toString());
db.close();
((Set_numbers_to_forward)
mContext).adapterData.remove(viewPosition);
((Set_numbers_to_forward)
mContext).adapterData.add(viewPosition, input
.getText().toString());
((Set_numbers_to_forward)
mContext).adapter.notifyDataSetChanged();
}
});
builder.setNegativeButton("Cancel",
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int
which) {
dialog.dismiss();
}
});
builder.create().show();
}
public void createDeleteDialog(String position, List<String> list) {
final int viewPosition = Integer.parseInt(position);
final long hpnumberID = Long.parseLong(position) + 1;
AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
builder.setMessage("Deleting \"" + list.get(viewPosition) + "\"");
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
DBAdapter db = new DBAdapter(mContext);
db.open();
db.deleteContact(hpnumberID);
db.close();
((Set_numbers_to_forward)
mContext).adapterData.remove(viewPosition);
((Set_numbers_to_forward)
mContext).adapter.notifyDataSetChanged();
}
});
builder.setNegativeButton("Cancel",
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int
which) {
dialog.dismiss();
}
});
builder.create().show();
}
}
You don't really have a question in your... question. What I can tell you is that if you setup and use your own ContentProvider it takes care of a lot of what you are doing and makes it simpler. You can read the tutorial on the android documentation here http://developer.android.com/guide/topics/providers/content-provider-creating.html
If you start with that feel free to leave a comment on this answer if you run into any problems with the tutorial and I might be able to help. As it is you are 'reinventing the wheel' and making things difficult for yourself
edit
I've just realised from Tobor's comment there's a content provider buried in there as well - I still recommend following the tutorial above (or finding your own) to clear up the code
Why do you need doubles??
You can't use ArrayAdapter and Activity like this. Also, you don't need two xml files for this. Create an xml layout that contains two views inside and set this view as content view of your activity.
In overrided getView method in your adapter, update these views.
onCreate2 and getView2 methods are not called from anywhere and shouldn't be. In an activity, there can be only one content view.
Please see ArrayAdapter and creating Android Activity and SQLite DBAdapter examples first before starting new development.