How to pull to refresh?
In Titanium appcelerator I need to show a list of content in tableview. If I pull the view it needs to update. In iPhone I complete but in Android it won't work. Please any one help to solve this problem in Android.
My Android code:-
tableView.addEventListener('scroll',function(e)
{
var offset = e.contentOffset.y;
if (offset < -65.0 && !pulling && !reloading)
{
var t = Ti.UI.create2DMatrix();
t = t.rotate(-180);
pulling = true;
arrow.animate({transform:t,duration:180});
statusLabel.text = "Release to refresh...";
}
else if((offset > -65.0 && offset < 0 ) && pulling && !reloading)
{
pulling = false;
var t = Ti.UI.create2DMatrix();
arrow.animate({transform:t,duration:180});
statusLabel.text = "Pull down to refresh...";
}
});
tableView.addEventListener('dragEnd', function(e)
{
if(pulling && !reloading)
{
reloading = true;
pulling = false;
arrow.hide();
actInd.show();
statusLabel.text = "Reloading...";
tableView.setContentInsets({top:60},{animated:true});
tableView.scrollToTop(-60,true);
arrow.transform=Ti.UI.create2DMatrix();
beginReloading();
}
});
Titanium now supports pull to refresh for BOTH Android (> v6.2.0) and iOS (>3.2.0) with a Titanium.UI.TableView, Titanium.UI.ListView or Titanium.UI.ScrollView object.
See the docs:
https://docs.appcelerator.com/platform/latest/#!/api/Titanium.UI.ListView
https://docs.appcelerator.com/platform/latest/#!/api/Titanium.UI.RefreshControl
Sample code taken from the docs:
var win = Ti.UI.createWindow({
fullscreen:true
});
var counter = 0;
function genData() {
var data = [];
for (var i=1; i<=3; i++) {
data.push({properties:{title:'ROW '+(counter+i)}})
}
counter += 3;
return data;
}
var section = Ti.UI.createListSection();
section.setItems(genData());
var control = Ti.UI.createRefreshControl({
tintColor:'red'
})
var listView = Ti.UI.createListView({
sections:[section],
refreshControl:control
});
control.addEventListener('refreshstart',function(e){
Ti.API.info('refreshstart');
setTimeout(function(){
Ti.API.debug('Timeout');
section.appendItems(genData());
control.endRefreshing();
}, 2000);
})
win.add(listView);
win.open();
Is this just the IOS code form the Kitchen Sink example?
There are a couple of attempts at getting this working on Android, though I haven't confirmed that any of them work as expected. From what I understand, the problem is that you can't get the offset the same way in Android as in IOS.
A quick Google search turned up this link, which was referenced from the official Appcelerator forums.
https://gist.github.com/903895
Related
I am building a mobile app for body measurement through photo I capture. how I can use OpenCV for the same? How to integrate OpenCV with Ionic framework? Kindly help.
Essentially you can pull in a flavor of the opencv.js framework. The way I've done it is by pulling down some reference like https://docs.opencv.org/3.4.1/opencv.js, and then hosting it somewhere (in case opencv moves it on you). Then include that script in the Ionic project. Be careful how you do that though. It is a big file, so it could take the app longer to load. Some options I've used:
Local Asset
Store the js file in the local assets, and include it in the index.js. If the Ionic app is deployed as a native app, then this asset is already in the app and fairly fast to load.
<script src="assets/js/opencv.js" async></script>
Dynamically load the file (example below)
async ionViewDidLoad() {
let loadingScreen = this.loadingCtrl.create({ content: "Loading Scripts. Please Wait..." });
//Show loading screen & load scripts
try {
await loadingScreen.present();
await this.loadScript();
}
catch (error) {
this.errorMessage = "We had some trouble loading scripts...";
}
finally {
loadingScreen && loadingScreen.dismiss();
}
}
public loadScript(): Promise<any> {
return new Promise((resolve, reject) => {
var isFound = false;
var scripts = document.getElementsByTagName("script")
for (var i = 0; i < scripts.length; ++i) {
if (scripts[i].getAttribute('src') != null &&
scripts[i].getAttribute('src').includes("opencv")) {
isFound = true;
return resolve();
}
}
if (!isFound) {
var dynamicScripts = ["https://docs.opencv.org/3.4.1/opencv.js"];
for (var i = 0; i < dynamicScripts.length; i++) {
let scriptNode = document.createElement('script');
scriptNode.src = dynamicScripts[i];
scriptNode.type = 'text/javascript';
scriptNode.async = false;
scriptNode.charset = 'utf-8';
document.getElementsByTagName('head')[0].appendChild(scriptNode);
scriptNode.onload = resolve;
}
}
});
}
I'm making an app capable of take photos and upload them to a server. The phone will save the id generated.
I made a class abstractApp that creates an App object with a couple of helpers and variables. I'm using Framework7.
var App;
document.addEventListener("deviceready", function() {
App = new abstractApp();
var i;
App.f7Ref = new Framework7({init: false});
for (i = 0; i < App.constants.views.length; i++)
{
if (i==0)
App.mainView = App.f7Ref.addView (
App.constants.views[i].selector,
App.constants.views[i].settings );
else
App.f7Ref.addView (
App.constants.views[i].selector,
App.constants.views[i].settings );
}
// Checks if there exists register of remote photos
if ( App.local.get('remotephotos', false) == null || App.local.get('remotephotos', false) == '' )
{
App.remotephotos = [];
App.local.set('remotephotos', []);
}
else
{
App.remotephotos = App.local.get('remotephotos');
}
// Checks if there exists register of local photos
if ( App.local.get('localphotos', false) == null || App.local.get('localphotos', false) == '' )
{
App.localphotos = [];
App.local.set('localphotos', []);
}
else
{
App.localphotos = App.local.get('localphotos');
}
for (i = 0; i < appControllers.length; i++)
{
appControllers[i].apply(App);
}
console.log(App);
}, false);
In appControllers I'm saving functions related to each page (so it is a bit more organized). With only index and new-photo controllers I have no problem, I can attach events to elements and navigate between views. The problem is calling the camera object.
window.appControllers.push(function()
{
var $$ = Dom7;
var Ref = this.f7Ref;
var server = new serverInterface();
var photos = this.remotephotos;
var App = this;
Ref.onPageInit('new', function (page) {
Ref.alert('entra', 'entra');
$$('.capture').on('click', function () {
Ref.alert('Click', 'Click detected');
navigator.camera.getPicture(onSuccess, onFail,
{
quality: 20,
destinationType: destinationType.FILE_URI
});
function onSuccess(imageURI) {
Ref.alert('Photo captured.', 'Bien');
}
function onFail(message) {
Ref.alert('There was a problem.', 'Ups');
}
});
});
});
So, I enter the new page and I click the button with cass capture and the alert (click detected) appears, but it doesn't show the camera to take the photo.
I'm using Phonegap Build and an android phone, do you have any idea of what's happening?
Thank you very much in advance
The problem wasn't the javascript code I quoted.
I was loading the camera plugin in the config.xml like this
<gap:plugin name="org.apache.cordova.camera" />
But it should be loaded this way:
<plugin name="cordova-plugin-camera" />
If the plugin is not loaded correctly, in Phonegap Build appears: version n/a installed. In this case, when it is correctly loaded, appears: version 2.1.0 installed.
More information about this thread can be found here: http://phonegap.com/blog/2015/11/19/config_xml_changes_part_two/
Hope it helps someone else too
Regards
I wrote this script for a navigation menu on the phone. If an item has drop downs, it prevents the link, then displays the drpdown.
$(document).ready(function() {
var bodyWidth = window.screen.availWidth;
if(bodyWidth <= 600) {
$('ul.dropdowns li > a').click(function(event) {
var parent = $(this).closest('li');
var nester = $(this).closest('li').closest('ul').closest('li');
var type = parent.attr("class");
if(parent.hasClass('dropdown') || parent.hasClass('flyout')) {
event.preventDefault();
$(parent).siblings().attr("id", "");
var isActive = (parent.attr("id") == "active" ? true : false);
(isActive ? $(parent).attr("id", "") : $(parent).attr("id", "active"));
}
});
};
});
This works fine with the iPhone, but on Android it gets screwed. I'm at a total loss, any ideas?
By, "gets screwed" I mean nothing happens on Android when you try to click a link.
I found the problem. I was using a CSS transition that for some reason Android wasn't keeping up with.
I am using bootstrap typeahead.
It depends on this jQuery code to work:
el.on('keyup', doSomething() )
On Chrome on Windows it works fine. On Chrome on Android it doesn't. The keyup event is never fired. The element to which it is bound definitely has the focus.
This appears to be a recent development.
Chrome 28.0.1500.64
Android 4.1.2 SGP321 Build/10.1.1.A.1.307
Thanks
--Justin Wyllie
I came across this same problem earlier today. How can android chrome not support these key events! I assume you've found a workaround by now, but here's a fix that I came up with for now.
function newKeyUpDown(originalFunction, eventType) {
return function() {
if ("ontouchstart" in document.documentElement) { // if it's a touch device, or test here specifically for android chrome
var $element = $(this), $input = null;
if (/input/i.test($element.prop('tagName')))
$input = $element;
else if ($('input', $element).size() > 0)
$input = $($('input', $element).get(0));
if ($input) {
var currentVal = $input.val(), checkInterval = null;
$input.focus(function(e) {
clearInterval(checkInterval);
checkInterval = setInterval(function() {
if ($input.val() != currentVal) {
var event = jQuery.Event(eventType);
currentVal = $input.val();
event.which = event.keyCode = (currentVal && currentVal.length > 0) ? currentVal.charCodeAt(currentVal.length - 1) : '';
$input.trigger(event);
}
}, 30);
});
$input.blur(function() {
clearInterval(checkInterval);
});
}
}
return originalFunction.apply(this, arguments);
}
}
$.fn.keyup = newKeyUpDown($.fn.keyup, 'keyup');
$.fn.keydown = newKeyUpDown($.fn.keydown, 'keydown');
Sorry to say this but keyup/keydown events do not work for chrome browser in android.
There are other people who have reported this issue(Here and Here) from last 1 year and its not fixed yet. so it's better for developers to avoid using these events till it gets fixed.
var style1 = document.createElement("link");
style1.id = "rel";
style1.rel = "stylesheet";
style1.href = "http://www.mysite.com/css.css";
style1.onload = function(){document.body.innerHTML+="fffffff";};
document.getElementsByTagName("head")[0].appendChild(style1);
This code works in Chrome/Firefox, and yet stock browsers on my Froyo (2.3) and Jellybean (4.1) Android devices will print nothing. What's the problem? I'd like if I could execute some js onload of a link. Anything else would in my case amount to a hack. :/
The problem isn't innerHTML. Try it with alerts if you want (at your own peril).
Another answer mentions checking for this functionality by doing
var huh = 'onload' in document.createElement('link');
..but this is true in both stock browsers! wtf guys?
Android browser doesn't support "onload" / "onreadystatechange" events for element: http://pieisgood.org/test/script-link-events/
But it returns:
"onload" in link === true
So, my solution is to detect Android browser from userAgent and then wait for some special css rule in your stylesheet (e.g., reset for "body" margins).
If it's not Android browser and it supports "onload" event- we will use it:
var userAgent = navigator.userAgent,
iChromeBrowser = /CriOS|Chrome/.test(userAgent),
isAndroidBrowser = /Mozilla\/5.0/.test(userAgent) && /Android/.test(userAgent) && /AppleWebKit/.test(userAgent) && !iChromeBrowser;
addCssLink('PATH/NAME.css', function(){
console.log('css is loaded');
});
function addCssLink(href, onload) {
var css = document.createElement("link");
css.setAttribute("rel", "stylesheet");
css.setAttribute("type", "text/css");
css.setAttribute("href", href);
document.head.appendChild(css);
if (onload) {
if (isAndroidBrowser || !("onload" in css)) {
waitForCss({
success: onload
});
} else {
css.onload = onload;
}
}
}
// We will check for css reset for "body" element- if success-> than css is loaded
function waitForCss(params) {
var maxWaitTime = 1000,
stepTime = 50,
alreadyWaitedTime = 0;
function nextStep() {
var startTime = +new Date(),
endTime;
setTimeout(function () {
endTime = +new Date();
alreadyWaitedTime += (endTime - startTime);
if (alreadyWaitedTime >= maxWaitTime) {
params.fail && params.fail();
} else {
// check for style- if no- revoke timer
if (window.getComputedStyle(document.body).marginTop === '0px') {
params.success();
} else {
nextStep();
}
}
}, stepTime);
}
nextStep();
}
Demo: http://codepen.io/malyw/pen/AuCtH