Accessibility Identifier issue in ReactNative - android

I am setting accessibility identifier for my components in react native using testID in iOS and accessibilityLabel in android. For iOS is working fine but for Android it my identifier is appended with , (a comma and a space). I am not sure what is causing issue. Here is my code:
const renderAccessibilityLabel = (str) => {
const propsForAutomation = {};
if (Platform.OS === "ios") {
propsForAutomation.testID = str;
} else {
propsForAutomation.accessibilityLabel = str;
}
return propsForAutomation;
};
// Inside render method:
<Text {...renderAccessibilityLabel("MyText")}>{MyText}</Text>
result > ios: MyText
android: MyText,
I don't know whats wrong with code :(

There was a bug with react native that was fixed in 0.60.5.
My guess is you are using an earlier version (0.60), updating will correct this.
Problem occurs in ReactAndroid/src/main/java/com/facebook/react/uimanager/BaseViewManager.java
Line 178 contentDescription.append(accessibilityLabel + ", ");
Just in case you can't update for any reason, it can be fixed by adding contentDescription = contentDescription.replaceAll(", $", ""); just above the line if (contentDescription.length() > 0) {
Or by replacing the file with the changes in https://github.com/facebook/react-native/commit/812abfd.

Related

Intl.NumberFormat.formatToParts is not a function

I am using the Intl namespace in React Native to do some currency and metric amounts formatting (W.h, etc)
When using the formatToParts method, everything works fine on IOS and also on Android debug mode. But in Android dev mode, I have the following error :
Intl.NumberFormat(_i18nJs.default.locale,options).formatToParts is not a function. (In 'Intl.NumberFormat(_i18n.Js.default.locale,options).formatToParts(value)','Intl.NumberFormat(_i18nJs.default.locale,options).formatToParts' is undefined)
In release mode, the screen on which I use this function makes the application crash
Code:
public static formatNumberWithCompacts(value: number, options: FormatNumberOptions = {}): FormatNumberResult {
const isCompactForm =
options.notation === NumberFormatNotationEnum.COMPACT &&
(!options.compactThreshold || (options.compactThreshold && value > options.compactThreshold));
const isCurrency = options.currency && options.style === NumberFormatStyleEnum.CURRENCY;
options.currency = options.currency || I18nManager.currency;
const isUnit = options.unit && options.style === NumberFormatStyleEnum.UNIT;
const isPercent = options.style === NumberFormatStyleEnum.PERCENT;
if (!isCompactForm) {
delete options.notation;
}
// Format the given value with the given options
const parts = Intl.NumberFormat(i18n.locale, options).formatToParts(value);
I fixed the issue by adding to my index.ts all the polyfill imports indicated here:
https://github.com/web-ridge/react-native-paper-dates/releases/tag/v0.2.15
I also had to install each of this polyfills beforehand as indicated in the doc of Format.js : https://formatjs.io/docs/polyfills

Got 'One of the sources for assign has an enumerable key on the prototype chain' on React native app

I am using react-native for Android app. And use axios as http library. When I try to send a Blob object through http post I will get below error:
HTTP Failure in Axios TypeError: One of the sources for assign has an enumerable key on the prototype chain. Are you trying to assign a prototype property? We don't allow it, as this is an edge case that we do not support. This error is a performance optimization and not spec compliant.
Below is the code I used to add blob object on form data:
let data = new FormData()
data.append('image', decodeBase64Image(image));
below is the code to decode base64 image. And below code works fine in one of my website application.
export const decodeBase64Image = (dataURI) => {
let byteString;
if (dataURI === undefined) {
return undefined
}
if (dataURI.split(',')[0].indexOf('base64') >= 0)
byteString = atob(dataURI.split(',')[1]);
else
byteString = unescape(dataURI.split(',')[1]);
// separate out the mime component
let mimeString = ''
if (dataURI.split(',')[0] != undefined && dataURI.split(',')[0].split(':')[1] != undefined) {
mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0]
}
// write the bytes of the string to a typed array
let ia = new Uint8Array(byteString.length);
for (let i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
return new Blob([ia], {type: mimeString});
}
The root of the problem is that the React Native devs made a performance optimization that is not spec-compliant (which is why the code works on your website, but not your React Native app). For more details, see the issue I opened here: https://github.com/facebook/react-native/issues/16814
As a workaround, you can use react-native-fetch-blob. I ran into the same error you did, and react-native-fetch-blob solved it for me.

Dynamic Image Loading in Android Offline HTML5 app using Sencha

Good day folks.
I am stuck with a strange problem and after lots of googling I couldn't find the solution/answer
I am creating and Sencha +cordova app for android.
It simply display 10 images in loop.
my code works fine on Chrome browser in desktop.
It fails On android 4.4.2 device when I install as APK.
Please help to fix the code for android.
init: function () {
this.callParent(arguments);
//console.log('init');
if(Ext.os.name == 'Android')
baseurl = baseAndroidUrl;
else
baseurl = baseDesktopUrl;
//alert('baseurl ' + baseurl);
}
var baseurl;
var baseAndroidUrl = 'file:///android_asset/www/resources/resources/images/';
var baseDesktopUrl = '/resources/resources/images/';
var imageArray =
['page00.jpg',
'page01.jpg',
'page02.jpg',
'page03.jpg',
'page04.jpg',
'page05.jpg',
'page06.jpg',
'page07.jpg',
'page08.jpg',
'page09.jpg',
'page10.jpg'];
var counter = 0;
-----------------------------------------------
onPrePageCommand: function () {
console.log('onPrePageCommand');
if( counter === 0 )
return ;
counter--;
// Folloing dynamic updation doesn't work in android , works perfectly on desktop
Ext.getCmp('pageID').setSrc(baseurl+imageArray[counter]);
//Ext.getCmp('pageID ').doLayout();
},
onNextPageCommand: function () {
console.log('onNextPageCommand');
if( counter === imageArray.length-1 )
return ;
counter++;
Ext.getCmp('pageID').setSrc(baseurl+imageArray[counter]);
},
------------------------------------------
//initial view : work perfect for both Desktop browser and APK
{
xtype: 'image',
src:'resources/images/Page00.jpg',
id:'pageID',
mode:'image'
height:'100%',
width:'100%'
}
--------------------------------------------
Try to use a Framework for that like http://wowslider.com/ this worked great for me the last time. You can also scroll the images with your fingers (swipe them).

Android 4.1 change - transition and webkittransition defiend, how to properly determine name of transition end event?

I have noticed that with the update from android 4.0 to 4.1, there is a change as to css transition prefix in the stock browser & webView
Basically, both "transition" and "webkitTrantion" are defiend.
Modernizr.prefixed("transition") returns webkitTrantion on android 4.0
Modernizr.prefixed("transition") returns trantion on android 4.1
However, as to transition end event name, "transitionend" event is not defined / does not work. you still need to use the webkit specific "webkitTransitionEnd" event name
QUESTION: I cannot find any documentation on this change, and thus are not certain how to proceed... can anyone shed some light on this? any suggestions or links to docs woudl be greatly appreciated!
TO REPRODUCE:
function whichTransitionEvent(){
var t;
var el = document.createElement('fakeelement');
var transitions = {
'OTransition':'oTransitionEnd',
'MSTransition':'msTransitionEnd',
'MozTransition':'transitionend',
'WebkitTransition':'webkitTransitionEnd',
'transition':'transitionEnd'
}
for(t in transitions){
if( el.style[t] !== undefined ){
alert (transitions[t]);
}
}
}
The code above, will result in just one popup showing up on android 4.0, and 2 popups for android 4.1 since on 4.1, both "transition" and "webkitTransition" as valid
I had a similar problem where Chrome on desktop and Android on Samsung devices would report another event name than what they actually used. The only way I can think of that would find what they are actually using is by triggering an event, set up several different event listeners, and see which one was triggered. The code below (from this gist) essentially does this and sets Modernizr.transitionEnd to be that eventname.
var $M = window.Modernizr
var _ = window._ // underscore.js
// Defines prefixed versions of the
// transitionEnd event handler
transitionFinishedEvents = {
'WebkitTransition' : 'webkitTransitionEnd',
'MozTransition' : 'transitionend',
'OTransition' : 'oTransitionEnd',
'msTransition' : 'msTransitionEnd',
'transition' : 'transitionEnd'
};
// Feature detect actual transitionEnd keyword by triggering an event
window.setTimeout(function () {
var div = document.createElement('div');
div.id = "my-transition-test";
div.style.position = 'absolute';
div.style.zIndex = -10;
div.style.bottom = '-1000px';
div.style.height = '100px';
div.style.width = '100px';
div.style.background = 'yellow';
div.style.display = 'hidden';
window.document.body.appendChild(div);
$('#my-transition-test').one(_.values(transitionFinishedEvents).join(" "), function (e) {
if ($M.transitionFinishedEvent !== e.type) {
window.console.warn("Changing misconfigured Modernizr.transitionFinishedEvent to " + e.type + ". (Was " + $M.transitionFinishedEvent + ")");
$M.transitionFinishedEvent = e.type;
}
window.document.body.removeChild(div);
});
window.setTimeout(function () {
div.style[$M.prefixed('transition')] = '0.1s';
div.style[$M.prefixed('transform')] = 'translate3d( 100px,0,0)';
}, 25);
}, 25);
Afterwards you can easily set up an event listener for transitionEnd that will work on all platforms (that has CSS3 transitions):
$("#fooBar").on($M.transitionEnd, function() {
// do something clever
}
The code has dependencies on underscore.js and jQuery, but can easily be turned into vanilla js.
Relevant links for people affected by this:
[Modernizr]Unprefixed version of 'transition' and 'transform' incorrectly returned for Android 4.1.1 (Samsung Note II)
[Leaflet] Freeze on Android 4.1.1 + Samsung Galaxy Note II

rotate3D of CSS3 transform is not working in Android

I've created one App using Phonegap and HTML5 (jqueryMobile). I've put rotate3D for one div,
it is working fine in google chrome and Safari, but it is not working in Android 2.3+
Any suggestion?
I think It is a bug of android browser. I make a function to test if rotate3d is supported and it says Yes:
function styleSupport( prop )
{
var vendorProp;
var supportedProp;
// capitalize first character of the prop to test vendor prefix
var capProp = prop.charAt(0).toUpperCase() + prop.slice(1);
var prefixes = [ "Moz", "Webkit", "O", "ms" ];
var div = document.createElement( "div" );
if ( prop in div.style )
{
//browser supports standard CSS property name
supportedProp = prop;
}
else
{
//otherwise test support for vendor-prefixed property names
for ( var i = 0; i < prefixes.length; i++ )
{
vendorProp = prefixes[i] + capProp;
if ( vendorProp in div.style )
{
supportedProp = vendorProp;
break;
}
}
}
// avoid memory leak in IE
div = null;
return supportedProp;
}
alert(styleSupport('perspective'));
alert(styleSupport('transform'));
As you can see her, CSS transforms3D are not supported by Android 2.3 :
http://caniuse.com/#feat=transforms3d
try to upgrade to Android 4 (it works for me)

Categories

Resources