Appcelerator ImageView, смена изображения на андроиде мигает/мерцает

У меня есть 20 изображений, которые я циклически просматриваю, чтобы показать фитнес-упражнения. При обновлении изображения (т.е. при переходе от кадра 1 к кадру 2) мигает весь imageView. Это происходит только на Android, на iOS работает нормально.

Вот видео, как это происходит: https://youtu.be/-CufuQErQ58 Это на эмуляторе, но это также происходит на всех устройствах Android, на которых я тестировал.

Я попытался изменить imageView просто на представление с фоновым изображением, и это работает без мигания, однако работает очень медленно, использует гораздо больше памяти и часто дает сбой.

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;
};

РЕДАКТИРОВАТЬ

Итак, немного покопавшись, я нашел эту статью — http://docs.appcelerator.com/platform/latest/#!/guide/Image_Best_Practices

Кажется на андроиде ограничивающим фактором является размер изображения, и уменьшение размера изображений помогло это исправить, хотя на первом цикле изображений все равно моргает.


person Mick Sool    schedule 31.01.2016    source источник
comment
глупый вопрос - почему бы просто предварительно не отредактировать эти изображения в короткий ролик и не показывать ролик вместо поворота изображений?   -  person developer82    schedule 31.01.2016
comment
Я хотел, чтобы пользователь мог выполнять его кадр за кадром, так как мы также представляем им небольшой текст для каждого шага упражнения. Я не верю, что вы можете сделать это с помощью Ti.Media.VideoPlayer.   -  person Mick Sool    schedule 01.02.2016


Ответы (1)


Добавьте представление (контейнерное представление) вокруг изображения и сделайте что-то вроде этого:

  • добавить еще одно представление с новым изображением в представление контейнера
  • после загрузки изображения удалите представление изображения на уровне 0 из представления контейнера

вы даже можете затенить новое изображение, чтобы оно выглядело еще лучше

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
}
person miga    schedule 31.01.2016
comment
Вы имеете в виду добавить 2 изображения одновременно? Таким образом, представление с изображением будет находиться под фактическим изображением? - person Mick Sool; 01.02.2016
comment
добавил еще немного псевдокода, чтобы понять идею. Это похоже на группу в фотошопе: вы добавляете еще один слой и удаляете нижний. Таким образом, у вас не появится пустой/пустой экран. - person miga; 01.02.2016