mirror of
https://github.com/zhigang1992/react-navigation.git
synced 2026-02-28 17:27:20 +08:00
For customizing back button image we use platform native functionality that is: `setBackIndicatorImage` on iOS and `setHomeAsUpIndicator` on Android. The reason we don't do that just by setting left item is that we get a couple of things for free such as handling RTL properly, working accessibility features, handling prop for hiding back button and a couple more. Unfortunately there are some downsides to that approach too. We need to install the back button as an Image component from the JS side, and the extract the image payload on the native side to set it with the navigator. This is specifically problematic in DEV mode where images are loaded asynchronously over HTTP from the packager. In order for that to work we had to employ a few hacks (more comments on that in the code).
79 lines
2.3 KiB
Java
79 lines
2.3 KiB
Java
package com.swmansion.rnscreens;
|
|
|
|
import android.view.View;
|
|
import android.view.ViewParent;
|
|
|
|
import com.facebook.react.bridge.ReactContext;
|
|
import com.facebook.react.uimanager.UIManagerModule;
|
|
import com.facebook.react.views.view.ReactViewGroup;
|
|
|
|
public class ScreenStackHeaderSubview extends ReactViewGroup {
|
|
|
|
public class Measurements {
|
|
public int width;
|
|
public int height;
|
|
}
|
|
|
|
public enum Type {
|
|
LEFT,
|
|
CENTER,
|
|
TITLE,
|
|
RIGHT,
|
|
BACK
|
|
}
|
|
|
|
private int mReactWidth, mReactHeight;
|
|
private final UIManagerModule mUIManager;
|
|
|
|
@Override
|
|
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
|
if (MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.EXACTLY &&
|
|
MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.EXACTLY) {
|
|
// dimensions provided by react
|
|
mReactWidth = MeasureSpec.getSize(widthMeasureSpec);
|
|
mReactHeight = MeasureSpec.getSize(heightMeasureSpec);
|
|
ViewParent parent = getParent();
|
|
if (parent != null) {
|
|
forceLayout();
|
|
((View) parent).requestLayout();
|
|
}
|
|
}
|
|
setMeasuredDimension(mReactWidth, mReactHeight);
|
|
}
|
|
|
|
@Override
|
|
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
|
|
if (changed && (mType == Type.CENTER || mType == Type.TITLE)) {
|
|
Measurements measurements = new Measurements();
|
|
measurements.width = right - left;
|
|
if (mType == Type.CENTER) {
|
|
// if we want the view to be centered we need to account for the fact that right and left
|
|
// paddings may not be equal.
|
|
View parent = (View) getParent();
|
|
int parentWidth = parent.getWidth();
|
|
int rightPadding = parentWidth - right;
|
|
int leftPadding = left;
|
|
measurements.width = Math.max(0, parentWidth - 2 * Math.max(rightPadding, leftPadding));
|
|
}
|
|
measurements.height = bottom - top;
|
|
mUIManager.setViewLocalData(getId(), measurements);
|
|
}
|
|
super.onLayout(changed, left, top, right, bottom);
|
|
}
|
|
|
|
private Type mType = Type.RIGHT;
|
|
|
|
public ScreenStackHeaderSubview(ReactContext context) {
|
|
super(context);
|
|
mUIManager = context.getNativeModule(UIManagerModule.class);
|
|
}
|
|
|
|
public void setType(Type type) {
|
|
mType = type;
|
|
}
|
|
|
|
public Type getType() {
|
|
return mType;
|
|
}
|
|
}
|