diff --git a/app/src/main/java/com/philliphsu/clock2/MainActivity.java b/app/src/main/java/com/philliphsu/clock2/MainActivity.java index 7c8e172..48c732d 100644 --- a/app/src/main/java/com/philliphsu/clock2/MainActivity.java +++ b/app/src/main/java/com/philliphsu/clock2/MainActivity.java @@ -3,13 +3,11 @@ package com.philliphsu.clock2; import android.content.Intent; import android.os.Bundle; import android.support.design.widget.FloatingActionButton; -import android.support.design.widget.Snackbar; import android.support.design.widget.TabLayout; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentPagerAdapter; import android.support.v4.view.ViewPager; -import android.util.Log; import android.view.LayoutInflater; import android.view.MenuItem; import android.view.View; @@ -20,7 +18,9 @@ import com.philliphsu.clock2.alarms.AlarmsFragment; import com.philliphsu.clock2.editalarm.EditAlarmActivity; import com.philliphsu.clock2.settings.SettingsActivity; -public class MainActivity extends BaseActivity implements AlarmsFragment.OnAlarmInteractionListener { +import butterknife.Bind; + +public class MainActivity extends BaseActivity { private static final String TAG = "MainActivity"; /** @@ -33,10 +33,11 @@ public class MainActivity extends BaseActivity implements AlarmsFragment.OnAlarm */ private SectionsPagerAdapter mSectionsPagerAdapter; - /** - * The {@link ViewPager} that will host the section contents. - */ - private ViewPager mViewPager; + @Bind(R.id.container) + ViewPager mViewPager; + + @Bind(R.id.fab) + FloatingActionButton mFab; @Override protected void onCreate(Bundle savedInstanceState) { @@ -45,19 +46,21 @@ public class MainActivity extends BaseActivity implements AlarmsFragment.OnAlarm // Create the adapter that will return a fragment for each of the three // primary sections of the activity. mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager()); - - // Set up the ViewPager with the sections adapter. - mViewPager = (ViewPager) findViewById(R.id.container); mViewPager.setAdapter(mSectionsPagerAdapter); TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs); tabLayout.setupWithViewPager(mViewPager); - FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab); - fab.setOnClickListener(new View.OnClickListener() { + mFab.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { - startEditAlarmActivity(-1); + Intent intent = new Intent(MainActivity.this, EditAlarmActivity.class); + // Call Fragment#startActivityForResult() instead of Activity#startActivityForResult() + // because we want the result to be handled in the Fragment, not in this Activity. + // FragmentActivity does NOT deliver the result to the Fragment, i.e. your + // Fragment's onActivityResult() will NOT be called. + mSectionsPagerAdapter.getCurrentFragment() + .startActivityForResult(intent, AlarmsFragment.REQUEST_CREATE_ALARM); } }); } @@ -132,7 +135,9 @@ public class MainActivity extends BaseActivity implements AlarmsFragment.OnAlarm * A {@link FragmentPagerAdapter} that returns a fragment corresponding to * one of the sections/tabs/pages. */ - public class SectionsPagerAdapter extends FragmentPagerAdapter { + private static class SectionsPagerAdapter extends FragmentPagerAdapter { + + private Fragment mCurrentFragment; public SectionsPagerAdapter(FragmentManager fm) { super(fm); @@ -145,6 +150,22 @@ public class MainActivity extends BaseActivity implements AlarmsFragment.OnAlarm : PlaceholderFragment.newInstance(position + 1); } + @Override + public void setPrimaryItem(ViewGroup container, int position, Object object) { + super.setPrimaryItem(container, position, object); + if (mCurrentFragment != object) { + mCurrentFragment = (Fragment) object; + } + } + + @Override + public void destroyItem(ViewGroup container, int position, Object object) { + if (mCurrentFragment == object) { + mCurrentFragment = null; + } + super.destroyItem(container, position, object); + } + @Override public int getCount() { // Show 3 total pages. @@ -163,31 +184,9 @@ public class MainActivity extends BaseActivity implements AlarmsFragment.OnAlarm } return null; } - } - @Override - public void onListItemClick(Alarm item) { - startEditAlarmActivity(item.id()); - } - - @Override - public void onListItemDeleted(Alarm item) { - Log.d(TAG, "Deleted " + item.toString()); - Snackbar.make(findViewById(R.id.main_content), - getString(R.string.snackbar_item_deleted, "Alarm"), - Snackbar.LENGTH_LONG) // TODO: not long enough? - .setAction(R.string.snackbar_undo_item_deleted, new View.OnClickListener() { - @Override - public void onClick(View v) { - // TODO get AlarmsFragment instance and restore the alarm - } - }) - .show(); - } - - private void startEditAlarmActivity(long alarmId) { - Intent intent = new Intent(this, EditAlarmActivity.class); - intent.putExtra(EditAlarmActivity.EXTRA_ALARM_ID, alarmId); - startActivity(intent); + public Fragment getCurrentFragment() { + return mCurrentFragment; + } } } diff --git a/app/src/main/java/com/philliphsu/clock2/alarms/AlarmsCursorAdapter.java b/app/src/main/java/com/philliphsu/clock2/alarms/AlarmsCursorAdapter.java index 2ed336c..1cfd020 100644 --- a/app/src/main/java/com/philliphsu/clock2/alarms/AlarmsCursorAdapter.java +++ b/app/src/main/java/com/philliphsu/clock2/alarms/AlarmsCursorAdapter.java @@ -61,8 +61,6 @@ public class AlarmsCursorAdapter extends RecyclerView.Adapter { mCursor.close(); } mCursor = (AlarmCursor) cursor; - // There is no way to notify the adapter of individual - // item changes when the dataset is a cursor. notifyDataSetChanged(); } } diff --git a/app/src/main/java/com/philliphsu/clock2/alarms/AlarmsFragment.java b/app/src/main/java/com/philliphsu/clock2/alarms/AlarmsFragment.java index 70cb646..aab1e5f 100644 --- a/app/src/main/java/com/philliphsu/clock2/alarms/AlarmsFragment.java +++ b/app/src/main/java/com/philliphsu/clock2/alarms/AlarmsFragment.java @@ -1,12 +1,16 @@ package com.philliphsu.clock2.alarms; +import android.app.Activity; import android.content.Context; +import android.content.Intent; import android.database.Cursor; import android.os.Bundle; +import android.support.design.widget.Snackbar; import android.support.v4.app.Fragment; import android.support.v4.app.LoaderManager.LoaderCallbacks; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; +import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -14,27 +18,22 @@ import android.view.ViewGroup; import com.philliphsu.clock2.Alarm; import com.philliphsu.clock2.OnListItemInteractionListener; import com.philliphsu.clock2.R; +import com.philliphsu.clock2.editalarm.EditAlarmActivity; import com.philliphsu.clock2.model.AlarmsListCursorLoader; -import com.philliphsu.clock2.model.BaseRepository; import com.philliphsu.clock2.model.DatabaseManager; +import com.philliphsu.clock2.util.AlarmUtils; import butterknife.Bind; import butterknife.ButterKnife; -/** - * A fragment representing a list of Items. - *

- * Activities containing this fragment MUST implement the {@link OnAlarmInteractionListener} - * interface. - */ // TODO: Use native fragments since we're targeting API >=19? // TODO: Use native LoaderCallbacks. -public class AlarmsFragment extends Fragment implements - BaseRepository.DataObserver, LoaderCallbacks { +public class AlarmsFragment extends Fragment implements LoaderCallbacks, + OnListItemInteractionListener { + private static final int REQUEST_EDIT_ALARM = 0; + public static final int REQUEST_CREATE_ALARM = 1; + private static final String TAG = "AlarmsFragment"; - private OnAlarmInteractionListener mListener; - @Deprecated - private AlarmsAdapter mAdapter; private AlarmsCursorAdapter mCursorAdapter; private DatabaseManager mDatabaseManager; @@ -77,11 +76,7 @@ public class AlarmsFragment extends Fragment implements // Set the adapter Context context = view.getContext(); mList.setLayoutManager(new LinearLayoutManager(context)); - // TODO: Create a new adapter subclass with constructor that - // has no dataset param. The Loader will set the Cursor after it - // has finished loading it. - mAdapter = new AlarmsAdapter(mDatabaseManager.getAlarms(), mListener); - mCursorAdapter = new AlarmsCursorAdapter(mListener); + mCursorAdapter = new AlarmsCursorAdapter(this); mList.setAdapter(mCursorAdapter); return view; } @@ -96,9 +91,6 @@ public class AlarmsFragment extends Fragment implements @Override public void onResume() { super.onResume(); - // TODO: Need to refresh the list's adapter for any item changes. Consider doing this in - // onNewActivity(). - getLoaderManager().restartLoader(0, null, this); } @Override @@ -107,39 +99,6 @@ public class AlarmsFragment extends Fragment implements ButterKnife.unbind(this); // Only for fragments! } - @Override - public void onAttach(Context context) { - super.onAttach(context); - if (context instanceof OnAlarmInteractionListener) { - mListener = (OnAlarmInteractionListener) context; - } else { - throw new RuntimeException(context.toString() - + " must implement OnAlarmInteractionListener"); - } - } - - @Override - public void onDetach() { - super.onDetach(); - mListener = null; - } - - @Override - public void onItemAdded(Alarm item) { - mList.smoothScrollToPosition(mAdapter.addItem(item)); - } - - @Override - public void onItemDeleted(Alarm item) { - mAdapter.removeItem(item); - mListener.onListItemDeleted(item); - } - - @Override - public void onItemUpdated(Alarm oldItem, Alarm newItem) { - mAdapter.updateItem(oldItem, newItem); - } - @Override public android.support.v4.content.Loader onCreateLoader(int id, Bundle args) { return new AlarmsListCursorLoader(getActivity()); @@ -157,15 +116,45 @@ public class AlarmsFragment extends Fragment implements mCursorAdapter.swapCursor(null); } - /** - * This interface must be implemented by activities that contain this - * fragment to allow an interaction in this fragment to be communicated - * to the activity and potentially other fragments contained in that - * activity. - *

- * See the Android Training lesson Communicating with Other Fragments for more information. - */ - public interface OnAlarmInteractionListener extends OnListItemInteractionListener {} + @Override + public void onActivityResult(int requestCode, int resultCode, Intent data) { + Log.d(TAG, "onActivityResult()"); + if (resultCode != Activity.RESULT_OK) { + return; + } + + switch (requestCode) { + case REQUEST_CREATE_ALARM: + case REQUEST_EDIT_ALARM: + getLoaderManager().restartLoader(0, null, this); + break; + default: + Log.i(TAG, "Could not handle request code " + requestCode); + break; + } + } + + @Override + public void onListItemClick(Alarm item) { + Intent intent = new Intent(getActivity(), EditAlarmActivity.class); + intent.putExtra(EditAlarmActivity.EXTRA_ALARM_ID, item.id()); + startActivityForResult(intent, REQUEST_EDIT_ALARM); + } + + @Override + public void onListItemDeleted(final Alarm item) { + Snackbar.make(getActivity().findViewById(R.id.main_content), + getString(R.string.snackbar_item_deleted, "Alarm"), + Snackbar.LENGTH_LONG) // TODO: not long enough? + .setAction(R.string.snackbar_undo_item_deleted, new View.OnClickListener() { + @Override + public void onClick(View v) { + DatabaseManager.getInstance(getActivity()).insertAlarm(item); + if (item.isEnabled()) { + AlarmUtils.scheduleAlarm(getActivity(), item, true); + } + } + }) + .show(); + } } diff --git a/app/src/main/java/com/philliphsu/clock2/editalarm/EditAlarmActivity.java b/app/src/main/java/com/philliphsu/clock2/editalarm/EditAlarmActivity.java index 1c3f290..1c84bf5 100644 --- a/app/src/main/java/com/philliphsu/clock2/editalarm/EditAlarmActivity.java +++ b/app/src/main/java/com/philliphsu/clock2/editalarm/EditAlarmActivity.java @@ -234,6 +234,7 @@ public class EditAlarmActivity extends BaseActivity implements AlarmNumpad.KeyLi scheduleAlarm(alarm); } + setResult(RESULT_OK); showEditorClosed(); } @@ -246,6 +247,7 @@ public class EditAlarmActivity extends BaseActivity implements AlarmNumpad.KeyLi } mDatabaseManager.deleteAlarm(mOldAlarm); } + setResult(RESULT_OK); showEditorClosed(); }