Result from EditAlarmActivity returns to AlarmsFragment and the list is updated correctly

This commit is contained in:
Phillip Hsu 2016-06-29 21:26:26 -07:00
parent 7d0718387f
commit d042891e51
4 changed files with 93 additions and 105 deletions

View File

@ -3,13 +3,11 @@ package com.philliphsu.clock2;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.support.design.widget.FloatingActionButton; import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.design.widget.TabLayout; import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment; import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter; import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager; import android.support.v4.view.ViewPager;
import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
@ -20,7 +18,9 @@ import com.philliphsu.clock2.alarms.AlarmsFragment;
import com.philliphsu.clock2.editalarm.EditAlarmActivity; import com.philliphsu.clock2.editalarm.EditAlarmActivity;
import com.philliphsu.clock2.settings.SettingsActivity; 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"; private static final String TAG = "MainActivity";
/** /**
@ -33,10 +33,11 @@ public class MainActivity extends BaseActivity implements AlarmsFragment.OnAlarm
*/ */
private SectionsPagerAdapter mSectionsPagerAdapter; private SectionsPagerAdapter mSectionsPagerAdapter;
/** @Bind(R.id.container)
* The {@link ViewPager} that will host the section contents. ViewPager mViewPager;
*/
private ViewPager mViewPager; @Bind(R.id.fab)
FloatingActionButton mFab;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { 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 // Create the adapter that will return a fragment for each of the three
// primary sections of the activity. // primary sections of the activity.
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager()); mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter); mViewPager.setAdapter(mSectionsPagerAdapter);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs); TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(mViewPager); tabLayout.setupWithViewPager(mViewPager);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab); mFab.setOnClickListener(new View.OnClickListener() {
fab.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View view) { 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 * A {@link FragmentPagerAdapter} that returns a fragment corresponding to
* one of the sections/tabs/pages. * one of the sections/tabs/pages.
*/ */
public class SectionsPagerAdapter extends FragmentPagerAdapter { private static class SectionsPagerAdapter extends FragmentPagerAdapter {
private Fragment mCurrentFragment;
public SectionsPagerAdapter(FragmentManager fm) { public SectionsPagerAdapter(FragmentManager fm) {
super(fm); super(fm);
@ -145,6 +150,22 @@ public class MainActivity extends BaseActivity implements AlarmsFragment.OnAlarm
: PlaceholderFragment.newInstance(position + 1); : 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 @Override
public int getCount() { public int getCount() {
// Show 3 total pages. // Show 3 total pages.
@ -163,31 +184,9 @@ public class MainActivity extends BaseActivity implements AlarmsFragment.OnAlarm
} }
return null; return null;
} }
}
@Override public Fragment getCurrentFragment() {
public void onListItemClick(Alarm item) { return mCurrentFragment;
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);
} }
} }

View File

@ -61,8 +61,6 @@ public class AlarmsCursorAdapter extends RecyclerView.Adapter<AlarmViewHolder> {
mCursor.close(); mCursor.close();
} }
mCursor = (AlarmCursor) cursor; mCursor = (AlarmCursor) cursor;
// There is no way to notify the adapter of individual
// item changes when the dataset is a cursor.
notifyDataSetChanged(); notifyDataSetChanged();
} }
} }

View File

@ -1,12 +1,16 @@
package com.philliphsu.clock2.alarms; package com.philliphsu.clock2.alarms;
import android.app.Activity;
import android.content.Context; import android.content.Context;
import android.content.Intent;
import android.database.Cursor; import android.database.Cursor;
import android.os.Bundle; import android.os.Bundle;
import android.support.design.widget.Snackbar;
import android.support.v4.app.Fragment; import android.support.v4.app.Fragment;
import android.support.v4.app.LoaderManager.LoaderCallbacks; import android.support.v4.app.LoaderManager.LoaderCallbacks;
import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@ -14,27 +18,22 @@ import android.view.ViewGroup;
import com.philliphsu.clock2.Alarm; import com.philliphsu.clock2.Alarm;
import com.philliphsu.clock2.OnListItemInteractionListener; import com.philliphsu.clock2.OnListItemInteractionListener;
import com.philliphsu.clock2.R; import com.philliphsu.clock2.R;
import com.philliphsu.clock2.editalarm.EditAlarmActivity;
import com.philliphsu.clock2.model.AlarmsListCursorLoader; import com.philliphsu.clock2.model.AlarmsListCursorLoader;
import com.philliphsu.clock2.model.BaseRepository;
import com.philliphsu.clock2.model.DatabaseManager; import com.philliphsu.clock2.model.DatabaseManager;
import com.philliphsu.clock2.util.AlarmUtils;
import butterknife.Bind; import butterknife.Bind;
import butterknife.ButterKnife; import butterknife.ButterKnife;
/**
* A fragment representing a list of Items.
* <p/>
* Activities containing this fragment MUST implement the {@link OnAlarmInteractionListener}
* interface.
*/
// TODO: Use native fragments since we're targeting API >=19? // TODO: Use native fragments since we're targeting API >=19?
// TODO: Use native LoaderCallbacks. // TODO: Use native LoaderCallbacks.
public class AlarmsFragment extends Fragment implements public class AlarmsFragment extends Fragment implements LoaderCallbacks<Cursor>,
BaseRepository.DataObserver<Alarm>, LoaderCallbacks<Cursor> { OnListItemInteractionListener<Alarm> {
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 AlarmsCursorAdapter mCursorAdapter;
private DatabaseManager mDatabaseManager; private DatabaseManager mDatabaseManager;
@ -77,11 +76,7 @@ public class AlarmsFragment extends Fragment implements
// Set the adapter // Set the adapter
Context context = view.getContext(); Context context = view.getContext();
mList.setLayoutManager(new LinearLayoutManager(context)); mList.setLayoutManager(new LinearLayoutManager(context));
// TODO: Create a new adapter subclass with constructor that mCursorAdapter = new AlarmsCursorAdapter(this);
// 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);
mList.setAdapter(mCursorAdapter); mList.setAdapter(mCursorAdapter);
return view; return view;
} }
@ -96,9 +91,6 @@ public class AlarmsFragment extends Fragment implements
@Override @Override
public void onResume() { public void onResume() {
super.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 @Override
@ -107,39 +99,6 @@ public class AlarmsFragment extends Fragment implements
ButterKnife.unbind(this); // Only for fragments! 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 @Override
public android.support.v4.content.Loader<Cursor> onCreateLoader(int id, Bundle args) { public android.support.v4.content.Loader<Cursor> onCreateLoader(int id, Bundle args) {
return new AlarmsListCursorLoader(getActivity()); return new AlarmsListCursorLoader(getActivity());
@ -157,15 +116,45 @@ public class AlarmsFragment extends Fragment implements
mCursorAdapter.swapCursor(null); mCursorAdapter.swapCursor(null);
} }
/** @Override
* This interface must be implemented by activities that contain this public void onActivityResult(int requestCode, int resultCode, Intent data) {
* fragment to allow an interaction in this fragment to be communicated Log.d(TAG, "onActivityResult()");
* to the activity and potentially other fragments contained in that if (resultCode != Activity.RESULT_OK) {
* activity. return;
* <p/> }
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html" switch (requestCode) {
* >Communicating with Other Fragments</a> for more information. case REQUEST_CREATE_ALARM:
*/ case REQUEST_EDIT_ALARM:
public interface OnAlarmInteractionListener extends OnListItemInteractionListener<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();
}
} }

View File

@ -234,6 +234,7 @@ public class EditAlarmActivity extends BaseActivity implements AlarmNumpad.KeyLi
scheduleAlarm(alarm); scheduleAlarm(alarm);
} }
setResult(RESULT_OK);
showEditorClosed(); showEditorClosed();
} }
@ -246,6 +247,7 @@ public class EditAlarmActivity extends BaseActivity implements AlarmNumpad.KeyLi
} }
mDatabaseManager.deleteAlarm(mOldAlarm); mDatabaseManager.deleteAlarm(mOldAlarm);
} }
setResult(RESULT_OK);
showEditorClosed(); showEditorClosed();
} }