update: add minimal3 frame

This commit is contained in:
2026-05-31 23:26:09 +02:00
parent fb293d840c
commit 3ec6654e9d
71 changed files with 1020 additions and 17291 deletions
@@ -0,0 +1,81 @@
def safeExtGet(prop, fallback) {
rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
}
buildscript {
if (project == rootProject) {
repositories {
google()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:4.1.2'
}
}
}
apply plugin: 'com.android.library'
def agpVersion = com.android.Version.ANDROID_GRADLE_PLUGIN_VERSION.tokenize('.')[0].toInteger()
def shouldUseNameSpace = agpVersion >= 7
def PACKAGE_PROP = "package=\"org.reactnative.maskedview\""
def manifestOutFile = file("${projectDir}/src/main/AndroidManifest.xml")
def manifestContent = manifestOutFile.getText()
if(shouldUseNameSpace){
manifestContent = manifestContent.replaceAll(
PACKAGE_PROP,
''
)
} else {
if(!manifestContent.contains("$PACKAGE_PROP")){
manifestContent = manifestContent.replace(
'<manifest',
"<manifest $PACKAGE_PROP "
)
}
}
manifestContent.replaceAll(" ", " ")
manifestOutFile.write(manifestContent)
android {
compileSdkVersion safeExtGet('compileSdkVersion', 28)
if(shouldUseNameSpace){
namespace = "org.reactnative.maskedview"
}
defaultConfig {
minSdkVersion safeExtGet('minSdkVersion', 16)
targetSdkVersion safeExtGet('targetSdkVersion', 28)
}
sourceSets {
main {
java.srcDirs = ['src/main/java']
}
}
lintOptions {
abortOnError false
warning 'InvalidPackage'
}
buildTypes {
release {
}
}
}
repositories {
google()
maven { url "https://jitpack.io" }
mavenCentral()
maven {
// All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
url "$rootDir/../node_modules/react-native/android"
}
}
dependencies {
implementation 'com.facebook.react:react-native:+'
}
@@ -0,0 +1,2 @@
<manifest package="org.reactnative.maskedview" xmlns:android="http://schemas.android.com/apk/res/android">
</manifest>
Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

@@ -0,0 +1,112 @@
package org.reactnative.maskedview;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.view.View;
import com.facebook.react.views.view.ReactViewGroup;
public class RNCMaskedView extends ReactViewGroup {
private static final String TAG = "RNCMaskedView";
private Bitmap mBitmapMask = null;
private boolean mBitmapMaskInvalidated = false;
private Paint mPaint;
private PorterDuffXfermode mPorterDuffXferMode;
private int mRenderingMode = View.LAYER_TYPE_HARDWARE;
public RNCMaskedView(Context context) {
super(context);
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPorterDuffXferMode = new PorterDuffXfermode(PorterDuff.Mode.DST_IN);
}
@Override
protected void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas);
if (mBitmapMaskInvalidated) {
// redraw mask element to support animated elements
updateBitmapMask();
mBitmapMaskInvalidated = false;
}
// draw the mask
if (mBitmapMask != null) {
setLayerType(mRenderingMode, mPaint);
mPaint.setXfermode(mPorterDuffXferMode);
canvas.drawBitmap(mBitmapMask, 0, 0, mPaint);
mPaint.setXfermode(null);
}
}
@Override
public void onDescendantInvalidated(View child, View target) {
super.onDescendantInvalidated(child, target);
if (!mBitmapMaskInvalidated) {
View maskView = getChildAt(0);
if (maskView != null) {
if (maskView.equals(child)) {
mBitmapMaskInvalidated = true;
}
}
}
invalidate();
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
if (changed) {
mBitmapMaskInvalidated = true;
}
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
mBitmapMaskInvalidated = true;
}
private void updateBitmapMask() {
View maskView = getChildAt(0);
if (maskView != null) {
maskView.setVisibility(View.VISIBLE);
if (this.mBitmapMask != null) {
this.mBitmapMask.recycle();
}
this.mBitmapMask = getBitmapFromView(maskView);
maskView.setVisibility(View.INVISIBLE);
}
}
public static Bitmap getBitmapFromView(final View view) {
view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
if (view.getMeasuredWidth() <= 0 || view.getMeasuredHeight() <= 0) {
return null;
}
final Bitmap bitmap = Bitmap.createBitmap(view.getMeasuredWidth(),
view.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
final Canvas canvas = new Canvas(bitmap);
view.draw(canvas);
return bitmap;
}
public void setRenderingMode(String renderingMode) {
mRenderingMode = renderingMode.equals("software") ? View.LAYER_TYPE_SOFTWARE : View.LAYER_TYPE_HARDWARE;
}
}
@@ -0,0 +1,38 @@
package org.reactnative.maskedview;
import android.view.View;
import android.widget.Toast;
import androidx.annotation.Nullable;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.common.MapBuilder;
import com.facebook.react.uimanager.SimpleViewManager;
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.ViewGroupManager;
import com.facebook.react.uimanager.annotations.ReactProp;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class RNCMaskedViewManager extends ViewGroupManager<RNCMaskedView> {
private static final String REACT_CLASS = "RNCMaskedView";
@Override
public String getName() {
return REACT_CLASS;
}
@Override
protected RNCMaskedView createViewInstance(ThemedReactContext themedReactContext) {
return new RNCMaskedView(themedReactContext);
}
@ReactProp(name = "androidRenderingMode")
public void setAndroidRenderingMode(RNCMaskedView view, @Nullable String renderingMode) {
if (renderingMode != null) {
view.setRenderingMode(renderingMode);
}
}
}
@@ -0,0 +1,25 @@
package org.reactnative.maskedview;
import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.JavaScriptModule;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class RNCMaskedViewPackage implements ReactPackage {
@Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactApplicationContext) {
return Collections.emptyList();
}
@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactApplicationContext) {
return Arrays.<ViewManager>asList(
new RNCMaskedViewManager()
);
}
}