Removed PlaceholderView nesting

This commit is contained in:
Denis Karmyshakov 2018-09-07 13:42:08 +03:00
parent b2e3d6b0f0
commit 726f466c02
3 changed files with 21 additions and 119 deletions

View File

@ -20,9 +20,7 @@
package ru.touchin.roboswag.components.navigation.fragments;
import android.animation.Animator;
import android.content.Context;
import android.content.Intent;
import android.graphics.Canvas;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
@ -30,7 +28,6 @@ import android.os.SystemClock;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.FragmentActivity;
import android.support.v4.view.ViewCompat;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
@ -38,11 +35,9 @@ import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.widget.FrameLayout;
import java.lang.reflect.Constructor;
import ru.touchin.roboswag.components.R;
import ru.touchin.roboswag.components.navigation.viewcontrollers.ViewController;
import ru.touchin.roboswag.components.utils.UiUtils;
import ru.touchin.roboswag.core.log.Lc;
@ -152,15 +147,13 @@ public class ViewControllerFragment<TActivity extends FragmentActivity, TState e
@NonNull
private ViewController createViewController(
@NonNull final FragmentActivity activity,
@NonNull final PlaceholderView view,
@NonNull final ViewController.CreationContext creationContext,
@Nullable final Bundle savedInstanceState
) {
if (viewControllerClass.getConstructors().length != 1) {
throw new ShouldNotHappenException("There should be single constructor for " + viewControllerClass);
}
final Constructor<?> constructor = viewControllerClass.getConstructors()[0];
final ViewController.CreationContext creationContext = new ViewController.CreationContext(activity, this, view);
final long creationTime = inDebugMode ? SystemClock.elapsedRealtime() : 0;
try {
switch (constructor.getParameterTypes().length) {
@ -194,16 +187,16 @@ public class ViewControllerFragment<TActivity extends FragmentActivity, TState e
@Nullable final ViewGroup container,
@Nullable final Bundle savedInstanceState
) {
return new PlaceholderView(inflater.getContext(), viewControllerClass.getName());
viewController = createViewController(
new ViewController.CreationContext(requireActivity(), this, inflater, container), savedInstanceState);
viewController.onCreate();
return viewController.getView();
}
@Override
public void onActivityCreated(@Nullable final Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
//noinspection ConstantConditions
viewController = createViewController(requireActivity(), (PlaceholderView) getView(), savedInstanceState);
viewController.onCreate();
if (pendingActivityResult != null) {
if (viewController != null && pendingActivityResult != null) {
viewController.onActivityResult(pendingActivityResult.requestCode, pendingActivityResult.resultCode, pendingActivityResult.data);
pendingActivityResult = null;
}
@ -212,11 +205,6 @@ public class ViewControllerFragment<TActivity extends FragmentActivity, TState e
@Nullable
@Override
public Animation onCreateAnimation(final int transit, final boolean enter, final int nextAnim) {
if (nextAnim == R.anim.fragment_slide_in_right_animation || nextAnim == R.anim.fragment_slide_out_right_animation) {
ViewCompat.setTranslationZ(getView(), 1F);
} else {
ViewCompat.setTranslationZ(getView(), 0F);
}
if (viewController != null) {
return viewController.onCreateAnimation(transit, enter, nextAnim);
} else {
@ -346,39 +334,6 @@ public class ViewControllerFragment<TActivity extends FragmentActivity, TState e
}
}
private static class PlaceholderView extends FrameLayout {
@NonNull
private final String tagName;
private long lastMeasureTime;
public PlaceholderView(@NonNull final Context context, @NonNull final String tagName) {
super(context);
this.tagName = tagName;
}
@Override
protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if (inDebugMode && lastMeasureTime == 0) {
lastMeasureTime = SystemClock.uptimeMillis();
}
}
@Override
protected void onDraw(@NonNull final Canvas canvas) {
super.onDraw(canvas);
if (inDebugMode && lastMeasureTime > 0) {
final long layoutTime = SystemClock.uptimeMillis() - lastMeasureTime;
if (layoutTime > acceptableUiCalculationTime) {
UiUtils.UI_METRICS_LC_GROUP.w("Measure and layout of %s took too much: %dms", tagName, layoutTime);
}
lastMeasureTime = 0;
}
}
}
private static class ActivityResult {
public final int requestCode;
public final int resultCode;

View File

@ -1,21 +0,0 @@
package ru.touchin.roboswag.components.navigation.viewcontrollers
import android.os.Bundle
import android.os.Parcelable
import android.support.annotation.LayoutRes
import android.support.v4.app.FragmentActivity
abstract class DefaultViewController<TActivity : FragmentActivity, TState : Parcelable>(
@LayoutRes layoutRes: Int,
creationContext: CreationContext,
savedInstanceState: Bundle?
) : ViewController<TActivity, TState>(
creationContext,
savedInstanceState
) {
init {
setContentView(layoutRes)
}
}

View File

@ -41,6 +41,7 @@ import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.content.ContextCompat;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
@ -59,7 +60,7 @@ import ru.touchin.roboswag.core.log.Lc;
* @param <TActivity> Type of activity where such {@link ViewController} could be;
* @param <TState> Type of state;
*/
public class ViewController<TActivity extends FragmentActivity, TState extends Parcelable> implements LifecycleOwner {
public abstract class ViewController<TActivity extends FragmentActivity, TState extends Parcelable> implements LifecycleOwner {
@NonNull
private final LifecycleRegistry lifecycleRegistry = new LifecycleRegistry(this);
@ -68,14 +69,14 @@ public class ViewController<TActivity extends FragmentActivity, TState extends P
@NonNull
private final ViewControllerFragment<TActivity, TState> fragment;
@NonNull
private final ViewGroup container;
private final View view;
@SuppressWarnings({"unchecked", "PMD.UnusedFormalParameter"})
//UnusedFormalParameter: savedInstanceState could be used by children
public ViewController(@NonNull final CreationContext creationContext, @Nullable final Bundle savedInstanceState) {
public ViewController(@NonNull final CreationContext creationContext, @Nullable final Bundle savedInstanceState, @LayoutRes final int layoutRes) {
this.activity = (TActivity) creationContext.activity;
this.fragment = creationContext.fragment;
this.container = creationContext.container;
view = creationContext.inflater.inflate(layoutRes, creationContext.container, false);
}
@NonNull
@ -110,7 +111,7 @@ public class ViewController<TActivity extends FragmentActivity, TState extends P
* @return Returns state.
*/
@NonNull
protected final TState getState() {
public final TState getState() {
return fragment.getState();
}
@ -121,45 +122,8 @@ public class ViewController<TActivity extends FragmentActivity, TState extends P
* @return Returns view.
*/
@NonNull
protected final ViewGroup getContainer() {
return container;
}
/**
* Set the view controller content from a layout resource.
* This layout is placed directly into the container's ({@link #getContainer()}) view hierarchy.
*
* @param layoutResId Resource ID to be inflated.
*/
protected final void setContentView(@LayoutRes final int layoutResId) {
if (getContainer().getChildCount() > 0) {
getContainer().removeAllViews();
}
UiUtils.inflateAndAdd(layoutResId, getContainer());
}
/**
* Set the view controller content to an explicit view.
* This view is placed directly into the container's ({@link #getContainer()}) view hierarchy.
*
* @param view The desired content to display.
*/
protected final void setContentView(@NonNull final View view) {
setContentView(view, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
}
/**
* Set the view controller content to an explicit view with specific layout parameters.
* This view is placed directly into the container's ({@link #getContainer()}) view hierarchy.
*
* @param view The desired content to display;
* @param layoutParams Layout parameters for the view.
*/
protected final void setContentView(@NonNull final View view, @NonNull final ViewGroup.LayoutParams layoutParams) {
if (getContainer().getChildCount() > 0) {
getContainer().removeAllViews();
}
getContainer().addView(view, layoutParams);
public final View getView() {
return view;
}
/**
@ -170,7 +134,7 @@ public class ViewController<TActivity extends FragmentActivity, TState extends P
*/
@NonNull
public final <T extends View> T findViewById(@IdRes final int id) {
return getContainer().findViewById(id);
return getView().findViewById(id);
}
/**
@ -337,7 +301,7 @@ public class ViewController<TActivity extends FragmentActivity, TState extends P
public void onStart() {
UiUtils.UI_LIFECYCLE_LC_GROUP.i(Lc.getCodePoint(this));
lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
UiUtils.OfViews.hideSoftInput(getContainer());
UiUtils.OfViews.hideSoftInput(getView());
}
/**
@ -453,15 +417,19 @@ public class ViewController<TActivity extends FragmentActivity, TState extends P
@NonNull
private final ViewControllerFragment fragment;
@NonNull
private final LayoutInflater inflater;
@Nullable
private final ViewGroup container;
public CreationContext(
@NonNull final FragmentActivity activity,
@NonNull final ViewControllerFragment fragment,
@NonNull final ViewGroup container
@NonNull final LayoutInflater inflater,
@Nullable final ViewGroup container
) {
this.activity = activity;
this.fragment = fragment;
this.inflater = inflater;
this.container = container;
}