titanium-sdk icon indicating copy to clipboard operation
titanium-sdk copied to clipboard

feat(android): optimize borderRadius

Open m1ga opened this issue 1 year ago • 5 comments

fixes https://github.com/tidev/titanium-sdk/issues/13464

Work in progress

When setting optimizeBorderRadius:true the view will use the ViewOutlineProvider to set the borderRadius. That will remove one nested view:

Before this PR: Screenshot_20220705_214015

After this PR (BorderWrapperView is gone): Screenshot_20220705_214001

It only works if:

  • optimizeBorderRadius is true
  • borderRadius is one integer value
  • no borderWidth is used

otherwise the old way is used. Especially in a ListView with many circular profile pictures it flattens the hierarchy.

I would love to use it without the property but I have one issue: toImage() won't the ViewOutlineProvider so all elements that automatically use the new way would look wrong. I've added the property so a user can activate the optimized rendering if he knows that there won't be any toImage() calls.

I'm still trying to either get toImage() to work or rerender the view with the old way when the user uses toImage().

const win = Ti.UI.createWindow();
const img = Ti.UI.createImageView({
	image:"/images/appicon.png",
	borderRadius: 50,
	height: 100,
	width: 100,
	top: 10,
	optimizeBorderRadius: true
});
win.add(img);
win.open();

toImage test:

const win = Ti.UI.createWindow({ backgroundColor:"#ddd" });
const view = Ti.UI.createView({width: 50, height: 50, borderRadius: 25, left: 10, backgroundColor:"red", optimizeBorderRadius: true});
const view_old = Ti.UI.createView({width: 50, height: 50, borderRadius: 25, left: 70, backgroundColor:"red" });
const img = Ti.UI.createImageView({ image:"./images/img.jpg", backgroundColor:"#999", borderRadius: 25, height: 50, width: 50, right: 10, optimizeBorderRadius: true});
const img_old  = Ti.UI.createImageView({ image:"./images/img.jpg", backgroundColor:"#999", borderRadius: 25, height: 50, width: 50, right: 70});
const img_check1 = Ti.UI.createImageView({ width: 50, height: 50, bottom: 10, left: 10})
const img_check2 = Ti.UI.createImageView({ width: 50, height: 50, bottom: 10, right: 10})

win.add([img,view, view_old, img_old, img_check1, img_check2]);

win.addEventListener("open", function() {
	setTimeout(function() {
		img_check1.image = view.toImage();
		img_check2.image = img.toImage();
	}, 1000)
})

win.open();

m1ga avatar Jul 05 '22 20:07 m1ga

Hi @m1ga that's great PR I was working on it recently. But now I'm working on TiView to optimize Border too but with MaterialShapeDrawable instead of ViewOutlineProvider. Will try to finish it soon to avoid using TiBorderWrapperView.

AhmedMSayed avatar Aug 05 '22 11:08 AhmedMSayed

@AhmedMSayed sounds awesome! Still have the toImage() issue but perhaps you'll find away around it. Not sure if MaterialShapeDrawable will have the same. Otherwise I'll add it as a optimizeBorder property so the user needs to opt-in to use it

m1ga avatar Aug 05 '22 12:08 m1ga

@AhmedMSayed I've tried a shapeDrawable too but still have issues with ImageViews

const win = Ti.UI.createWindow({ title: "Select Time", backgroundColor:"#ddd" });
var view = Ti.UI.createView({
	width: 100,
	height: 100,
	borderRadius: 50,
	left: 10,
	backgroundColor:"red",
	elevation: 50,
	borderWidth:10,
	borderColor: "#00f"
})
const img = Ti.UI.createImageView({
	image:"/images/bg_intro.jpg",
	borderRadius: 50,
	height: 100,
	width: 100,
	right: 10,
	elevation: 50,
	borderWidth:10,
	borderColor: "#f00"
});
win.add([img,view]);

var img_check1 = Ti.UI.createImageView({
	width: 100,
	height: 100,
	bottom: 10,
	left: 10
})
var img_check2 = Ti.UI.createImageView({
	width: 100,
	height: 100,
	bottom: 10,
	right: 10
})

win.add(img_check1);
win.add(img_check2);
setTimeout(function(){
	img_check1.image = view.toImage();
	img_check2.image = img.toImage();
}, 3000)
win.open();

normal view works fine but the imageview will lose the shape when doing toImage(). Maybe you have a solution for that

m1ga avatar Aug 14 '22 17:08 m1ga

Think I finally figured it out!

Screenshot_20230311_005339

Old views with border radius = TiBorderWrapperView + TiCompositeView/TiImageView New view with border radius = TiCompositeLayout/TiImageView

So I'm able to get rid of one nested element and still can do a toImage() It will be API >= 24 and I still have to clean up some parts.

m1ga avatar Mar 11 '23 00:03 m1ga

I've enabled it for two views in a real app:

Screenshot_20230311_011210 default is false, so you can enable it with optimizeBorderRadius:true. More in the next days.

One last image :smile: I've set it to default true so it will use it everywhere where it can. Screenshot_20230311_013126 like those numbers :wink: (not 100% sure if the state was the same)

m1ga avatar Mar 11 '23 00:03 m1ga