Skip to content

Commit

Permalink
added logging for potential future bug fixed. attempt to determine im…
Browse files Browse the repository at this point in the history
…mersion based on the calling activities system ui visibility
  • Loading branch information
marksalpeter committed Feb 12, 2018
1 parent 3d5189d commit 20104e2
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 41 deletions.
6 changes: 6 additions & 0 deletions .idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@

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

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import android.animation.AnimatorInflater;
import android.animation.ValueAnimator;
import android.app.Dialog;
import android.app.DialogFragment;
import android.app.Fragment;
import android.content.res.Resources;
import android.graphics.Color;
Expand All @@ -23,13 +22,16 @@
import java.lang.reflect.Field;

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

private static String TAG = ImmersiveDialogFragment.class.getSimpleName();
private static String TAG = DialogFragment.class.getSimpleName();

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

private Dialog mDialog;
private Handler mHandler;
private boolean mIsImmersive;

@Override public Dialog onCreateDialog(final Bundle savedInstanceState) {
@Override public Dialog onCreateDialog(Bundle savedInstanceState) {

// check to see if the dialog is immersive
mIsImmersive = (getActivity().getWindow().getDecorView().getSystemUiVisibility() & View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY) == View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
if (!mIsImmersive) {
Log.d(TAG, getActivity().getWindow().getDecorView().getSystemUiVisibility() + " is not immersive");
return super.onCreateDialog(savedInstanceState);
}

// create a handler
mHandler = new Handler();
Expand Down Expand Up @@ -94,9 +104,8 @@ public boolean onTouch(View v, MotionEvent event) {
super.onDestroyView();
}

@Override
public void onGlobalLayout() {
if (!isDialog()) {
@Override public void onGlobalLayout() {
if (!isDialog() || !mIsImmersive) {
return;
}
mHandler.postDelayed(new Runnable() {
Expand All @@ -109,7 +118,7 @@ public void run() {

@Override public void onResume() {
super.onResume();
if (!isDialog()) {
if (!isDialog() || !mIsImmersive) {
return;
}

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

/**
* onCreateAnimator is overridden to fix the following animation bug:
* http://stackoverflow.com/questions/14900738/nested-fragments-disappear-during-transition-animation
*/
@Override public Animator onCreateAnimator(int transit, boolean enter, int nextAnim) {

// if a child fragment is being removed because its parent is being removed
// return a fake animator that lasts the duration of the parent's animator
Fragment removingParentFragment = getRemovingParent(getParentFragment());
if (!enter && removingParentFragment != null) {
// This is a workaround for the bug where child fragments disappear when
// the parent is removed (as all children are first removed from the parent)
// See https://code.google.com/p/android/issues/detail?id=55228
long duration = getNextAnimatiorDuration(removingParentFragment);
Log.d(TAG, "TAG: " + getTag() + " | DURATION: " + duration);
return ValueAnimator.ofFloat(0, 1).setDuration(duration);
if(!enter) {
Fragment removingParentFragment = getRemovingParentFragment();
if (removingParentFragment != null) {
return ValueAnimator.ofFloat(0f, 1f).setDuration(getNextAnimatorDuration(removingParentFragment));
}
}

// inflate the animator
Animator animator = null;
try {
animator = AnimatorInflater.loadAnimator(getActivity(), nextAnim);
} catch (Exception e) {}

return animator;
return super.onCreateAnimator(transit, enter, nextAnim);
}


/**
* getRemovingParent returns the first fragment or parent fragment that is removing r null if it can't find one
* getRemovingParentFragment returns the first fragment or parent fragment that is removing r null if it can't find one
*/
private static Fragment getRemovingParent(Fragment fragment) {
private android.app.Fragment getRemovingParentFragment() {
android.app.Fragment fragment = getParentFragment();
while (fragment != null) {
if (fragment.isRemoving()) {
Log.v(TAG, fragment.toString() + " is removing");
return fragment;
}
fragment = fragment.getParentFragment();
Expand All @@ -163,29 +165,35 @@ private static Fragment getRemovingParent(Fragment fragment) {

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

// attempt to get the resource ID of the next animation that will be applied to the given fragment.
Field nextAnimField = Fragment.class.getDeclaredField("mNextAnim");
Field nextAnimField = android.app.Fragment.class.getDeclaredField("mNextAnim");
nextAnimField.setAccessible(true);
int nextAnimResource = nextAnimField.getInt(fragment);
int nextAnimResourceID = nextAnimField.getInt(fragment);

Log.v(TAG, "nextAnimResourceID: " + nextAnimResourceID);
if (nextAnimResourceID < 1) {
return sDefaultChildAnimationDuration;
}

// load the animator
Animator nextAnim = AnimatorInflater.loadAnimator(fragment.getActivity(), nextAnimResource);
Animator nextAnim = AnimatorInflater.loadAnimator(fragment.getActivity(), nextAnimResourceID);

Log.v(TAG, "nextAnim.getDuration(): " + nextAnim.getDuration());

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

} catch (NoSuchFieldException|IllegalAccessException|Resources.NotFoundException ex) {
// Log.w(TAG, "Unable to load next animation from parent.", ex);
Log.e(TAG, ex.getMessage(), ex);
return sDefaultChildAnimationDuration;
}
}


/**
* getFirstEditText returns the first edit text in the parents hierarchy
*/
Expand Down Expand Up @@ -236,4 +244,11 @@ private boolean isDialog() {
return mDialog != null && mDialog.getWindow() != null;
}

/**
* isImmersive returns true if the dialog was initialized in immersive mode
*/
protected boolean isImmersive() {
return mIsImmersive;
}

}

0 comments on commit 20104e2

Please sign in to comment.