mirror of
https://github.com/zhigang1992/react-navigation.git
synced 2026-02-09 17:23:18 +08:00
Fix header rendering – layout and transparency (#184)
* Let UINavController control subcontroller view's frames. This PR changes the way we've been handling yoga <> NavController layout interactions. Now we ignore frame updates coming from react for the main Screen view to allow NavController take the controll. In order to keep yoga working we now use `setSize` to pass the dimensions of the view back to yoga such that it can properly calculate layout of the views under Screen component. * Header resizing fixes for Android. In this change we use CoordinatorLayout as a stack screen container to handle rendering of toolbar and screen content. Thanks to this approach we can support collapsable bars in the future. Instead of relying on RN to layout screen container when renered under ScreenStack we rely on Android native layout to measure and position screen content and then use UIManager.setNodeSize to communicate that back to react.
This commit is contained in:
committed by
GitHub
parent
c590283359
commit
4a9a3a877a
@@ -1,6 +1,7 @@
|
||||
package com.swmansion.rnscreens;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.util.TypedValue;
|
||||
@@ -16,42 +17,10 @@ import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import com.facebook.react.uimanager.PixelUtil;
|
||||
import com.facebook.react.views.text.ReactFontManager;
|
||||
|
||||
public class ScreenStackHeaderConfig extends ViewGroup {
|
||||
|
||||
private static final float TOOLBAR_ELEVATION = PixelUtil.toPixelFromDIP(4);
|
||||
|
||||
private static final class ToolbarWithLayoutLoop extends Toolbar {
|
||||
|
||||
private final Runnable mLayoutRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mLayoutEnqueued = false;
|
||||
measure(
|
||||
MeasureSpec.makeMeasureSpec(getWidth(), MeasureSpec.EXACTLY),
|
||||
MeasureSpec.makeMeasureSpec(getHeight(), MeasureSpec.EXACTLY));
|
||||
layout(getLeft(), getTop(), getRight(), getBottom());
|
||||
}
|
||||
};
|
||||
private boolean mLayoutEnqueued = false;
|
||||
|
||||
public ToolbarWithLayoutLoop(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void requestLayout() {
|
||||
super.requestLayout();
|
||||
|
||||
if (!mLayoutEnqueued) {
|
||||
mLayoutEnqueued = true;
|
||||
post(mLayoutRunnable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final ScreenStackHeaderSubview mConfigSubviews[] = new ScreenStackHeaderSubview[3];
|
||||
private int mSubviewsCount = 0;
|
||||
private String mTitle;
|
||||
@@ -63,20 +32,18 @@ public class ScreenStackHeaderConfig extends ViewGroup {
|
||||
private boolean mIsBackButtonHidden;
|
||||
private boolean mIsShadowHidden;
|
||||
private int mTintColor;
|
||||
private int mWidth;
|
||||
private int mHeight;
|
||||
private final Toolbar mToolbar;
|
||||
|
||||
private OnBackPressedCallback mBackCallback = new OnBackPressedCallback(false) {
|
||||
@Override
|
||||
public void handleOnBackPressed() {
|
||||
getScreenStack().dismiss(getScreen());
|
||||
getScreenStack().dismiss(getScreenFragment());
|
||||
}
|
||||
};
|
||||
private OnClickListener mBackClickListener = new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
getScreenStack().dismiss(getScreen());
|
||||
getScreenStack().dismiss(getScreenFragment());
|
||||
}
|
||||
};
|
||||
|
||||
@@ -84,36 +51,18 @@ public class ScreenStackHeaderConfig extends ViewGroup {
|
||||
super(context);
|
||||
setVisibility(View.GONE);
|
||||
|
||||
mToolbar = new ToolbarWithLayoutLoop(context);
|
||||
mToolbar = new Toolbar(context);
|
||||
|
||||
// set primary color as background by default
|
||||
TypedValue tv = new TypedValue();
|
||||
if (context.getTheme().resolveAttribute(android.R.attr.colorPrimary, tv, true)) {
|
||||
mToolbar.setBackgroundColor(tv.data);
|
||||
}
|
||||
|
||||
mWidth = 0;
|
||||
mHeight = 0;
|
||||
|
||||
if (context.getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true)) {
|
||||
mHeight = TypedValue.complexToDimensionPixelSize(tv.data, getResources().getDisplayMetrics());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void updateToolbarLayout() {
|
||||
mToolbar.measure(
|
||||
View.MeasureSpec.makeMeasureSpec(mWidth, View.MeasureSpec.EXACTLY),
|
||||
View.MeasureSpec.makeMeasureSpec(mHeight, View.MeasureSpec.EXACTLY));
|
||||
mToolbar.layout(0, 0, mWidth, mHeight);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLayout(boolean changed, int l, int t, int r, int b) {
|
||||
if (mWidth != (r - l)) {
|
||||
mWidth = (r - l);
|
||||
updateToolbarLayout();
|
||||
}
|
||||
// no-op
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -141,10 +90,13 @@ public class ScreenStackHeaderConfig extends ViewGroup {
|
||||
return null;
|
||||
}
|
||||
|
||||
private Fragment getScreenFragment() {
|
||||
private ScreenStackFragment getScreenFragment() {
|
||||
ViewParent screen = getParent();
|
||||
if (screen instanceof Screen) {
|
||||
return ((Screen) screen).getFragment();
|
||||
Fragment fragment = ((Screen) screen).getFragment();
|
||||
if (fragment instanceof ScreenStackFragment) {
|
||||
return (ScreenStackFragment) fragment;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -159,16 +111,16 @@ public class ScreenStackHeaderConfig extends ViewGroup {
|
||||
Screen parent = (Screen) getParent();
|
||||
if (mIsHidden) {
|
||||
if (mToolbar.getParent() != null) {
|
||||
parent.removeView(mToolbar);
|
||||
getScreenFragment().removeToolbar();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (mToolbar.getParent() == null) {
|
||||
parent.addView(mToolbar);
|
||||
getScreenFragment().setToolbar(mToolbar);
|
||||
}
|
||||
|
||||
AppCompatActivity activity = (AppCompatActivity) parent.getFragment().getActivity();
|
||||
AppCompatActivity activity = (AppCompatActivity) getScreenFragment().getActivity();
|
||||
activity.setSupportActionBar(mToolbar);
|
||||
ActionBar actionBar = activity.getSupportActionBar();
|
||||
|
||||
@@ -188,7 +140,7 @@ public class ScreenStackHeaderConfig extends ViewGroup {
|
||||
|
||||
|
||||
// shadow
|
||||
actionBar.setElevation(mIsShadowHidden ? 0 : TOOLBAR_ELEVATION);
|
||||
getScreenFragment().setToolbarShadowHidden(mIsShadowHidden);
|
||||
|
||||
// title
|
||||
actionBar.setTitle(mTitle);
|
||||
|
||||
Reference in New Issue
Block a user