Titanium JIRA Archive
Titanium SDK/CLI (TIMOB)

[TIMOB-25945] Android: Elevation disappear on change of view dynamically

GitHub Issuen/a
TypeBug
PriorityNone
StatusClosed
ResolutionFixed
Resolution Date2020-01-06T15:54:31.000+0000
Affected Version/sRelease 6.3.0
Fix Version/sRelease 8.3.1
ComponentsAndroid
LabelsengSchedule, regression
ReporterMostafizur Rahman
AssigneeYordan Banev
Created2018-04-06T20:44:13.000+0000
Updated2020-06-30T11:10:17.000+0000

Description

Hi, In our application, we have a requirement where the view should have a shadow effect. For iOS, we are using viewShadowRadius, viewShadowColor and viewShadowOffset properties for getting the shadow effect behavior. For Android, we are using the *elevation* property. When the view gets changed dynamically(i.e., if we add any view to existing view which has the elevation), the elevation for the existing view is disappeared. We tried to add the elevation property in 'post layout' event callback but it is not working. *Steps to reproduce:* 1. Create a sample classic app 2. Place the attached app.js code in the app.js file 3. Run the app on the android device 4. Click on "change the second view" label and observe the shadow for the second view. *Test Code:* app.js
var win = Ti.UI.createWindow({
	backgroundColor : '#EAEAEA',
	layout : 'vertical'
});
var secondWinLbl = Ti.UI.createLabel({
	top : 30,
	text : 'change the second view',
	color : 'black'
});
win.add(secondWinLbl);
function getView() {
	//Create a container view
	var container = Ti.UI.createView({
			layout : 'vertical',
			width : '95%',
			height : 50, //Ti.UI.SIZE,
			top : 10,
			borderRadius : 5,
			backgroundColor : 'white',
			viewShadowRadius : 3,
			viewShadowColor : '#8AA0AE',
			viewShadowOffset : {
				x : 0,
				y : 4
			},
			elevation : 10
		});
	container.add(Ti.UI.createLabel({
		text : "Here is some content",
		textAlign : Ti.UI.TEXT_ALIGNMENT_CENTER,
		color : "#000"
	}));
	container.add(Ti.UI.createView({
		height : 1,
		borderWidth : 1,
		top : 5,
		borderColor : 'red',
		id : 'titleline'
	}));
	container.addEventListener('postlayout', function(e) {
		Ti.API.info('in post layout');
		e.source.applyProperties({
			elevation : 10
		});
	});
	return container;
}

var scrollView = Ti.UI.createScrollView({
	top : 20,
	layout : 'vertical',
	height : Ti.UI.FILL,
	width : Ti.UI.FILL
});
scrollView.add(getView());
var v2 = getView();
scrollView.add(v2);
scrollView.add(getView());
win.add(scrollView);
win.open();
secondWinLbl.addEventListener('click', function() {
	v2.height = Ti.UI.SIZE;
	v2.add(Ti.UI.createView({
		height : 50,
		top : 5,
		width : '100%'
	}));
});
*Test Environment:* 7.0.1.GA Ti SDK and Appcelerator Command-Line Interface, version 7.0.0 7.1.0.GA Ti SDK and Appcelerator Command-Line Interface, version 7.0.2 also Thanks

Attachments

FileDateSize
demo.mp42018-04-06T20:42:19.000+00002030174

Comments

  1. Joshua Quick 2018-04-09

    This looks like a bug on Google's end where it's not redrawing the elevation's shadow when the view resizes. The view's elevation drop-shadow is always 1 frame behind. For example, if you rotate the app to landscape, notice that the drop-shadow is still using the previous portrait width. If you rotate back to portrait, the drop-shadow now uses landscape width and is drawn offscreen. It's always 1 frame behind. A work-around will have to be found.
  2. Rene Pot 2018-04-11

    I've tested the code and was able to reproduce. Removing the borderRadius property fixes the problem for me as a workaround. I've not been able to work around the issue by disabling/enabling the borderRadius temporary or wrapping the view again. Best workaround for now seems to be to add an extra view right after (with a tiny delay) with a small height (I used 1, 0.1 was too small to trigger a re-render) Altered code that doesn't show the issue
       secondWinLbl.addEventListener('click', function() {
         v2.height = Ti.UI.SIZE;
         v2.add(Ti.UI.createView({
           height : 50,
           top : 4,
           width : '100%'
         }));
         setTimeout(function(){
           v2.add(Ti.UI.createView({
             height : 1,
             top : 0,
             width : '100%'
           }));
         },10);
       });
       
  3. Joshua Quick 2018-04-11

    [~topener] is right. If I comment out the "borderRadius" property from the test code [~mrahman] gave us, then it works-around the issue. Our "borderRadius" uses Google's Java Canvas.clipPath() feature, which has been proven to be notoriously buggy on Google's end. Google typically displays UI with rounded corners via a 9-patch background image instead, like how it works with buttons. But unfortunately this is an Android only feature.
  4. Mostafizur Rahman 2018-04-12

    [~jquick], Thanks for the information. We have provided this solution to the customer and waiting for his reply.
  5. Yordan Banev 2019-09-20

    Investigating the issue, I found that changing the container to CardView works around the issue. I will keep looking for a solution for the default View class..
  6. Gary Mathews 2019-10-14

    Looks like the outline is not being invalidated when the child views are changed. We can do something like this: *TiBorderWrapperView.java*
       @Override
       public void onDescendantInvalidated(View child, View target) {
       		
       	// Also invalidate outline to recalculate drop shadow.
       	if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
       		invalidateOutline();
       	}
       	super.onDescendantInvalidated(child, target);
       }
       
  7. Yordan Banev 2019-10-15

    Thanks for checking it out! PR: https://github.com/appcelerator/titanium_mobile/pull/11280
  8. Samir Mohammed 2019-12-12

    FR Passed, waiting on Jenkins build.
  9. Christopher Williams 2019-12-16

    merged to master for 9.0.0
  10. Samir Mohammed 2020-01-06

    Closing ticket, fix verified in SDK version 9.0.0.v20200103081513. Test and other information can be found at: https://github.com/appcelerator/titanium_mobile/pull/11280
  11. Yordan Banev 2020-01-09

    PR (8_3_X): https://github.com/appcelerator/titanium_mobile/pull/11424
  12. Samir Mohammed 2020-01-09

    FR Passed for 8_3_X. Waiting on Jenkins build.
  13. Christopher Williams 2020-01-09

    merged to 8_3_X for 8.3.1
  14. Samir Mohammed 2020-01-10

    Verified fix in SDK version 8.3.1.v20200110021712
  15. Ewan Harris 2020-02-26

    Removing from fixVersion 9.0.0 as this shipped in 8.3.1.GA

JSON Source