Titanium not recognizing its own API for android - android

I have a window that's part of a tab group. When I try to set the right nav button, I get the following runtime error:
Uncaught TypeError: Object #Window has no method setRightNavButton
However, the method is clearly listed in the API for Titanium.UI.Window. Interestingly enough, it doesn't have a problem with the setLeftNavButton method which is executed just before. Also, it executes perfectly running on ios, but has issues when running on android. Any help would be greatly appreciated.
Here's the code to create the window in question:
var queryWindow = Titanium.UI.createWindow({
barColor : '#1ADC2FF',
layout : 'vertical',
backgroundColor : '#1389d1',
title : L('Search'),
fullscreen : true
});
var clearButton = Ti.UI.createButton({
title : L('Clear'),
style : Titanium.UI.iPhone.SystemButtonStyle.BORDERED,
right : 10,
width : 60,
font : {
fontSize : 14
},
color : '#2952CC',
height : 30
});
....<MORE UI INITIALIZATION>....
queryWindow.setLeftNavButton(findButton);
queryWindow.setRightNavButton(clearButton); //Error thrown here
queryWindow.add(queryTable);
queryWindow.add(queryView);
return queryTab;

The method setRightNavButton and setLeftNavButton is only for iOS, that's why it throw an error on Android : http://docs.appcelerator.com/platform/latest/#!/api/Titanium.UI.Window-method-setRightNavButton

Related

appcelerator titanium map error

I've been tasked with adding a map to my appcelerator project. I have tried the alloy way (since I'm using alloy in the project). That apparently doesn't work and its been suggested that I create the map in the controller. I have done that below and the call to the map is triggered by an onclick function attached to an icon on the primary window. This seems to work on iOS but causes the app to crash on Android (using a samsung note)
function openMap(){
alert(alertString);
//var map = Alloy.createController('map');
//$.map.show();
//add alert location here -- get the data from the push message that comes in
var payload = Ti.App.Properties.getString("latest_buddy_alert","empty");
if (payload != "empty"){
var messageDetails = parsePushMessage(payload);
}
opera = mapview.createAnnotation({
latitude: messageDetails['lat'], // 43.7000,
longitude: messageDetails['lng'], // 79.4000,
title: alert,
pincolor:Map.ANNOTATION_RED,
});
var winMap = Titanium.UI.createWindow({
title:'Buddy Location',
BackgroundColor:'#fff'
});
var mapview = Titanium.Map.createView({
mapType: Titanium.Map.STANDARD_TYPE,
region: {latitude:lat, longitude:lon, latitudeDelta:0.01, longitudeDelta:0.01},
animate:true,
regionFit:true,
userLocation:true
,annotations: [opera]
});
winMap.add(mapview);
winMap.open();
Titanium.Geolocation.getCurrentPosition(function(e) {
if (e.error) {
Ti.API.log('error: ' + JSON.stringify(e.error) );
return;
}
var region = {
latitude:e.coords.latitude,
longitude:e.coords.longitude,
animate:true,
latitudeDelta:0.04,
longitudeDelta:0.04
};
mapview.setLocation(region);
});
}
As mentioned above, this creates an error which crashes the app:
Location[1,1] undefined
uncaught syntaxerror: unexpected token u
source: undefined
This is totally unhelpful, since I don't use a token 'u' or variable 'u' anywhere in my code. I have used several variations on the code above, all giving the same error.
I have had some small success moving to a webview, which shows the map on apple, but not on android.
Any ideas?

How to lock orientation in some views in Titanium app

I'm doing an application for Android and IOS. In this application, I have a window, and I add/remove different views with the content.
I want that the first view will be only in portrait mode, whereas the rest of the views can be in any orientation.
How can I do it?
With titanium SDK 3.1.2 it works more or less on IOS:
My window:
var appWindow = Titanium.UI.createWindow({
top : 0,
left : 0,
height : utils.getScreenHeight(),
width : utils.getScreenWidth(),
backgroundColor : "#393a3a",
//fullscreen : true,
orientationModes : [Ti.UI.PORTRAIT, Ti.UI.UPSIDE_PORTRAIT],
});
Then, when I want to load a view:
var openWindow = function(e) {
appWindow.orientationModes = [Ti.UI.PORTRAIT, Ti.UI.UPSIDE_PORTRAIT, Ti.UI.LANDSCAPE_LEFT, Ti.UI.LANDSCAPE_RIGHT];
if (e.win == 'Home') {
Titanium.UI.orientation = Titanium.UI.PORTRAIT;
appWindow.orientationModes = [Titanium.UI.PORTRAIT];
orientacion = 0;
activeView = Home.Constructor(appWindow);
} else if (e.win == 'configuracion') {
Titanium.UI.orientation = Titanium.UI.PORTRAIT;
orientacion = 0;
appWindow.orientationModes = [Titanium.UI.PORTRAIT];
activeView = Configuracion.Constructor(appWindow);
} else if (e.win == 'Circle') {
activeView = Circle.Constructor(appWindow);
}
appWindow.add(activeView);
};
Now, I want to use SDK 3.1.3 to support IOS 7, and it doesn't work, none of the views allow to rotate.
Do you know how I can do this?
Thank you very much
I did not have any luck with changing a windows orientationModes on runtime too. The docs say that the window property orientationModes as well as its method setOrientationModes have to be set before opening the window.
So switching from views to windows is not an option?
If you want a window to allow orientations different from those defined in tiapp.xml, you have to set orientationModes on every window individually:
// This window allows orientations defined in tiapp.xml
var appWin = Ti.UI.createWindow({
backgroundColor = '#FFF'
});
appWin.open();
// This window is portrait only
var win = Ti.UI.createWindow({
backgroundColor: '#FFF',
orientationModes: [Ti.UI.PORTRAIT]
});
win.open();
// If this window is opened it allows multiple orientations
var newWindow = Ti.UI.createWindow({
backgroundColor: '#FFF',
orientationModes: [Ti.UI.PORTRAIT, Ti.UI.LANDSCAPE_LEFT, Ti.UI.LANDSCAPE_RIGHT]
});
newWindow.open()
This is tested with SDK 3.1.3.
Edit
To make this work on Android, you have to force a heavyweight window by either setting fullscreen: true or navBarHidden: true
You can create a custom AndroidManifest.xml and set screenOrientation attribute for the activities you want.-
android:screenOrientation="portrait"
More information here
With titanium SDK 3.1.2 I put the following code for:
Titanium.UI.orientation = Titanium.UI.PORTRAIT;
appWindow.orientationModes = [Titanium.UI.PORTRAIT];
and then, when you load other view, then put:
appWindow.orientationModes = [Ti.UI.PORTRAIT, Ti.UI.UPSIDE_PORTRAIT, Ti.UI.LANDSCAPE_LEFT, Ti.UI.LANDSCAPE_RIGHT];

How to save the Instance State in Android applications developed with Titanium?

I'm working with Titanium 3.1 and developing for Android 3.0 and greater.
My app has a view that when clicked asks you if you want to take a picture or select an image from gallery. When I choose to take a picture from the camera, the camera shows with no problem and I can take the picture, the problem is that after I take the picture and choose to use it, my app resume from the beginning, not returning to the previous state it was showing before choosing to take a picture.
When I checked logcat I saw this line:
I/TiRootActivity(24120): (main) [0,0] checkpoint, on root activity create, savedInstanceState: null
It seems the state of my app is not being saved, but I don't know why. I'll be honest, this is my first time working on an app that goes to the camera app, takes a picture and returns to the app. Previously I've worked with Intents in Titanium and I've been able to return to the correct state of my app after exiting the application that was opened with the Intent using the back button.
This is the code I use to open the camera:
var globalBabyPicture = Titanium.UI.createImageView({
image:imagesPath + "kinedu_0027_ic_camara.png",
width:75,
});
var photoOptionsViewFromCamera = Ti.UI.createView({
width:Ti.Platform.displayCaps.platformWidth,
height:44,
left:0,
top:1*44,
backgroundColor:"transparent"
});
var photoOptionsViewFromCameraLabel = Ti.UI.createLabel({
text:"from camera",
font:{fontSize:14, fontFamily:"Arial Rounded MT Bold"},
color:"#368cd6"
});
photoOptionsViewFromCamera.add(photoOptionsViewFromCameraLabel);
photoOptionsViewFromCamera.addEventListener("touchstart", function(e){
var animateTouchStart = Ti.UI.createAnimation({backgroundColor:"#AFD1DE", duration:150});
photoOptionsViewFromCamera.animate(animateTouchStart);
});
//********* this is the code that triggers the camera to take the picture
photoOptionsViewFromCamera.addEventListener("touchend", function(e){
var animateTouchEnd = Ti.UI.createAnimation({backgroundColor:"transparent", duration:150});
photoOptionsViewFromCamera.animate(animateTouchEnd);
animateTouchEnd.addEventListener("complete", function(e){
Ti.Media.showCamera({
success : function(event) {
var tmp = Ti.Filesystem.getFile(Ti.Filesystem.tempDirectory, ('baby_temp.png'));
tmp.write(event.media);
var blob = tmp.read();
Ti.App.fireEvent("changePicture");
},
cancel : function() {
},
error : function(error) {
var message;
if (error.code == Ti.Media.NO_CAMERA) {
message = 'Device does not have camera capabilities';
} else {
message = 'Unexpected error: ' + error.code;
}
Ti.UI.createAlertDialog({
title : 'Camera',
message : message
}).show();
},
saveToPhotoGallery : false,
allowEditing : true,
mediaTypes : [Ti.Media.MEDIA_TYPE_PHOTO]
});
});
});
Ti.App.addEventListener("changePicture", function(e){
var tmp = Ti.Filesystem.getFile(Ti.Filesystem.tempDirectory, ('baby_temp.png'));
var blob = tmp.read();
var animationChange = Ti.UI.createAnimation({opacity:0, duration:200});
babyImage.animate(animationChange);
var animationChangeCompleted = Ti.UI.createAnimation({opacity:1, duration:200});
animationChange.addEventListener("complete", function(e){
babyImage.setWidth(100);
var image = blob.imageAsThumbnail(150);
babyImage.setImage(image);
babyImage.animate(animationChangeCompleted);
});
});
I've checked and the success callback is never made, I think it's because the application resumes from the beginning, showing the application splash screen.
How can I ensure that after taking the picture, the application returns to the previous view without resuming the application from the beginning?
I think allowEditing should be allowImageEditing

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

Titanium accessing child of a view returns null

I get null on
view.children[0]
The view is a Titanium.UI.View-object and has just one child Titanium.UI.ImageView-object that need to access. How do I fix this?
I have had a look at How to query the child views of a parent view using Titanium? but it doesn't work for me. I found this, http://developer.appcelerator.com/question/31361/how-to-access-child-view-of-a-tableview-row , it could be a reason for my problem, any clue if this bug has been fixed?
Here is the more detailed code.
function (parentView, id, leftMargin) {
var cellImageView = cellImageView = Titanium.UI.createImageView({
url: imageUrl
});
var cellView = Ti.UI.createView({
id: id,
left: leftMargin,
parent: parentView
});
cellView.addEventListener('click', function (e) {
Titanium.API.info("you clicked1:" + e.source.id);
OnNumClick(e.source, e.source.parent);
});
cellView.add(cellImageView);
return cellView;
}
OnNumClick = function (cellViewObj) {
Titanium.API.info("cellViewObj:" + cellViewObj);
Titanium.API.info("cellViewObj.children:" + cellViewObj.children);
};
result:
[INFO] [7,10537] cellViewObj:ti.modules.titanium.ui.ViewProxy#437ba5a8
[INFO] [15,10628] cellViewObj.children:null
My bad, I upgraded from Titanium SDK 1.2 to 1.6 (for some reason my setup was not working with 1.6 earlier), and it finally worked. Thanks for your help Muhammad.

Categories

Resources