问题
I have a from that a user fills in and their data is stored in a row using SQLite, a cursor gets their details from the table and outputs it in a listView. I want the user to be able to fill in that form again so as to update their details and display the new details in the listview in replace of the old details that are there. What happens at the moment is that when the user updates their details (fills in form again) then another row is created and that new row is outputed in the along with the original in the listview.
MyDBHandler class
package com.astuetz.viewpager.extensions.sample;
import android.content.ContentValues;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.Cursor;
import android.content.Context;
import android.content.ContentValues;
import java.util.ArrayList;
import java.util.List;
public class MyDBHandler extends SQLiteOpenHelper {
public MyDBHandler(Context context){
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
private static final int DATABASE_VERSION = 1;
private static final String DATABASE_NAME = "detailsDB.db";
public static final String TABLE_DETAILS = "details";
public static final String COLUMN_ID = "_id";
public static final String COLUMN_FIRSTNAME = "firstname";
public static final String COLUMN_SURNAME = "surname";
public static final String COLUMN_PHONE = "phone";
public static final String COLUMN_EMAIL = "email";
public static final String COLUMN_ADDRESS1 = "address1";
public static final String COLUMN_ADDRESS2 = "address2";
public static final String TABLE_KIN_DETAILS = "kindetails";
public static final String COLUMN_KIN_ID = "_id";
public static final String COLUMN_KIN_YOUREMAIL = "youremailkin";
public static final String COLUMN_KIN_FIRSTNAME = "firstnamekin";
public static final String COLUMN_KIN_SURNAME = "surnamekin";
public static final String COLUMN_KIN_PHONE = "phonekin";
public static final String COLUMN_KIN_EMAIL = "emailkin";
public static final String COLUMN_KIN_ADDRESS1 = "address1kin";
public static final String COLUMN_KIN_ADDRESS2 = "address2kin";
// Pass database information along to superclass
public MyDBHandler(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
super(context, DATABASE_NAME, factory, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
String query = " CREATE TABLE " + TABLE_DETAILS + "("
+ COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
+ COLUMN_FIRSTNAME + " TEXT, "
+ COLUMN_SURNAME + " TEXT, "
+ COLUMN_PHONE + " TEXT, "
+ COLUMN_EMAIL + " TEXT, "
+ COLUMN_ADDRESS1 + " TEXT, "
+ COLUMN_ADDRESS2 + " TEXT "
+ ");";
String query2 = " CREATE TABLE " + TABLE_KIN_DETAILS + "("
+ COLUMN_KIN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
+ COLUMN_KIN_YOUREMAIL + " TEXT, "
+ COLUMN_KIN_FIRSTNAME + " TEXT, "
+ COLUMN_KIN_SURNAME + " TEXT, "
+ COLUMN_KIN_PHONE + " TEXT, "
+ COLUMN_KIN_EMAIL + " TEXT, "
+ COLUMN_KIN_ADDRESS1 + " TEXT, "
+ COLUMN_KIN_ADDRESS2 + " TEXT "
+ ");";
db.execSQL(query);
db.execSQL(query2);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL(" DROP TABLE IF EXISTS " + TABLE_DETAILS);
db.execSQL(" DROP TABLE IF EXISTS " + TABLE_KIN_DETAILS);
onCreate(db);
}
//Add a new row to the database
public void addDetails(Details details) {
ContentValues values = new ContentValues();
values.put(COLUMN_FIRSTNAME, details.getFirstname());
values.put(COLUMN_SURNAME, details.getSurname());
values.put(COLUMN_PHONE, details.getPhone());
values.put(COLUMN_EMAIL, details.getEmail());
values.put(COLUMN_ADDRESS1, details.getAddress1());
values.put(COLUMN_ADDRESS2, details.getAddress2());
SQLiteDatabase db = getWritableDatabase();
db.insert(TABLE_DETAILS, null, values);
db.close();
}
public void addKinDetails(KinDetails kinDetails){
ContentValues values = new ContentValues();
values.put(COLUMN_KIN_YOUREMAIL, kinDetails.getyourEmailkin());
values.put(COLUMN_KIN_FIRSTNAME, kinDetails.getFirstnamekin());
values.put(COLUMN_KIN_SURNAME, kinDetails.getSurnamekin());
values.put(COLUMN_KIN_PHONE, kinDetails.getPhonekin());
values.put(COLUMN_KIN_EMAIL, kinDetails.getEmailkin());
values.put(COLUMN_KIN_ADDRESS1, kinDetails.getAddress1kin());
values.put(COLUMN_KIN_ADDRESS2, kinDetails.getAddress2kin());
SQLiteDatabase db = getWritableDatabase();
db.insert(TABLE_KIN_DETAILS, null, values);
db.close();
}
public List<Details> getAllDetails(){
//create a new list in which we put all persons
List<Details>detailsList = new ArrayList<>();
SQLiteDatabase db = getWritableDatabase();
String query = "SELECT * FROM " + TABLE_DETAILS;
//Cursor points to a location in your results
Cursor c = db.rawQuery(query, null);
//Move to the first row in your results
if (c != null) {
c.moveToFirst();
//Position after the last row means the end of the results
while (!c.isAfterLast()) {
//create new details object
Details details = new Details();
//Here use static declared on top of the class..don't use "" for the table column
details.set_id(c.getColumnIndex(COLUMN_ID));
details.setFirstname(c.getString(c.getColumnIndex(COLUMN_FIRSTNAME)));
details.setSurname(c.getString(c.getColumnIndex(COLUMN_SURNAME)));
details.setPhone(c.getString(c.getColumnIndex(COLUMN_PHONE)));
details.setEmail(c.getString(c.getColumnIndex(COLUMN_EMAIL)));
details.setAddress1(c.getString(c.getColumnIndex(COLUMN_ADDRESS1)));
details.setAddress2(c.getString(c.getColumnIndex(COLUMN_ADDRESS2)));
detailsList.add(details);
c.moveToNext();
}
c.close();
}
db.close();
//return our list of persons
return detailsList;
}
}
DetailsAdapter class
package com.astuetz.viewpager.extensions.sample;
import android.content.Context;
import android.text.format.DateFormat;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
import java.text.SimpleDateFormat;
import java.util.List;
public class DetailsAdapter extends ArrayAdapter<Details> {
private Context context;
//Constructor
public DetailsAdapter(Context context, int resource, List<Details> objects) {
super(context, resource, objects);
this.context = context;
}
//The get view is the most crucial part of the adapter, here the listview asks the
//adapter for the row to display
@Override
public View getView(int position, View row, ViewGroup parent) {
//Get an instance of the holder
Holder holder;
//Check if this is the first time creating this row for the listview
if (row == null){
//Row was null, need to get components from the row_details.xml
holder = new Holder();
//get the Android's layout inflater service which will read row_details.xml
LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
//Fill the row view with the xml layout file
row = inflater.inflate(R.layout.row_details, null);
//Fill the holder with the text view components
holder.textViewId = (TextView)row.findViewById(R.id.row_details_textview_id);
holder.textViewName = (TextView)row.findViewById(R.id.row_details_textview_name);
holder.textViewSurname = (TextView)row.findViewById(R.id.row_details_textview_surname);
holder.textViewPhone = (TextView)row.findViewById(R.id.row_details_textview_phone);
holder.textViewEmail = (TextView)row.findViewById(R.id.row_details_textview_email);
holder.textViewAddress1 = (TextView)row.findViewById(R.id.row_details_textview_address1);
holder.textViewAddress2 = (TextView)row.findViewById(R.id.row_details_textview_address2);
//attach the holder to the row
row.setTag(holder);
}else{
//row was created before! thus get the holder object from the row tag
holder = (Holder)row.getTag();
}
//At this point we have our row, either created from new or got it from the row tag object
//we can now fill the data
//get our object from the list which is in the position of the listview
//position is passed to the getView method by the listview
Details details = getItem(position);
holder.textViewId.setText("ID: " + details.get_id());
holder.textViewName.setText("Firstname: " + details.getFirstname());
holder.textViewSurname.setText("Surname: " + details.getSurname());
holder.textViewPhone.setText("Phone: " + details.getPhone());
holder.textViewEmail.setText("Email: " + details.getEmail());
holder.textViewAddress1.setText("Address1: " + details.getAddress1());
holder.textViewAddress2.setText("Address2: " + details.getAddress2());
//return to listview to show
return row;
}
//A holder will be responsible to hold the components to improve listview performance
//We replicate the components in the row_details.xml
private class Holder{
TextView textViewName;
TextView textViewId;
TextView textViewSurname;
TextView textViewPhone;
TextView textViewEmail;
TextView textViewAddress1;
TextView textViewAddress2;
}
}
** EDIT FragmentTab1 class**
package com.astuetz.viewpager.extensions.sample;
import com.astuetz.viewpager.extensions.sample.*;
import android.database.Cursor;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.support.v4.app.Fragment;
import android.content.Context;
import android.content.Intent;
//import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.view.View.OnClickListener;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import android.widget.Toast;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
public class FragmentTab1 extends Fragment {
SharedPreferences sharedpreferences;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment1, container, false);
super.onCreate(savedInstanceState);
//setContentView(R.layout.fragment1);
firstName = (TextView) rootView.findViewById(R.id.firstName);
editTextName = (EditText) rootView.findViewById(R.id.editTextName);
textView5 = (TextView) rootView.findViewById(R.id.surName);
editTextSurname = (EditText) rootView.findViewById(R.id.editTextSurname);
textView4 = (TextView) rootView.findViewById(R.id.mobile);
editTextMobile = (EditText) rootView.findViewById(R.id.editTextMobile);
textView2 = (TextView) rootView.findViewById(R.id.Email);
editTextEmail = (EditText) rootView.findViewById(R.id.editTextEmail);
textView3 = (TextView) rootView.findViewById(R.id.address1);
editTextAddress1 = (EditText) rootView.findViewById(R.id.editTextAddress1);
textView6 = (TextView) rootView.findViewById(R.id.address2);
editTextAddress2 = (EditText) rootView.findViewById(R.id.editTextAddress2);
dbHandler = new MyDBHandler(getActivity(), null, null, 1);
/*sharedpreferences = getActivity().getSharedPreferences(MyPREFERENCES, Context.MODE_PRIVATE);
//sharedpreferences = this.getActivity().getSharedPreferences("pref",0);
if (sharedpreferences.contains(FirstName))
{
firstName.setText(sharedpreferences.getString(FirstName, ""));
}
if (sharedpreferences.contains(SurName))
{
textView5.setText(sharedpreferences.getString(SurName, ""));
}
if (sharedpreferences.contains(Phone))
{
textView4.setText(sharedpreferences.getString(Phone, ""));
}
if (sharedpreferences.contains(Emails))
{
textView2.setText(sharedpreferences.getString(Emails, ""));
}
if (sharedpreferences.contains(Addresss1))
{
textView3.setText(sharedpreferences.getString(Addresss1,""));
}
if (sharedpreferences.contains(Addresss2))
{
textView6.setText(sharedpreferences.getString(Addresss2,""));
}*/
Button addButtonClicked = (Button)rootView.findViewById(R.id.addButtonClicked);
addButtonClicked.setOnClickListener(new OnClickListener(){
public void onClick(View v)
{
addButtonClicked(v);
}
});
return rootView;
}
TextView firstName;
EditText editTextName;
TextView textView5;
EditText editTextSurname;
TextView textView4;
EditText editTextMobile;
TextView textView2;
EditText editTextEmail;
TextView textView3;
EditText editTextAddress1;
TextView textView6;
EditText editTextAddress2;
MyDBHandler dbHandler;
/*public static final String MyPREFERENCES = "MyPrefs" ;
public static final String FirstName = "firstNameKey";
public static final String SurName = "surNameKey";
public static final String Phone = "phoneKey";
public static final String Emails = "emailKey";
public static final String Addresss1 = "address1Key";
public static final String Addresss2 = "address2Key";*/
//validate email provided by user
private boolean isValidEmail(String email) {
String EMAIL_PATTERN = "^[_A-Za-z0-9-\\+]+(\\.[_A-Za-z0-9-]+)*@"
+ "[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$";
Pattern pattern = Pattern.compile(EMAIL_PATTERN);
Matcher matcher = pattern.matcher(email);
return matcher.matches();
}
//Add details to the database and shared preferences
public void addButtonClicked(View view) {
/*String n = firstName.getText().toString();
String sn = textView5.getText().toString();
String ph = textView4.getText().toString();
String e = textView2.getText().toString();
String ad1 = textView3.getText().toString();
String ad2 = textView6.getText().toString();
Editor editor = sharedpreferences.edit();
editor.putString(FirstName, n);
editor.putString(SurName, sn);
editor.putString(Phone, ph);
editor.putString(Emails, e);
editor.putString(Addresss1, ad1);
editor.putString(Addresss2, ad2);
editor.commit();*/
final String email = editTextEmail.getText().toString();
if (!isValidEmail(email))
{
editTextEmail.setError("Invalid Email");
Toast.makeText(getActivity().getApplicationContext(), "Invalid email format",
Toast.LENGTH_LONG).show();
}
else if( editTextName.getText().toString().length() == 0 )
{
editTextName.setError("First name is required!");
Toast.makeText(getActivity().getApplicationContext(), "First name is required",
Toast.LENGTH_LONG).show();
}
else if( editTextSurname.getText().toString().length() == 0 )
{
editTextSurname.setError("Surname is required!");
Toast.makeText(getActivity().getApplicationContext(), "Surname is required",
Toast.LENGTH_LONG).show();
}
else if( editTextMobile.getText().toString().length() == 0 || editTextMobile.getText().toString().length() < 10 )
{
editTextMobile.setError("Not a valid number!");
Toast.makeText(getActivity().getApplicationContext(), "Not a valid number",
Toast.LENGTH_LONG).show();
}
else if( editTextAddress1.getText().toString().length() == 0 )
{
editTextAddress1.setError("Address Line 1 is required!");
Toast.makeText(getActivity().getApplicationContext(), "Address Line 1 is required",
Toast.LENGTH_LONG).show();
}
else if( editTextAddress2.getText().toString().length() == 0 )
{
editTextAddress2.setError("Address Line 2 is required!");
Toast.makeText(getActivity().getApplicationContext(), "Address Line 2 is required",
Toast.LENGTH_LONG).show();
}
else
{
Details details = new Details();
details.setFirstname(editTextName.getText().toString());
details.setSurname(editTextSurname.getText().toString());
details.setPhone(editTextMobile.getText().toString());
details.setEmail(editTextEmail.getText().toString());
details.setAddress1(editTextAddress1.getText().toString());
details.setAddress2(editTextAddress2.getText().toString());
dbHandler.addDetails(details);
Toast.makeText(getActivity().getApplicationContext(), "Details saved successfully",
Toast.LENGTH_LONG).show();
}
}
}
回答1:
Hi in your Database Handler Class you need to create methods for update..
as I can see you have an uto incremented primary key (INTEGER PRIMARY KEY AUTOINCREMENT) which is good since we will be using this primary key to locate the record and do the update. to the update method you pass a new Details object which contains new data.
The method in the Database Handler class should be like so :
//Updates the no of comments
public void updateDetails(Details details){
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
//Take new values from the details object provided
values.put(COLUMN_FIRSTNAME, details.getFirstname());
values.put(COLUMN_SURNAME, details.getSurname());
values.put(COLUMN_PHONE, details.getPhone());
values.put(COLUMN_EMAIL, details.getEmail());
values.put(COLUMN_ADDRESS1, details.getAddress1());
values.put(COLUMN_ADDRESS2, details.getAddress2());
//Update the details object where id matches
db.update(TABLE_DETAILS, values, COLUMN_ID + "='" + details._id + "'", null);
db.close();
}
Update
Basically you create a new details object with the new data entered from the user and you pass it to the update details method in the dbHandler class, it is important that you set the id to 1 since the sql query will look for that particular detail in the database :
Details details = new Details();
details.set_id(1);
details.setFirstname("Steve");
dbHandler.updateDetails(details);
No you have the record updated ..please try and advice
回答2:
Instead of an ArrayAdapter try using a SimpleCursorAdapter
. Check here for more info on usage.
Also use Loaders to do all this in the background and notify the adapter on changes
来源:https://stackoverflow.com/questions/28766920/sqlite-updating-a-row-and-updating-listview-created-by-cursor