Skip to content

Commit 20104e2

Browse files
committed
added logging for potential future bug fixed. attempt to determine immersion based on the calling activities system ui visibility
1 parent 3d5189d commit 20104e2

File tree

3 files changed

+62
-41
lines changed

3 files changed

+62
-41
lines changed

.idea/vcs.xml

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

fragment/src/main/java/com/marksalpeter/fragment/ContractDialogFragment.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@
77

88
/**
99
* ContractDialogFragment is a dialog fragment whos parent fragment or parent activity must implement an interface
10-
* Created by Mark Salpeter. Original concepts taken from Jake Thwarton
10+
* Created by Mark Salpeter. Original concepts taken from Jake Wharton
1111
* see https://gist.github.com/JakeWharton/2621173
1212
*/
13-
public abstract class ContractDialogFragment<T> extends ImmersiveDialogFragment {
13+
public abstract class ContractDialogFragment<T> extends DialogFragment {
1414

1515
public final static String TAG = ContractDialogFragment.class.getSimpleName();
1616

fragment/src/main/java/com/marksalpeter/fragment/ImmersiveDialogFragment.java renamed to fragment/src/main/java/com/marksalpeter/fragment/DialogFragment.java

Lines changed: 54 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
import android.animation.AnimatorInflater;
55
import android.animation.ValueAnimator;
66
import android.app.Dialog;
7-
import android.app.DialogFragment;
87
import android.app.Fragment;
98
import android.content.res.Resources;
109
import android.graphics.Color;
@@ -23,13 +22,16 @@
2322
import java.lang.reflect.Field;
2423

2524
/**
26-
* ImmersiveDialogFragment is a dialog fragment with no decoration that will take up as much of the screen
27-
* as possible
25+
* DialogFragment is a dialog fragment with the fragment animation bug fix applied and an immersive mode
26+
* bug fix applied (when
27+
* read more about the bug fixes here:
28+
* - http://stackoverflow.com/questions/14900738/nested-fragments-disappear-during-transition-animation
29+
* - https://stackoverflow.com/questions/32758559/maintain-immersive-mode-when-dialogfragment-is-shown
2830
* Created by Mark on 11/9/16.
2931
*/
30-
abstract class ImmersiveDialogFragment extends DialogFragment implements ViewTreeObserver.OnGlobalLayoutListener {
32+
public abstract class DialogFragment extends android.app.DialogFragment implements ViewTreeObserver.OnGlobalLayoutListener {
3133

32-
private static String TAG = ImmersiveDialogFragment.class.getSimpleName();
34+
private static String TAG = DialogFragment.class.getSimpleName();
3335

3436
/**
3537
* sDefaultChildAnimationDuration is an arbitrary, but reasonable transition duration we can use if
@@ -39,8 +41,16 @@ abstract class ImmersiveDialogFragment extends DialogFragment implements ViewTre
3941

4042
private Dialog mDialog;
4143
private Handler mHandler;
44+
private boolean mIsImmersive;
4245

43-
@Override public Dialog onCreateDialog(final Bundle savedInstanceState) {
46+
@Override public Dialog onCreateDialog(Bundle savedInstanceState) {
47+
48+
// check to see if the dialog is immersive
49+
mIsImmersive = (getActivity().getWindow().getDecorView().getSystemUiVisibility() & View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY) == View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
50+
if (!mIsImmersive) {
51+
Log.d(TAG, getActivity().getWindow().getDecorView().getSystemUiVisibility() + " is not immersive");
52+
return super.onCreateDialog(savedInstanceState);
53+
}
4454

4555
// create a handler
4656
mHandler = new Handler();
@@ -94,9 +104,8 @@ public boolean onTouch(View v, MotionEvent event) {
94104
super.onDestroyView();
95105
}
96106

97-
@Override
98-
public void onGlobalLayout() {
99-
if (!isDialog()) {
107+
@Override public void onGlobalLayout() {
108+
if (!isDialog() || !mIsImmersive) {
100109
return;
101110
}
102111
mHandler.postDelayed(new Runnable() {
@@ -109,7 +118,7 @@ public void run() {
109118

110119
@Override public void onResume() {
111120
super.onResume();
112-
if (!isDialog()) {
121+
if (!isDialog() || !mIsImmersive) {
113122
return;
114123
}
115124

@@ -120,40 +129,33 @@ public void run() {
120129
EditText firstEditText = getFirstEditText((ViewGroup) mDialog.getWindow().getDecorView());
121130
if (firstEditText != null) {
122131
mDialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
123-
Log.d("FFF", firstEditText.toString() + " | " + firstEditText.getText().toString() + " " + firstEditText.getText().length());
124132
firstEditText.setSelection(firstEditText.getText().length());
125133
}
126134
}
127135

136+
/**
137+
* onCreateAnimator is overridden to fix the following animation bug:
138+
* http://stackoverflow.com/questions/14900738/nested-fragments-disappear-during-transition-animation
139+
*/
128140
@Override public Animator onCreateAnimator(int transit, boolean enter, int nextAnim) {
129-
130-
// if a child fragment is being removed because its parent is being removed
131-
// return a fake animator that lasts the duration of the parent's animator
132-
Fragment removingParentFragment = getRemovingParent(getParentFragment());
133-
if (!enter && removingParentFragment != null) {
134-
// This is a workaround for the bug where child fragments disappear when
135-
// the parent is removed (as all children are first removed from the parent)
136-
// See https://code.google.com/p/android/issues/detail?id=55228
137-
long duration = getNextAnimatiorDuration(removingParentFragment);
138-
Log.d(TAG, "TAG: " + getTag() + " | DURATION: " + duration);
139-
return ValueAnimator.ofFloat(0, 1).setDuration(duration);
141+
if(!enter) {
142+
Fragment removingParentFragment = getRemovingParentFragment();
143+
if (removingParentFragment != null) {
144+
return ValueAnimator.ofFloat(0f, 1f).setDuration(getNextAnimatorDuration(removingParentFragment));
145+
}
140146
}
141-
142-
// inflate the animator
143-
Animator animator = null;
144-
try {
145-
animator = AnimatorInflater.loadAnimator(getActivity(), nextAnim);
146-
} catch (Exception e) {}
147-
148-
return animator;
147+
return super.onCreateAnimator(transit, enter, nextAnim);
149148
}
150149

150+
151151
/**
152-
* getRemovingParent returns the first fragment or parent fragment that is removing r null if it can't find one
152+
* getRemovingParentFragment returns the first fragment or parent fragment that is removing r null if it can't find one
153153
*/
154-
private static Fragment getRemovingParent(Fragment fragment) {
154+
private android.app.Fragment getRemovingParentFragment() {
155+
android.app.Fragment fragment = getParentFragment();
155156
while (fragment != null) {
156157
if (fragment.isRemoving()) {
158+
Log.v(TAG, fragment.toString() + " is removing");
157159
return fragment;
158160
}
159161
fragment = fragment.getParentFragment();
@@ -163,29 +165,35 @@ private static Fragment getRemovingParent(Fragment fragment) {
163165

164166
/**
165167
* getNextAnimationDuration returns the "mNextAnim" animators duration
166-
* TODO: this is broken, so i just set sDefaultChildAnimationDuration to @integer/slide_transition_duration
168+
* TODO: this needs a bug fix, but its not mission critical unless people are adding fragment transition
167169
*/
168-
private static long getNextAnimatiorDuration(Fragment fragment) {
170+
private static long getNextAnimatorDuration(android.app.Fragment fragment) {
169171
try {
170172

171173
// attempt to get the resource ID of the next animation that will be applied to the given fragment.
172-
Field nextAnimField = Fragment.class.getDeclaredField("mNextAnim");
174+
Field nextAnimField = android.app.Fragment.class.getDeclaredField("mNextAnim");
173175
nextAnimField.setAccessible(true);
174-
int nextAnimResource = nextAnimField.getInt(fragment);
176+
int nextAnimResourceID = nextAnimField.getInt(fragment);
177+
178+
Log.v(TAG, "nextAnimResourceID: " + nextAnimResourceID);
179+
if (nextAnimResourceID < 1) {
180+
return sDefaultChildAnimationDuration;
181+
}
175182

176183
// load the animator
177-
Animator nextAnim = AnimatorInflater.loadAnimator(fragment.getActivity(), nextAnimResource);
184+
Animator nextAnim = AnimatorInflater.loadAnimator(fragment.getActivity(), nextAnimResourceID);
185+
186+
Log.v(TAG, "nextAnim.getDuration(): " + nextAnim.getDuration());
178187

179188
// return its duration
180189
return(nextAnim == null || nextAnim.getDuration() < 0) ? sDefaultChildAnimationDuration : nextAnim.getDuration();
181190

182191
} catch (NoSuchFieldException|IllegalAccessException|Resources.NotFoundException ex) {
183-
// Log.w(TAG, "Unable to load next animation from parent.", ex);
192+
Log.e(TAG, ex.getMessage(), ex);
184193
return sDefaultChildAnimationDuration;
185194
}
186195
}
187196

188-
189197
/**
190198
* getFirstEditText returns the first edit text in the parents hierarchy
191199
*/
@@ -236,4 +244,11 @@ private boolean isDialog() {
236244
return mDialog != null && mDialog.getWindow() != null;
237245
}
238246

247+
/**
248+
* isImmersive returns true if the dialog was initialized in immersive mode
249+
*/
250+
protected boolean isImmersive() {
251+
return mIsImmersive;
252+
}
253+
239254
}

0 commit comments

Comments
 (0)