From c8f5e839c3db8c6bd46f0d04729d2ede54610a73 Mon Sep 17 00:00:00 2001 From: Hyperling Date: Sat, 4 Jan 2025 12:42:10 -0700 Subject: [PATCH] Add original project. --- .gitignore | 42 ++++ app/.gitignore | 1 + app/build.gradle | 26 +++ app/proguard-rules.pro | 17 ++ .../ApplicationTest.java | 13 ++ app/src/main/AndroidManifest.xml | 20 ++ .../AddEditFragment.java | 154 ++++++++++++++ .../ContactListFragment.java | 123 +++++++++++ .../DatabaseConnector.java | 107 ++++++++++ .../DetailsFragment.java | 200 ++++++++++++++++++ .../MainActivity.java | 120 +++++++++++ app/src/main/res/drawable/textview_border.xml | 7 + .../main/res/layout-large/activity_main.xml | 20 ++ app/src/main/res/layout/activity_main.xml | 16 ++ app/src/main/res/layout/fragment_add_edit.xml | 116 ++++++++++ app/src/main/res/layout/fragment_details.xml | 140 ++++++++++++ .../res/menu/fragment_contact_list_menu.xml | 9 + .../main/res/menu/fragment_details_menu.xml | 14 ++ app/src/main/res/mipmap-hdpi/ic_launcher.png | Bin 0 -> 3418 bytes app/src/main/res/mipmap-mdpi/ic_launcher.png | Bin 0 -> 2206 bytes app/src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 0 -> 4842 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 0 -> 7718 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 0 -> 10486 bytes app/src/main/res/values-w820dp/dimens.xml | 6 + app/src/main/res/values/colors.xml | 6 + app/src/main/res/values/dimens.xml | 5 + app/src/main/res/values/strings.xml | 9 + app/src/main/res/values/styles.xml | 27 +++ .../ExampleUnitTest.java | 15 ++ build.gradle | 23 ++ gradle.properties | 18 ++ gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 53637 bytes gradle/wrapper/gradle-wrapper.properties | 6 + gradlew | 160 ++++++++++++++ gradlew.bat | 90 ++++++++ settings.gradle | 1 + 36 files changed, 1511 insertions(+) create mode 100755 app/.gitignore create mode 100755 app/build.gradle create mode 100755 app/proguard-rules.pro create mode 100755 app/src/androidTest/java/com/hyperling/apps/example_sqlite_addressbook/ApplicationTest.java create mode 100755 app/src/main/AndroidManifest.xml create mode 100755 app/src/main/java/com/hyperling/apps/example_sqlite_addressbook/AddEditFragment.java create mode 100755 app/src/main/java/com/hyperling/apps/example_sqlite_addressbook/ContactListFragment.java create mode 100755 app/src/main/java/com/hyperling/apps/example_sqlite_addressbook/DatabaseConnector.java create mode 100755 app/src/main/java/com/hyperling/apps/example_sqlite_addressbook/DetailsFragment.java create mode 100755 app/src/main/java/com/hyperling/apps/example_sqlite_addressbook/MainActivity.java create mode 100755 app/src/main/res/drawable/textview_border.xml create mode 100755 app/src/main/res/layout-large/activity_main.xml create mode 100755 app/src/main/res/layout/activity_main.xml create mode 100755 app/src/main/res/layout/fragment_add_edit.xml create mode 100755 app/src/main/res/layout/fragment_details.xml create mode 100755 app/src/main/res/menu/fragment_contact_list_menu.xml create mode 100755 app/src/main/res/menu/fragment_details_menu.xml create mode 100755 app/src/main/res/mipmap-hdpi/ic_launcher.png create mode 100755 app/src/main/res/mipmap-mdpi/ic_launcher.png create mode 100755 app/src/main/res/mipmap-xhdpi/ic_launcher.png create mode 100755 app/src/main/res/mipmap-xxhdpi/ic_launcher.png create mode 100755 app/src/main/res/mipmap-xxxhdpi/ic_launcher.png create mode 100755 app/src/main/res/values-w820dp/dimens.xml create mode 100755 app/src/main/res/values/colors.xml create mode 100755 app/src/main/res/values/dimens.xml create mode 100755 app/src/main/res/values/strings.xml create mode 100755 app/src/main/res/values/styles.xml create mode 100755 app/src/test/java/com/hyperling/apps/example_sqlite_addressbook/ExampleUnitTest.java create mode 100755 build.gradle create mode 100755 gradle.properties create mode 100755 gradle/wrapper/gradle-wrapper.jar create mode 100755 gradle/wrapper/gradle-wrapper.properties create mode 100755 gradlew create mode 100755 gradlew.bat create mode 100755 settings.gradle diff --git a/.gitignore b/.gitignore index a8b0d1d..d3c6c1b 100644 --- a/.gitignore +++ b/.gitignore @@ -33,3 +33,45 @@ google-services.json # Android Profiling *.hprof +## Suggested ^^ + +## From TicTacToe project for good measure. vv + +# Gradle files +.gradle/ +build/ + +# Local configuration file (sdk path, etc) +local.properties + +# Log/OS Files +*.log + +# Android Studio generated files and folders +captures/ +.externalNativeBuild/ +.cxx/ +*.apk +output.json + +# IntelliJ +*.iml +.idea/ +misc.xml +deploymentTargetDropDown.xml +render.experimental.xml + +# Keystore files +*.jks +*.keystore + +# Google Services (e.g. APIs or Firebase) +google-services.json + +# Android Profiling +*.hprof +/app/debug/output-metadata.json + +# Ha! +keystore/* +release diff --git a/app/.gitignore b/app/.gitignore new file mode 100755 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100755 index 0000000..f299b07 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,26 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 23 + buildToolsVersion "23.0.2" + + defaultConfig { + applicationId "com.hyperling.apps.example_sqlite_addressbook" + minSdkVersion 18 + targetSdkVersion 23 + versionCode 1 + versionName "1.0" + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } +} + +dependencies { + compile fileTree(dir: 'libs', include: ['*.jar']) + testCompile 'junit:junit:4.12' + compile 'com.android.support:appcompat-v7:23.1.1' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100755 index 0000000..675df9e --- /dev/null +++ b/app/proguard-rules.pro @@ -0,0 +1,17 @@ +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in /home/ling/WDBlue/Programming/Java/Android/android-sdk/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the proguardFiles +# directive in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} diff --git a/app/src/androidTest/java/com/hyperling/apps/example_sqlite_addressbook/ApplicationTest.java b/app/src/androidTest/java/com/hyperling/apps/example_sqlite_addressbook/ApplicationTest.java new file mode 100755 index 0000000..362bacc --- /dev/null +++ b/app/src/androidTest/java/com/hyperling/apps/example_sqlite_addressbook/ApplicationTest.java @@ -0,0 +1,13 @@ +package com.hyperling.apps.example_sqlite_addressbook; + +import android.app.Application; +import android.test.ApplicationTestCase; + +/** + * Testing Fundamentals + */ +public class ApplicationTest extends ApplicationTestCase { + public ApplicationTest() { + super(Application.class); + } +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100755 index 0000000..8d51983 --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + diff --git a/app/src/main/java/com/hyperling/apps/example_sqlite_addressbook/AddEditFragment.java b/app/src/main/java/com/hyperling/apps/example_sqlite_addressbook/AddEditFragment.java new file mode 100755 index 0000000..a4ec766 --- /dev/null +++ b/app/src/main/java/com/hyperling/apps/example_sqlite_addressbook/AddEditFragment.java @@ -0,0 +1,154 @@ +package com.hyperling.apps.example_sqlite_addressbook; + +import android.app.Activity; +import android.app.AlertDialog; +import android.app.Dialog; +import android.app.DialogFragment; +import android.app.Fragment; +import android.content.Context; +import android.content.DialogInterface; +import android.os.AsyncTask; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.inputmethod.InputMethodManager; +import android.widget.Button; +import android.widget.EditText; + +/** + * Created by ling on 12/13/15. + */ +public class AddEditFragment extends Fragment { + public interface AddEditFragmentListener { + public void onAddEditCompleted(long rowID); + } + + private AddEditFragmentListener listener; + + private long rowID; + + private Bundle contactInfoBundle; + + private EditText etName; + private EditText etPhone; + private EditText etEmail; + private EditText etStreet; + private EditText etCity; + private EditText etState; + private EditText etZip; + + @Override + public void onAttach(Activity activity){ + super.onAttach(activity); + listener = (AddEditFragmentListener) activity; + } + + @Override + public void onDetach(){ + super.onDetach(); + listener = null; + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){ + super.onCreateView(inflater, container, savedInstanceState); + setRetainInstance(true); + setHasOptionsMenu(true); + + View view = inflater.inflate(R.layout.fragment_add_edit, container, false); + etName = (EditText) view.findViewById(R.id.et_name); + etPhone = (EditText) view.findViewById(R.id.et_phone); + etEmail = (EditText) view.findViewById(R.id.et_email); + etStreet = (EditText) view.findViewById(R.id.et_street); + etCity = (EditText) view.findViewById(R.id.et_city); + etState = (EditText) view.findViewById(R.id.et_state); + etZip = (EditText) view.findViewById(R.id.et_zip); + + contactInfoBundle = getArguments(); + + if (contactInfoBundle != null){ + rowID = contactInfoBundle.getLong(MainActivity.ROW_ID); + etName.setText(contactInfoBundle.getString("name")); + etPhone.setText(contactInfoBundle.getString("phone")); + etEmail.setText(contactInfoBundle.getString("email")); + etStreet.setText(contactInfoBundle.getString("street")); + etCity.setText(contactInfoBundle.getString("city")); + etState.setText(contactInfoBundle.getString("state")); + etZip.setText(contactInfoBundle.getString("zip")); + } + + Button btnSave = (Button) view.findViewById(R.id.btn_save); + btnSave.setOnClickListener(saveButtonClicked); + + return view; + } + + View.OnClickListener saveButtonClicked = new View.OnClickListener() { + @Override + public void onClick(View v) { + if (etName.getText().toString().trim().length() > 0){ + AsyncTask saveContactTask = new AsyncTask() { + @Override + protected Object doInBackground(Object... params) { + saveContact(); + return null; + } + + @Override + protected void onPostExecute(Object results){ + InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE); + imm.hideSoftInputFromWindow(getView().getWindowToken(), 0); + + listener.onAddEditCompleted(rowID); + } + }; + + saveContactTask.execute((Object[]) null); + } + else{ + DialogFragment errorSaving = new DialogFragment(){ + @Override + public Dialog onCreateDialog(Bundle savedInstanceState){ + AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); + + builder.setMessage(R.string.error_create_contact); + builder.setPositiveButton(R.string.msg_confirm_ok_button, null); + + return builder.create(); + } + }; + + errorSaving.show(getFragmentManager(), "Error saving contact"); + } + } + }; + + private void saveContact(){ + DatabaseConnector databaseConnector = new DatabaseConnector(getActivity()); + + if (contactInfoBundle == null) { + rowID = databaseConnector.insertContact( + etName.getText().toString(), + etPhone.getText().toString(), + etEmail.getText().toString(), + etStreet.getText().toString(), + etCity.getText().toString(), + etState.getText().toString(), + etZip.getText().toString() + ); + } + else{ + databaseConnector.updateContact( + rowID, + etName.getText().toString(), + etPhone.getText().toString(), + etEmail.getText().toString(), + etStreet.getText().toString(), + etCity.getText().toString(), + etState.getText().toString(), + etZip.getText().toString() + ); + } + } +} diff --git a/app/src/main/java/com/hyperling/apps/example_sqlite_addressbook/ContactListFragment.java b/app/src/main/java/com/hyperling/apps/example_sqlite_addressbook/ContactListFragment.java new file mode 100755 index 0000000..e9a4a7e --- /dev/null +++ b/app/src/main/java/com/hyperling/apps/example_sqlite_addressbook/ContactListFragment.java @@ -0,0 +1,123 @@ +package com.hyperling.apps.example_sqlite_addressbook; + +import android.app.Activity; +import android.app.ListFragment; +import android.database.Cursor; +import android.os.AsyncTask; +import android.os.Bundle; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.widget.AdapterView; +import android.widget.CursorAdapter; +import android.widget.ListView; +import android.widget.SimpleCursorAdapter; + +/** + * Created by ling on 12/13/15. + */ +public class ContactListFragment extends ListFragment { + public interface ContactListFragmentListener{ + public void onContactSelected(long rowID); + public void onAddContact(); + } + + private ContactListFragmentListener listener; + + private ListView contactListView; + + private CursorAdapter contactAdapter; + + @Override + public void onAttach(Activity activity){ + super.onAttach(activity); + listener = (ContactListFragmentListener) activity; + } + + @Override + public void onDetach(){ + super.onDetach(); + listener = null; + } + + @Override + public void onViewCreated(View view, Bundle savedInstanceBundle){ + super.onViewCreated(view, savedInstanceBundle); + setRetainInstance(true); + setHasOptionsMenu(true); + + setEmptyText(getResources().getString(R.string.no_contacts)); + + contactListView = getListView(); + contactListView.setOnItemClickListener(viewContactListener); + contactListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE); + + String[] from = new String[] {"name"}; + int[] to = new int[] {android.R.id.text1}; + contactAdapter = new SimpleCursorAdapter(getActivity(), android.R.layout.simple_list_item_1, null, from, to, 0); + setListAdapter(contactAdapter); + } + + AdapterView.OnItemClickListener viewContactListener = new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + listener.onContactSelected(id); + } + }; + + @Override + public void onResume(){ + super.onResume(); + new GetContactsTask().execute((Object[]) null); + } + + private class GetContactsTask extends AsyncTask{ + DatabaseConnector databaseConnector = new DatabaseConnector(getActivity()); + + @Override + protected Cursor doInBackground(Object... params){ + databaseConnector.open(); + return databaseConnector.getAllContacts(); + } + + @Override + protected void onPostExecute(Cursor result){ + contactAdapter.changeCursor(result); + databaseConnector.close(); + } + } + + @Override + public void onStop(){ + Cursor cursor = contactAdapter.getCursor(); + contactAdapter.changeCursor(null); + + if (cursor != null){ + cursor.close(); + } + + super.onStop(); + } + + @Override + public void onCreateOptionsMenu(Menu menu, MenuInflater inflater){ + super.onCreateOptionsMenu(menu, inflater); + inflater.inflate(R.menu.fragment_contact_list_menu, menu); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item){ + switch(item.getItemId()){ + case R.id.action_add: + listener.onAddContact(); + return true; + } + + return super.onOptionsItemSelected(item); + } + + public void updateContactList(){ + new GetContactsTask().execute((Object[]) null); + } +} diff --git a/app/src/main/java/com/hyperling/apps/example_sqlite_addressbook/DatabaseConnector.java b/app/src/main/java/com/hyperling/apps/example_sqlite_addressbook/DatabaseConnector.java new file mode 100755 index 0000000..93e117e --- /dev/null +++ b/app/src/main/java/com/hyperling/apps/example_sqlite_addressbook/DatabaseConnector.java @@ -0,0 +1,107 @@ +package com.hyperling.apps.example_sqlite_addressbook; + +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; + +/** + * Created by ling on 12/13/15. + */ +public class DatabaseConnector extends Object { + private static final String DATABASE_NAME = "user_contacts"; + + private SQLiteDatabase database; + private DatabaseOpenHelper databaseOpenHelper; + + public DatabaseConnector(Context context){ + databaseOpenHelper = new DatabaseOpenHelper(context, DATABASE_NAME, null, 1); + } + + public void open() throws SQLException{ + database = databaseOpenHelper.getWritableDatabase(); + } + + public void close(){ + if (database != null){ + database.close(); + } + } + + public long insertContact(String name, String phone, String email, String street, String city, String state, String zip){ + ContentValues newContact = new ContentValues(); + newContact.put("name", name); + newContact.put("phone", phone); + newContact.put("email", email); + newContact.put("street", street); + newContact.put("city", city); + newContact.put("state", state); + newContact.put("zip", zip); + + open(); + long rowID = database.insert("contacts", null, newContact); + close(); + return rowID; + } + + public void updateContact(long id, String name, String phone, String email, String street, String city, String state, String zip){ + ContentValues editContact = new ContentValues(); + editContact.put("name", name); + editContact.put("phone", phone); + editContact.put("email", email); + editContact.put("street", street); + editContact.put("city", city); + editContact.put("state", state); + editContact.put("zip", zip); + + open(); + database.update("contacts", editContact, "_id=" + id, null); + close(); + } + + public Cursor getAllContacts(){ + return database.query("contacts", new String[] {"_id"}, null, null, null, null, "name"); + } + + public Cursor getOneContact(long id){ + return database.query("contacts", null, "_id=" + id, null, null, null, null); + } + + public void deleteContact(long id){ + open(); + database.delete("contacts", "_id=" + id, null); + close(); + } + + private class DatabaseOpenHelper extends SQLiteOpenHelper{ + public DatabaseOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version){ + super(context, name, factory, version); + } + + @Override + public void onCreate(SQLiteDatabase db){ + String createQuery = + "CREATE TABLE contacts" + + "(" + + "_id integer primary key autoincrement," + + "name TEXT," + + "phone TEXT," + + "email TEXT," + + "street TEXT," + + "city TEXT," + + "state TEXT," + + "zip TEXT" + + ");"; + + db.execSQL(createQuery); + } + + @Override + public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){ + // Do nothing + return; + } + } +} diff --git a/app/src/main/java/com/hyperling/apps/example_sqlite_addressbook/DetailsFragment.java b/app/src/main/java/com/hyperling/apps/example_sqlite_addressbook/DetailsFragment.java new file mode 100755 index 0000000..71408e3 --- /dev/null +++ b/app/src/main/java/com/hyperling/apps/example_sqlite_addressbook/DetailsFragment.java @@ -0,0 +1,200 @@ +package com.hyperling.apps.example_sqlite_addressbook; + +import android.app.Activity; +import android.app.AlertDialog; +import android.app.Dialog; +import android.app.DialogFragment; +import android.app.Fragment; +import android.content.DialogInterface; +import android.database.Cursor; +import android.os.AsyncTask; +import android.os.Bundle; +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.TextView; + +/** + * Created by ling on 12/13/15. + */ +public class DetailsFragment extends Fragment { + + public interface DetailsFragmentListener{ + public void onContactDeleted(); + public void onEditContact(Bundle arguments); + } + + private DetailsFragmentListener listener; + + private long rowID = -1; + + private TextView tvName; + private TextView tvPhone; + private TextView tvEmail; + private TextView tvStreet; + private TextView tvCity; + private TextView tvState; + private TextView tvZip; + + @Override + public void onAttach(Activity activity){ + super.onAttach(activity); + listener = (DetailsFragmentListener) activity; + } + + @Override + public void onDetach(){ + super.onDetach(); + listener = null; + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){ + super.onCreateView(inflater, container, savedInstanceState); + setRetainInstance(true); + + if (savedInstanceState != null){ + rowID = savedInstanceState.getLong(MainActivity.ROW_ID); + } + else{ + Bundle arguments = getArguments(); + + if (arguments != null){ + rowID = arguments.getLong(MainActivity.ROW_ID); + } + } + + View view = inflater.inflate(R.layout.fragment_details, container, false); + setHasOptionsMenu(true); + + tvName = (TextView) view.findViewById(R.id.tv_name); + tvPhone = (TextView) view.findViewById(R.id.tv_phone); + tvEmail = (TextView) view.findViewById(R.id.tv_email); + tvStreet = (TextView) view.findViewById(R.id.tv_street); + tvCity = (TextView) view.findViewById(R.id.tv_city); + tvState = (TextView) view.findViewById(R.id.tv_state); + tvZip = (TextView) view.findViewById(R.id.tv_zip); + + return view; + } + + @Override + public void onResume(){ + super.onResume(); + new LoadContactTask().execute(rowID); + } + + @Override + public void onSaveInstanceState(Bundle outState){ + super.onSaveInstanceState(outState); + outState.putLong(MainActivity.ROW_ID, rowID); + } + + @Override + public void onCreateOptionsMenu(Menu menu, MenuInflater inflater){ + super.onCreateOptionsMenu(menu, inflater); + inflater.inflate(R.menu.fragment_details_menu, menu); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item){ + switch(item.getItemId()){ + case R.id.action_edit: + Bundle arguments = new Bundle(); + + arguments.putLong(MainActivity.ROW_ID, rowID); + arguments.putCharSequence("name", tvName.getText()); + arguments.putCharSequence("phone", tvPhone.getText()); + arguments.putCharSequence("email", tvEmail.getText()); + arguments.putCharSequence("street", tvStreet.getText()); + arguments.putCharSequence("city", tvCity.getText()); + arguments.putCharSequence("state", tvState.getText()); + arguments.putCharSequence("zip", tvZip.getText()); + return true; + case R.id.action_delete: + deleteContact(); + return true; + } + + return super.onOptionsItemSelected(item); + } + + private class LoadContactTask extends AsyncTask{ + DatabaseConnector databaseConnector = new DatabaseConnector(getActivity()); + + @Override + protected Cursor doInBackground(Long... params){ + databaseConnector.open(); + return databaseConnector.getOneContact(params[0]); + } + + @Override + protected void onPostExecute(Cursor result){ + super.onPostExecute(result); + + result.moveToFirst(); + + int iName = result.getColumnIndex("name"); + int iPhone = result.getColumnIndex("phone"); + int iEmail = result.getColumnIndex("email"); + int iStreet = result.getColumnIndex("street"); + int iCity = result.getColumnIndex("city"); + int iState = result.getColumnIndex("state"); + int iZip = result.getColumnIndex("zip"); + + tvName.setText(result.getString(iName)); + tvPhone.setText(result.getString(iPhone)); + tvEmail.setText(result.getString(iEmail)); + tvStreet.setText(result.getString(iStreet)); + tvCity.setText(result.getString(iCity)); + tvState.setText(result.getString(iState)); + tvZip.setText(result.getString(iZip)); + + result.close(); + databaseConnector.close(); + } + + private void deleteContact(){ + confirmDelete.show(getFragmentManager(), "confirm delete"); + } + + private DialogFragment confirmDelete = new DialogFragment(){ + @Override + public Dialog onCreateDialog(Bundle bundle){ + AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); + + builder.setTitle(R.string.msg_confirm_title); + builder.setMessage(R.string.msg_confirm_text); + + builder.setPositiveButton(R.string.msg_confirm_ok_button, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + final DatabaseConnector databaseConnector = new DatabaseConnector(getActivity()); + + AsyncTask deleteTask = new AsyncTask() { + @Override + protected Cursor doInBackground(Long... params) { + databaseConnector.deleteContact(params[0]); + return null; + } + + @Override + protected void onPostExecute(Object result) { + listener.onContactDeleted(); + } + + }; + + deleteTask.execute(new Long[]{rowID}); + } + }); + + builder.setNegativeButton(R.string.msg_confirm_cancel_button, null); + return builder.create(); + } + }; + } +} diff --git a/app/src/main/java/com/hyperling/apps/example_sqlite_addressbook/MainActivity.java b/app/src/main/java/com/hyperling/apps/example_sqlite_addressbook/MainActivity.java new file mode 100755 index 0000000..2c6857a --- /dev/null +++ b/app/src/main/java/com/hyperling/apps/example_sqlite_addressbook/MainActivity.java @@ -0,0 +1,120 @@ +package com.hyperling.apps.example_sqlite_addressbook; + +import android.app.FragmentTransaction; +import android.support.v7.app.AppCompatActivity; +import android.os.Bundle; + +public class MainActivity extends AppCompatActivity + implements ContactListFragment.ContactListFragmentListener, + DetailsFragment.DetailsFragmentListener, + AddEditFragment.AddEditFragmentListener{ + + public static final String ROW_ID = "row_id"; + + ContactListFragment contactListFragment; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + + if (savedInstanceState != null){ + return; + } + + if (findViewById(R.id.fragmentContainer) != null){ + contactListFragment = new ContactListFragment(); + FragmentTransaction transaction = getFragmentManager().beginTransaction(); + transaction.add(R.id.fragmentContainer, contactListFragment); + } + } + + @Override + protected void onResume(){ + super.onResume(); + + if (contactListFragment == null){ + contactListFragment = (ContactListFragment) getFragmentManager().findFragmentById(R.id.contactListFragment); + } + } + + @Override + public void onContactSelected(long rowID){ + if (findViewById(R.id.fragmentContainer) != null){ + displayContact(rowID, R.id.fragmentContainer); + } + else{ + getFragmentManager().popBackStack(); + displayContact(rowID, R.id.rightPaneContainer); + } + } + + private void displayContact(long rowID, int viewID){ + DetailsFragment detailsFragment = new DetailsFragment(); + + Bundle arguments = new Bundle(); + arguments.putLong(ROW_ID, rowID); + + detailsFragment.setArguments(arguments); + + FragmentTransaction transaction = getFragmentManager().beginTransaction(); + transaction.replace(viewID, detailsFragment); + transaction.addToBackStack(null); + transaction.commit(); + } + + @Override + public void onAddContact(){ + if (findViewById(R.id.fragmentContainer) != null){ + displayAddEditFragment(R.id.fragmentContainer, null); + } + else{ + displayAddEditFragment(R.id.rightPaneContainer, null); + } + } + + private void displayAddEditFragment(int viewID, Bundle arguments){ + AddEditFragment addEditFragment = new AddEditFragment(); + + if (arguments != null){ + addEditFragment.setArguments(arguments); + } + + FragmentTransaction transaction = getFragmentManager().beginTransaction(); + transaction.replace(viewID, addEditFragment); + transaction.addToBackStack(null); + transaction.commit(); + } + + @Override + public void onContactDeleted(){ + getFragmentManager().popBackStack(); + + if (findViewById(R.id.fragmentContainer) == null){ + contactListFragment.updateContactList(); + } + } + + @Override + public void onEditContact(Bundle arguments){ + if (findViewById(R.id.fragmentContainer) != null){ + displayAddEditFragment(R.id.fragmentContainer, arguments); + } + else{ + displayAddEditFragment(R.id.rightPaneContainer, arguments); + } + } + + @Override + public void onAddEditCompleted(long rowID){ + getFragmentManager().popBackStack(); + + if (findViewById(R.id.fragmentContainer) == null){ + getFragmentManager().popBackStack(); + + contactListFragment.updateContactList(); + + displayContact(rowID, R.id.rightPaneContainer); + } + } +} diff --git a/app/src/main/res/drawable/textview_border.xml b/app/src/main/res/drawable/textview_border.xml new file mode 100755 index 0000000..f7f6e46 --- /dev/null +++ b/app/src/main/res/drawable/textview_border.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout-large/activity_main.xml b/app/src/main/res/layout-large/activity_main.xml new file mode 100755 index 0000000..4820cfd --- /dev/null +++ b/app/src/main/res/layout-large/activity_main.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml new file mode 100755 index 0000000..c48c9cf --- /dev/null +++ b/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,16 @@ + + + + + diff --git a/app/src/main/res/layout/fragment_add_edit.xml b/app/src/main/res/layout/fragment_add_edit.xml new file mode 100755 index 0000000..4e25b05 --- /dev/null +++ b/app/src/main/res/layout/fragment_add_edit.xml @@ -0,0 +1,116 @@ + + + + + + + + + + + + + + + + + + + +