Files
react-navigation/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderSubview.java
Krzysztof Magiera 0919404b2e Add support for customizing back button image. (#253)
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).
2019-12-20 21:59:34 +01:00

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;
}
}