summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYuutaW <17158086+trumeet@users.noreply.github.com>2019-04-13 14:27:50 -0700
committerYuutaW <17158086+Trumeet@users.noreply.github.com>2019-04-13 14:27:50 -0700
commitaee4c4f0f4c644dd024cef2c5fa084af0684c1ac (patch)
tree71357320f902df739ed4c4d87271db92f3a099f1
parent64d97258a1b8c293f5cd0adcc179e60c01c9ca85 (diff)
downloadFlow-aee4c4f0f4c644dd024cef2c5fa084af0684c1ac.tar
Flow-aee4c4f0f4c644dd024cef2c5fa084af0684c1ac.tar.gz
Flow-aee4c4f0f4c644dd024cef2c5fa084af0684c1ac.tar.bz2
Flow-aee4c4f0f4c644dd024cef2c5fa084af0684c1ac.zip
fix(app/library): add instance state handling
Signed-off-by: YuutaW <17158086+Trumeet@users.noreply.github.com>
-rw-r--r--app/src/main/java/moe/yuuta/flow/MainActivity.java33
-rw-r--r--library/src/main/java/moe/yuuta/flow/FlowFragment.java63
-rw-r--r--library/src/main/java/moe/yuuta/flow/PageFragment.java15
-rw-r--r--library/src/main/java/moe/yuuta/flow/widgets/FlowPager.java4
4 files changed, 84 insertions, 31 deletions
diff --git a/app/src/main/java/moe/yuuta/flow/MainActivity.java b/app/src/main/java/moe/yuuta/flow/MainActivity.java
index cba4bbd..d827aa6 100644
--- a/app/src/main/java/moe/yuuta/flow/MainActivity.java
+++ b/app/src/main/java/moe/yuuta/flow/MainActivity.java
@@ -6,6 +6,7 @@ import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.widget.Button;
import android.widget.TextView;
import androidx.annotation.NonNull;
@@ -26,9 +27,9 @@ public class MainActivity extends AppCompatActivity {
super.onCreate(savedInstanceState);
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
Log.i(TAG, "onCreate()");
- if (mFragment == null) {
+ if (mFragment == null && savedInstanceState == null) {
mFragment = new FlowFragment();
- mFragment.setPages(Arrays.asList(new Page1(), new Page2(), new Page3()));
+ mFragment.setPages(Arrays.asList(new Page1(), new Page2(), new Page3(), new Page4()));
getSupportFragmentManager()
.beginTransaction()
.replace(android.R.id.content, mFragment)
@@ -95,6 +96,34 @@ public class MainActivity extends AppCompatActivity {
}
}
+ public static class Page4 extends PageFragment {
+ public Page4() {
+ mInfo = new FlowInfo(new HeaderConfig("Page 4", "just a counter", false), null);
+ }
+
+ // TODO: The FlowFragment keeps the instance, maybe we don't want that happened to child fragments.
+ private int mCount;
+
+ @Nullable
+ @Override
+ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
+ Button button = new Button(requireContext());
+ button.setMinHeight(20);
+ button.setText("+1s");
+ button.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ mCount++;
+ HeaderConfig config = mInfo.getHeaderConfig();
+ config.setSubtitleText(Integer.toString(mCount));
+ mInfo.setHeaderConfig(config);
+ getHostFragment().notifyCurrentFlowInfoUpdated();
+ }
+ });
+ return button;
+ }
+ }
+
@Override
public void onBackPressed() {
if (mFragment != null && mFragment.onBackPressed()) return;
diff --git a/library/src/main/java/moe/yuuta/flow/FlowFragment.java b/library/src/main/java/moe/yuuta/flow/FlowFragment.java
index d7d4776..87deaf2 100644
--- a/library/src/main/java/moe/yuuta/flow/FlowFragment.java
+++ b/library/src/main/java/moe/yuuta/flow/FlowFragment.java
@@ -1,6 +1,7 @@
package moe.yuuta.flow;
import android.os.Bundle;
+import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -9,21 +10,25 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.fragment.app.Fragment;
-import androidx.fragment.app.FragmentManager;
-import androidx.fragment.app.FragmentPagerAdapter;
+import androidx.fragment.app.FragmentStatePagerAdapter;
import androidx.viewpager.widget.ViewPager;
import java.util.ArrayList;
import java.util.List;
/**
- * The Host fragment
+ * The Host fragment. It is marked as final because it was set to remain instance.
*/
-public class FlowFragment extends Fragment implements IFlowFragment, View.OnClickListener {
+public final class FlowFragment extends Fragment implements IFlowFragment, View.OnClickListener {
+ private static final String TAG = "FlowFragment";
+
private List<PageFragment> mPages = new ArrayList<>(0);
// true: after the view settles, update the UI immediately.
private volatile boolean mUIUpdateScheduled;
+ private static final String ARG_CURRENT = FlowFragment.class.getName() + ".ARG_CURRENT";
+ private static final String ARG_UI_UPDATE_SCHEDULED = FlowFragment.class.getName() + ".ARG_UI_UPDATE_SCHEDULED";
+
private Header mHeader;
private ViewPager mPager;
private NavigationBar mNav;
@@ -73,18 +78,17 @@ public class FlowFragment extends Fragment implements IFlowFragment, View.OnClic
}
}
- @Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
+ if (getView() != null) return getView();
final View view = inflater.inflate(R.layout.fragment_flow, container, false);
mHeader = new Header(view.<ConstraintLayout>findViewById(R.id.flow_host_header));
mNav = new NavigationBar(view.<ConstraintLayout>findViewById(R.id.flow_host_nav));
mPager = view.findViewById(R.id.flow_host_pager);
- mPager.setAdapter(new FragmentPagerAdapter(getChildFragmentManager()) {
+ mPager.setAdapter(new FragmentStatePagerAdapter(getChildFragmentManager()) {
@Override
public Fragment getItem(int position) {
- PageFragment fragment = mPages.get(position);
- return fragment;
+ return mPages.get(position);
}
@Override
@@ -93,13 +97,11 @@ public class FlowFragment extends Fragment implements IFlowFragment, View.OnClic
}
});
mPager.addOnPageChangeListener(mPageListener);
- getChildFragmentManager().registerFragmentLifecycleCallbacks(mCallback, false);
return view;
}
@Override
public void onDestroyView() {
- getChildFragmentManager().unregisterFragmentLifecycleCallbacks(mCallback);
mPager.removeOnPageChangeListener(mPageListener);
super.onDestroyView();
}
@@ -107,6 +109,11 @@ public class FlowFragment extends Fragment implements IFlowFragment, View.OnClic
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
+ Log.d(TAG, "onViewCreated");
+ if (savedInstanceState != null) {
+ Log.d(TAG, "onViewCreated - restore " + savedInstanceState.getInt(ARG_CURRENT, -1));
+ mPager.setCurrentItem(savedInstanceState.getInt(ARG_CURRENT, 0));
+ }
if (mUIUpdateScheduled) {
updateUI();
mUIUpdateScheduled = false;
@@ -143,16 +150,6 @@ public class FlowFragment extends Fragment implements IFlowFragment, View.OnClic
mPager.setCurrentItem(index, true);
}
- private FragmentManager.FragmentLifecycleCallbacks mCallback = new FragmentManager.FragmentLifecycleCallbacks() {
- @Override
- public void onFragmentPreCreated(@NonNull FragmentManager fm, @NonNull Fragment f, @Nullable Bundle savedInstanceState) {
- if (f instanceof PageFragment) {
- final PageFragment pf = (PageFragment) f;
- pf.setHostFragment(FlowFragment.this);
- }
- }
- };
-
private ViewPager.OnPageChangeListener mPageListener = new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
@@ -191,4 +188,30 @@ public class FlowFragment extends Fragment implements IFlowFragment, View.OnClic
public View.OnClickListener getGeneralFlowNavListener() {
return this;
}
+
+ @Override
+ public void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ // To save the child fragment instances
+ setRetainInstance(true);
+ }
+
+ @Override
+ public void onSaveInstanceState(@NonNull Bundle outState) {
+ super.onSaveInstanceState(outState);
+ Log.d(TAG, "save");
+ if (mPager != null) outState.putInt(ARG_CURRENT, mPager.getCurrentItem());
+ if (mPager != null) Log.d(TAG, "current " + mPager.getCurrentItem());
+ outState.putBoolean(ARG_UI_UPDATE_SCHEDULED, mUIUpdateScheduled);
+ }
+
+ @Override
+ public void onActivityCreated(@Nullable Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+ Log.d(TAG, "onActivityCreated");
+ if (savedInstanceState != null) {
+ Log.d(TAG, "restore");
+ mUIUpdateScheduled = savedInstanceState.getBoolean(ARG_UI_UPDATE_SCHEDULED, false);
+ }
+ }
}
diff --git a/library/src/main/java/moe/yuuta/flow/PageFragment.java b/library/src/main/java/moe/yuuta/flow/PageFragment.java
index dcc9f21..4e7996b 100644
--- a/library/src/main/java/moe/yuuta/flow/PageFragment.java
+++ b/library/src/main/java/moe/yuuta/flow/PageFragment.java
@@ -1,24 +1,25 @@
package moe.yuuta.flow;
+import android.util.Log;
+
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
public abstract class PageFragment extends Fragment {
- private IFlowFragment mHostFragment;
-
/**
* Once mInfo is changed, you should call {@link IFlowFragment#notifyCurrentFlowInfoUpdated()} to publish it.
* Note: it will be permanently change the recorded info.
*/
protected FlowInfo mInfo;
- final void setHostFragment(@NonNull IFlowFragment hostFragment) {
- this.mHostFragment = hostFragment;
- }
-
@NonNull
protected final IFlowFragment getHostFragment() {
- return mHostFragment;
+ final Fragment parent = getParentFragment();
+ if (!(parent instanceof IFlowFragment)) {
+ throw new IllegalStateException("This fragment is not attached to a valid flow host");
+ }
+ Log.d("Page", "get");
+ return (IFlowFragment) parent;
}
/**
diff --git a/library/src/main/java/moe/yuuta/flow/widgets/FlowPager.java b/library/src/main/java/moe/yuuta/flow/widgets/FlowPager.java
index c821eef..e76f319 100644
--- a/library/src/main/java/moe/yuuta/flow/widgets/FlowPager.java
+++ b/library/src/main/java/moe/yuuta/flow/widgets/FlowPager.java
@@ -8,7 +8,7 @@ import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
-import androidx.fragment.app.FragmentPagerAdapter;
+import androidx.fragment.app.FragmentStatePagerAdapter;
import androidx.viewpager.widget.ViewPager;
public class FlowPager extends ViewPager {
@@ -27,7 +27,7 @@ public class FlowPager extends ViewPager {
if(null != getAdapter()) {
int height = 0;
- View child = ((FragmentPagerAdapter) getAdapter()).getItem(getCurrentItem()).getView();
+ View child = ((FragmentStatePagerAdapter) getAdapter()).getItem(getCurrentItem()).getView();
if (child != null) {
child.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
height = child.getMeasuredHeight();