I have 20 images which I cycle through to show a fitness exercise. When updating the image (i.e going from frame 1 to frame 2) the entire imageView blinks. This only happens on Android, on iOS it works fine.
Here is a video of it happening https://youtu.be/-CufuQErQ58
This is on emulator but its also happening on all android devices i've tested on.
I tried changing the imageView to just a view with a backgroundImage, and this works without blinking however it runs very slowly and uses a lot more memory and often crashes.
exports.imagesWindow = function(exercise, noOfImages) {
var win = new SS.ui.win('landscape');
var imgCount = 0;
var header = new SS.ui.view(win, '10%', '100%'); header.top = 0; header.visible = true; header.backgroundColor = SS.ui.colors[0];
var cueText = new SS.ui.normalLabel(header, "some text", 7); cueText.color = 'white';
//var imgLeft = new SS.ui.responsiveImage({container:win, top:'10%', left:'2%', height: '75%', width: '30%', zoom: 0.3});
//var imgCenter = new SS.ui.responsiveImage({container:win, top: '10%', left: '35%', height: '75%', width: '30%', zoom: 0.3});
//var imgRight = new SS.ui.responsiveImage({container:win, top:'10%', left: '68%', height:'75%', width:'30%', zoom: 0.3});
if (noOfImages === 3) {
imgLeft = new ImagePanel(win, '17%');
imgCenter = new ImagePanel(win, '50%');
imgRight = new ImagePanel(win, '83%');
}
else {
imgLeft = new ImagePanel(win, '30%');
imgRight = new ImagePanel(win, '70%');
}
function updateImages() {
cueText.text = (eval(exercise + "Cues"))[imgCount];
instructionNumber.text = (imgCount+1) + "/20";
if (noOfImages === 3) {
imgLeft.image = '/images/instructionImages/' + exercise + "/" + exercise + '_front_' + imgCount + '.jpg';
imgCenter.image = '/images/instructionImages/' + exercise + "/" + exercise + '_side_' + imgCount + '.jpg';
imgRight.image = '/images/instructionImages/' + exercise + "/" + exercise + '_back_' + imgCount + '.jpg';
//SS.log("image updated: " + imgLeft.image + " " + imgCenter.image + " " + imgRight.image);
}
else {
imgLeft.image = '/images/instructionImages/' + exercise + "/" + exercise + '_front_' + imgCount + '.jpg';
imgRight.image = '/images/instructionImages/' + exercise + "/" + exercise + '_side_' + imgCount + '.jpg';
}
}
//view.add(win);
var homeView = new SS.ui.view(win, '12%', '30%'); homeView.center = {x: '5%', y: '92%'}; homeView.visible = true;
var home = new SS.ui.dateButton(homeView, 'footer/home');
home.addEventListener('click', function(){ if (start){ clearInterval(start); }; win.close(); });
var footerView = new SS.ui.view(win, '12%', '30%'); footerView.center = {x: '50%', y: '92%'}; footerView.visible = true;
var prevImg = new SS.ui.dateButton(footerView, 'footer/prevFrame'); prevImg.left = 0;
//prevImg.height = Ti.UI.SIZE;prevImg.width = Ti.UI.SIZE;
prevImg.addEventListener('click', goToPrev);
var nextImg = new SS.ui.dateButton(footerView, 'footer/nextFrame'); //nextImg.height = Ti.UI.SIZE; nextImg.width = Ti.UI.SIZE;
nextImg.addEventListener('click', goToNext); nextImg.right = 0;
var stopPlayBtn = new SS.ui.dateButton(footerView, 'footer/playVideo'); //stopPlayBtn.height = Ti.UI.SIZE;stopPlayBtn.width = Ti.UI.SIZE;
stopPlayBtn.addEventListener('click', stopPlay);
var numberView = new SS.ui.view(win, '12%', '30%'); numberView.center = {x: '95%', y: '92%'}; numberView.visible = true;
var instructionNumber = new SS.ui.normalLabel(numberView, (imgCount+1) + "/20", 5);
updateImages();
var start;
function stopPlay() {
// start videos
if (stopPlayBtn.image.indexOf('play')>=0) { cueText.visible = false; start = setInterval(goToNext, 200); stopPlayBtn.image = '/images/footer/stopVideo.png';}
// stop vidoes
else { clearInterval(start); cueText.visible = true; stopPlayBtn.image = '/images/footer/playVideo.png'; }
}
function goToPrev() {
if (imgCount > 0) { imgCount--; }
else { imgCount = 19; };
SS.log("imgCount: " + imgCount);
updateImages();
}
function goToNext() {
if (imgCount < 19) { imgCount++; }
else { imgCount = 0; };
SS.log("imgCount: " + imgCount);
updateImages();
}
return win;
};
var ImagePanel = function(viewToAdd, cX) {
var imageView = Ti.UI.createImageView({
width: '30%',
borderColor: 'white',
center: {x: cX, y: '50%'}
});
viewToAdd.add(imageView);
//resize for tablets
if(Ti.Platform.osname.indexOf('ipad') >=0) {
imageView.height = '45%';
imageView.borderWidth = 8;
imageView.borderRadius = 12;
}
else {
imageView.height = '65%';
imageView.borderWidth = 4;
imageView.borderRadius = 6;
}
return imageView;
};
EDIT
So after a bit more digging I found this article - http://docs.appcelerator.com/platform/latest/#!/guide/Image_Best_Practices
It seems on android that the image size is the limiting factor, and reducing the size of the images helped fix this, although it still blinks on the first cycle of images.
Add a view (container-view) around the imageview and do something like this:
add another view with the new image to the container-view
once the image is loaded remove the imageview at level 0 from the container-view
you can even fade the new image in so it looks even nicer
XML
<View id="container"></View>
JS
// first image
var img = Ti.UI.createImageView();
$.container.add(img);
function changeImage(){
// changing images and remove the old one
var img = Ti.UI.createImageView();
$.container.add(img);
$.container.remove($.container.getChildren()[0]); // or fade out
}
Related
My google chart is not aligned in the center of my android emulator screen. When activity loads up, I get this:
How can I put the chart in the center of the screen? I tried some css, and xml solutions found on stack but they brought no result.
Here is the code I used:
<html>
<head>
<!--Load the AJAX API-->
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load('visualization', '1.0', {'packages':['corechart']});
google.setOnLoadCallback(drawChart);
function drawChart() {
// Create the data table.
var data = new google.visualization.DataTable();
data.addColumn('string', 'ITEM');
data.addColumn('number', 'VALUE');
data.addRows([
[Android.getName(0), Android.getPoint(0)],
[Android.getName(1), Android.getPoint(1)],
[Android.getName(2), Android.getPoint(2)],
[Android.getName(3), Android.getPoint(3)],
[Android.getName(4), Android.getPoint(4)]
]);
// Set chart options
var options = {'title':'You Have a GREAT Music Taste',
pieHole: 0.4,
width: '100%',
height: '750'
};
// Instantiate and draw our chart, passing in some options.
var chart = new
google.visualization.PieChart(document.getElementById('chart_div'));
chart.draw(data, options);
google.visualization.events.addListener(chart, 'select', selectHandler);
function selectHandler() {
var selection = chart.getSelection();
var message = '';
for (var i = 0; i < selection.length; i++) {
var item = selection[i];
if (item.row != null && item.column != null) {
var str = data.getFormattedValue(item.row, item.column);
message += '{row:' + item.row + ',column:' + item.column + '} = '
+ str + '\n';
} else if (item.row != null) {
var str = data.getFormattedValue(item.row, 0);
message += '{row:' + item.row + ', column:none}; value (col 0) = '
+ str + '\n';
} else if (item.column != null) {
var str = data.getFormattedValue(0, item.column);
message += '{row:none, column:' + item.column + '}; value (row 0)
= ' + str + '\n';
}
}
if (message == '') {
message = 'nothing';
}
Android.sendData('You selected ' + message);
}
}
</script>
</head>
<body>
<!--Div that will hold the pie chart-->
<div id="chart_div" style="width:500; height:500"></div>
</body>
</html>
I am trying to achieve this horizontal swipers inside listview(vertical scroll) in Jquery Mobile, below i attached an example of what i meant but that is in Android. I am wondering how would i achieve this in Jquery Mobile. It is the functionality in Airbnb app - a listview that you can scroll vertically, but at the same time each list has multiple images that you can scroll horizontally.
swiping items on listview, with small vertical margin
I had an attempt to achieve it by loading the list in an ajax, and then nest the images inside another for loop and putting that into swipers. But the problem is the swiper isnt showing up, and also the layout is all messed up.
<script>
$( "#form" ).submit('pageinit',function( event ) {
$("#newContent2").empty();
var values = $(this).serialize();
console.log(values);
$.ajax({
type: "POST",
url: "http://test.com/search.php",
data: values,
dataType:'json',
success: function(data){
console.log(data);
var $el = $('#list');
var listView = new infinity.ListView($el);
for (var i=0; i<50; i++) {
var listing = data[i].listing;
var Location = data[i].Location;
var date = data[i].date;
var images = data[i].pics.split(',');
console.log(image);
for(var j = 0; j<images.length; j++){
var image3= "http://test.com/"+images;
console.log(image3);
var image2=" <div class='swiper-slide'><img class='lazy' src='"+ image3 + "' width='100%' id='viewer'/></div>"
}
var myOtherUrl = "list.html?Listingid=" + encodeURIComponent(listingid)+"?Location="+ encodeURIComponent(Location)+ encodeURIComponent(nobed+"?date="+ encodeURIComponent(date));
$.mobile.pageContainer.pagecontainer( "change", "#pageX", { foo: data[i].listingid, location:data[i].Location } );
var $newContent = "<li id='indi'><a href='" + myOtherUrl + "'>'"+ image2+ "'</a></li>"
+"<div id=two class=col-md-1 style=height:38%> <h9 class=name data-address href='"+ myOtherUrl + "'><a id="+"my-button"+">BucketListly</a>"+ "<h9 > "+data[i].Location+ "</h9>";
$("#newContent2").append($newContent);
var listItems = listView.find('.my-items');
for(var index = 0, length = listItems.length; index < length; index++) {
listItems[index].remove();
}
var swiper = new Swiper('.swiper-container', {
loop:false,
autoResize: true,
calculateHeight:true,
onSlideChangeStart: function(){
$('.swiper-pagination-switch').removeClass('active')
$('.swiper-pagination-switch').eq(swiper.activeSlide).addClass('active')
}
});
//navigation
$('.swiper-pagination-switch').click(function(){
swiper.swipeTo($(this).index());
$('.swiper-pagination-switch').removeClass('active');
$(this).addClass('active')
})
}
}
});
return false;
});
</script>
I am working on android application in phonegap-3.1.0
I want to use phone contacts in my application, So I have refer this Document.
Successfully installed the plugins for contacts
When I remove saved contact(save from javascript code), It alerts Removal Success
But when I go into the contacts, it is still not removed from here,
Every time I try, it saves the contact but not not removed since alerts like Removal Success,
What should I Do...
SO I need help on it, Why the contact can't be remove
I have created an app for contacts insert and delete
You can fork on github-> xxbinxx/phoneGap-ContactsApp-Android. you can definitely solve your issue after it.
I have used contact ID's for the deletion purpose.
Here's the short code...
var app ={
/********************SOME OTHER CODE*************************/
openContacts: function() {
app.initialize();
var options = new ContactFindOptions();
options.filter = "";
options.multiple = true;
var fields = ["*"]; //"*" will return all contact fields
navigator.contacts.find(fields, app.onSuccess, app.onError, options);
},
// Write contacts in DOM
onSuccess: function(contacts) {
var li = '';
$.each(contacts, function(key, value) {
if (value.name) {
$.each(value.name, function(key, value) {
if (key === 'formatted') {
name = value;
}
});
}
if (value.note) {
note = value.note;
}
if (value.id) {
id = value.id;
}
console.log("id : " + id + "-> name : " + name + " -> note : " + note);
li += '<li style="text-decoration:none;"><b>Name</b>: ' + name + '<div class="removeIcon pullRight" onclick="app.removeThisContact(\'' + id + '\',\'' + name + '\')"> </div><br><b> Note:</b> ' + note + '</li>';
}); // NOTICE the ID is passed as PARAMETER to remove specific contact.
$("#contact").html(li);
},
onError: function(contactError) {
alert('onError!' + contactError.code);
},
removeThisContact: function(id, name) {
console.log("removing contact : " + name);
options = new ContactFindOptions(); // find the contact to delete
options.filter.id = id;
options.multiple = "true";
var fields = ["displayName", "name"]; // you can take any..
navigator.contacts.find(fields, deleteThis, app.onError, options);
function deleteThis(contacts) {
var contact = contacts.pop();
// logging things to troubleshoot.
console.log('inside deleteThisContact: parameter passed: '+ contacts);
console.log("popped out:" +contact);
contact.remove(function() {
$('#status-area')
.flash_message({
text: 'Contact Removed!',
how: 'append'
});
app.openContacts();
}, null);
},
deleteAllTheContacts: function() {
var deleteContact = function(contacts) {
console.log("length = " + contacts.length);
// No contacts left, stop saving
if (contacts.length == 0) {
console.log("All contacts removed");
return;
}
var contact = contacts.pop();
contact.remove(function() {
deleteContact(contacts);
}, null);
};
navigator.contacts.find(["*"], deleteContact, app.onError, {
"multiple": true
});
},
/********************SOME OTHER CODE*************************/
}
$.fn.flash_message = function(options) {
//flash your message
}
Hope this will help you. :)
I was trying to create a li dynamically with JSON response and have included data-icon "check" in that. But in result its always displaying "arrow-r" data-icon.
Generation of li :-
function CallvarURL(url) {
var respPrice ;
$.ajax({
url: url,
type : "GET",
dataType : "json",
contentType: "application/json",
async : false,
success : function(msg) {
respPrice = msg;
$("#varList li").remove();
$.each(respPrice.Value, function(index, value) {
if(value.SubVar_id == 'NoDataFound' ) {
alert('No product is assigned to '+ localStorage.getItem('userId') + ' for update the price please contact your admin.');
} else {
vari = value.SrNo;
commVari = value.subVar_eng_name;
minPrice = value.Frm_price;
maxPrice = value.to_price;
var update = value.TimeCheck;
if (update == 'Y') {
$respPrice = '<li data-categoryId = "'+ vari +'" data-categoryId2 = "'+ minPrice +'" data-categoryId3 = "'+ maxPrice +'" data-categoryId4 = "'+ commVari +'"><b class="stuff">' + commVari + '</b><br><b class="tcolour">' + minPrice + ' - ' + maxPrice + '</b></li>';
} else {
$respPrice = '<li data-categoryId = "'+ vari +'" data-categoryId2 = "'+ minPrice +'" data-categoryId3 = "'+ maxPrice +'" data-categoryId4 = "'+ commVari +'"><b class="stuff">' + commVari + '</b><br><b class="tcolour">' + minPrice + ' - ' + maxPrice + '</b></li>';
}
$('#varList').append($respPrice);
};
});
Can't find the reason of that ? I have tried other values for data-icon also but its always displaying "arrow-r". Any help..??
Hi as I understood you are using jquery mobile. So here I am giving you link for jsfiddle in which I have created list with checkbox. You are getting right arrow in your code because you are giving it in tag. Jquerymobile by default gives right arrow in tag.
Just visit this jsfiddle (jsfiddle.net/4FdcY/366/) Hope it will help you.
I'm following javacv Face Detection/Recognition code, there is confusion regarding face recognition.. What I'm doing is (Sorry if it sounds stupid but I'm stuck)
1) Detect Face crop it and save it to sdcard and place path in learn.txt file (Learning part)
2) Detect Face crop it and find it in existing faces whether it exists or not, but it always return nearest position even if the face doesn't exist in sample faces..
what I'm doing wrong?
// Method, I'm using to recognize face
public Integer recognizeFace(Bitmap face, Context context) {
Log.i(TAG, "===========================================");
Log.i(TAG, "recognizeFace (single face)");
float[] projectedTestFace;
float confidence = 0.0f;
int nearest = -1; // closest match -- -1 for nothing.
int iNearest;
if (trainPersonNumMat == null) {
return null;
}
Log.i(TAG, "NUMBER OF EIGENS: " + nEigens);
// project the test images onto the PCA subspace
projectedTestFace = new float[nEigens];
// Start timing recognition
long startTime = System.nanoTime();
testFaceImg = bmpToIpl(face);
// saveBmp(face, "blah");
// convert Bitmap it IplImage
//testFaceImg = IplImage.create(face.getWidth(), face.getHeight(),
// IPL_DEPTH_8U, 4);
//face.copyPixelsToBuffer(testFaceImg.getByteBuffer());
// project the test image onto the PCA subspace
cvEigenDecomposite(testFaceImg, // obj
nEigens, // nEigObjs
new PointerPointer(eigenVectArr), // eigInput (Pointer)
0, // ioFlags
null, // userData
pAvgTrainImg, // avg
projectedTestFace); // coeffs
// LOGGER.info("projectedTestFace\n" +
// floatArrayToString(projectedTestFace));
Log.i(TAG, "projectedTestFace\n" + floatArrayToString(projectedTestFace));
final FloatPointer pConfidence = new FloatPointer(confidence);
iNearest = findNearestNeighbor(projectedTestFace, new FloatPointer(pConfidence));
confidence = pConfidence.get();
// truth = personNumTruthMat.data_i().get(i);
nearest = trainPersonNumMat.data_i().get(iNearest); // result
// get endtime and calculate time recognition process takes
long endTime = System.nanoTime();
long duration = endTime - startTime;
double seconds = (double) duration / 1000000000.0;
Log.i(TAG, "recognition took: " + String.valueOf(seconds));
Log.i(TAG, "nearest = " + nearest + ". Confidence = " + confidence);
Toast.makeText(context, "Nearest: "+nearest+" Confidence: "+confidence, Toast.LENGTH_LONG).show();
//Save the IplImage so we can see what it looks like
Random generator = new Random();
int n = 10000;
n = generator.nextInt(n);
String fname = "/sdcard/saved_images/" + nearest + " " + String.valueOf(seconds) + " " + String.valueOf(confidence) + " " + n + ".jpg";
Log.i(TAG, "Saving image as: " + fname);
cvSaveImage(fname, testFaceImg);
return nearest;
} // end of recognizeFace
EDIT The confidence is always negative!
Thanks in advance