Android: implement stretchInset for ImageNode

This commit is contained in:
王劲鹏 2020-04-16 17:16:21 +08:00 committed by osborn
parent 25d818966d
commit b1c1650478
2 changed files with 90 additions and 5 deletions

View File

@ -18,13 +18,19 @@ package pub.doric.shader;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.Color; import android.graphics.Color;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.graphics.drawable.NinePatchDrawable;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Base64; import android.util.Base64;
import android.widget.ImageView; import android.widget.ImageView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.AppCompatImageView;
import com.bumptech.glide.Glide; import com.bumptech.glide.Glide;
import com.bumptech.glide.RequestBuilder; import com.bumptech.glide.RequestBuilder;
import com.bumptech.glide.load.DataSource; import com.bumptech.glide.load.DataSource;
@ -42,9 +48,6 @@ import com.github.pengfeizhou.jscore.JSValue;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import jp.wasabeef.glide.transformations.BlurTransformation; import jp.wasabeef.glide.transformations.BlurTransformation;
import pub.doric.DoricContext; import pub.doric.DoricContext;
import pub.doric.extension.bridge.DoricPlugin; import pub.doric.extension.bridge.DoricPlugin;
@ -65,6 +68,7 @@ public class ImageNode extends ViewNode<ImageView> {
private String errorImage; private String errorImage;
private int placeHolderColor = Color.TRANSPARENT; private int placeHolderColor = Color.TRANSPARENT;
private int errorColor = Color.TRANSPARENT; private int errorColor = Color.TRANSPARENT;
private Rect stretchInset = null;
public ImageNode(DoricContext doricContext) { public ImageNode(DoricContext doricContext) {
super(doricContext); super(doricContext);
@ -85,7 +89,7 @@ public class ImageNode extends ViewNode<ImageView> {
@Override @Override
protected ImageView build() { protected ImageView build() {
ImageView imageView = new ImageView(getContext()) { ImageView imageView = new AppCompatImageView(getContext()) {
@Override @Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec); super.onMeasure(widthMeasureSpec, heightMeasureSpec);
@ -229,7 +233,24 @@ public class ImageNode extends ViewNode<ImageView> {
@Override @Override
protected void setResource(@Nullable Drawable resource) { protected void setResource(@Nullable Drawable resource) {
super.setResource(resource); if (resource instanceof BitmapDrawable) {
Bitmap bitmap = ((BitmapDrawable) resource).getBitmap();
if (stretchInset != null) {
NinePatchDrawable ninePatchDrawable = new NinePatchDrawable(
getContext().getResources(),
bitmap,
DoricUtils.getNinePatchChunk(stretchInset),
stretchInset,
null
);
super.setResource(ninePatchDrawable);
} else {
super.setResource(resource);
}
} else {
super.setResource(resource);
}
if (mSuperNode instanceof FlexNode) { if (mSuperNode instanceof FlexNode) {
YogaNode node = ((FlexNode) mSuperNode).mView.getYogaNodeForView(mView); YogaNode node = ((FlexNode) mSuperNode).mView.getYogaNodeForView(mView);
if (node != null) { if (node != null) {
@ -309,6 +330,15 @@ public class ImageNode extends ViewNode<ImageView> {
} }
} }
break; break;
case "stretchInset":
if (prop.isObject()) {
int left = prop.asObject().getProperty("left").asNumber().toInt();
int top = prop.asObject().getProperty("top").asNumber().toInt();
int right = prop.asObject().getProperty("right").asNumber().toInt();
int bottom = prop.asObject().getProperty("bottom").asNumber().toInt();
stretchInset = new Rect(left, top, right, bottom);
}
break;
default: default:
super.blend(view, name, prop); super.blend(view, name, prop);
break; break;

View File

@ -17,6 +17,7 @@ package pub.doric.utils;
import android.content.Context; import android.content.Context;
import android.content.res.AssetManager; import android.content.res.AssetManager;
import android.graphics.Rect;
import android.util.DisplayMetrics; import android.util.DisplayMetrics;
import android.view.Display; import android.view.Display;
import android.view.WindowManager; import android.view.WindowManager;
@ -36,6 +37,8 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.lang.reflect.Array; import java.lang.reflect.Array;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import pub.doric.Doric; import pub.doric.Doric;
@ -232,4 +235,56 @@ public class DoricUtils {
} }
return sbar; return sbar;
} }
private final static int NO_COLOR = 0x00000001;
private final static int X_SIZE = 2;
private final static int Y_SIZE = 2;
private final static int COLOR_SIZE = 9;
private final static int BUFFER_SIZE = X_SIZE * 4 + Y_SIZE * 4 + COLOR_SIZE * 4 + 32;
public static byte[] getNinePatchChunk(Rect rect) {
if (rect == null) {
return null;
}
ByteBuffer byteBuffer = ByteBuffer.allocate(BUFFER_SIZE).order(ByteOrder.nativeOrder());
// first bytenot equal to zero
byteBuffer.put((byte) 1);
//mDivX length
byteBuffer.put((byte) 2);
//mDivY length
byteBuffer.put((byte) 2);
//mColors length
byteBuffer.put((byte) COLOR_SIZE);
//skip
byteBuffer.putInt(0);
byteBuffer.putInt(0);
//padding preset zero
byteBuffer.putInt(0);
byteBuffer.putInt(0);
byteBuffer.putInt(0);
byteBuffer.putInt(0);
//skip
byteBuffer.putInt(0);
// mDivX
byteBuffer.putInt(rect.left);
byteBuffer.putInt(rect.right);
// mDivY
byteBuffer.putInt(rect.top);
byteBuffer.putInt(rect.bottom);
// mColors
for (int i = 0; i < COLOR_SIZE; i++) {
byteBuffer.putInt(NO_COLOR);
}
return byteBuffer.array();
}
} }