javaandroidtransitionsceneviewflipper

Scene transition is lagging out ViewFlipper


I have a ViewFlipper that basically resembles somebody deleting and typing text (i.e. deleting the word that is currently there and typing something else), and on the same activity I have a floating action button that, when pressed, brings up some icons that allows the user to click to go to certain websites (GitHub link, YouTube link, Instagram link, etc.). However, when the floating action button is pressed, it uses an AutoTransition (fading in, out) to transition to the next Scene (the clickable icons). This transition is lagging out my ViewFlipper (it is making the ViewFlipper pause for a little and then "type" really quickly.

Some possible issues:

  1. The ViewFlipper text uses the Html.fromHtml() to format the text (I need part of the text to be bold and different colors. To fix this, I could use a faster way to render text. Does anybody have any suggestions for this?
  2. The transition between the Scenes could also be too slow. However, I don't know a way around this.

So far, I've tried disabling the AutoTransition, which works, but it makes the button usage really awkward and uncomfortable. I've tried searching for this problem but I couldn't find anything.

Here is my code for the ViewFlipper:

public void inflateViewFlipper(String boldedName, String finalPhrase, String... words) {
    if (words.length == 0) return;
    ViewFlipper vf = findViewById(R.id.heading_flipper);
    vf.removeAllViews();
    // Vowels, determining whether to use "a" or "an":
    Set<Character> vowels = new HashSet<>();
    vowels.add('a');
    vowels.add('e');
    vowels.add('i');
    vowels.add('o');
    vowels.add('u');
    vowels.add('A');
    vowels.add('E');
    vowels.add('I');
    vowels.add('O');
    vowels.add('U');
    for (int i = 0; i < words.length; i++) {
        String word = words[i];
        boolean an = vowels.contains(word.charAt(0));
        String first = "<b>" + boldedName + "</b>\nis a" + (an ? "n" : "") + "<br>" +
                "<font color=\"#fafafa\">︳</font><i>" + word + "</i>︳&#8202<br>" + finalPhrase;
        String second = "<b>" + boldedName + "</b>\nis a" + (an ? "n" : "") + "<br>" +
                "<font color=\"#fafafa\">︳</font><i>" + word +
                "</i><font color=\"#fafafa\">︳&#8202</font><br>" + finalPhrase;
        if (i > 0) {
            // "Typing" the adjective:
            for (int j = 0; j <= word.length(); j++) {
                String cut = word.substring(0, j);
                String newText = "<b>" + boldedName + "</b>\nis a" + (an ? "n" : "") + "<br>" +
                        "<font color=\"#fafafa\">︳</font><i>"
                        + cut + "</i>︳&#8202<br>" + finalPhrase;
                TextView tv = new TextView(this);
                tv.setGravity(Gravity.CENTER);
                tv.setText(Html.fromHtml(newText, Html.FROM_HTML_MODE_LEGACY));
                tv.setTextSize(30);
                tv.setTextColor(Color.BLACK);
                vf.addView(tv);
            }
        }
        // Wait for a few seconds, cursor flashing to represent real cursors:
        for (int j = 0; j < 3; j++) {
            for (int k = 0; k < 5; k++) {
                TextView tv = new TextView(this);
                tv.setGravity(Gravity.CENTER);
                tv.setText(Html.fromHtml(first, Html.FROM_HTML_MODE_LEGACY));
                tv.setTextSize(30);
                tv.setTextColor(Color.BLACK);
                vf.addView(tv);
            }
            for (int k = 0; k < 5; k++) {
                TextView tv = new TextView(this);
                tv.setGravity(Gravity.CENTER);
                tv.setText(Html.fromHtml(second, Html.FROM_HTML_MODE_LEGACY));
                tv.setTextSize(30);
                tv.setTextColor(Color.BLACK);
                vf.addView(tv);
            }
        }
        for (int j = 0; j < 5; j++) {
            TextView tv = new TextView(this);
            tv.setGravity(Gravity.CENTER);
            tv.setText(Html.fromHtml(first, Html.FROM_HTML_MODE_LEGACY));
            tv.setTextSize(30);
            tv.setTextColor(Color.BLACK);
            vf.addView(tv);
        }
        for (int j = word.length(); j > 0; j--) {
            String cut = word.substring(0, j);
            String newText = "<b>" + boldedName + "</b>\nis a" + (an ? "n" : "") + "<br>" +
                    "<font color=\"#fafafa\">︳</font><i>" +
                    cut + "</i>︳&#8202<br>" + finalPhrase;
            TextView tv = new TextView(this);
            tv.setGravity(Gravity.CENTER);
            tv.setText(Html.fromHtml(newText, Html.FROM_HTML_MODE_LEGACY));
            tv.setTextSize(30);
            tv.setTextColor(Color.BLACK);
            vf.addView(tv);
        }
        if (i == words.length - 1) {
            // "Deleting" the text:
            word = words[0];
            an = vowels.contains(word.charAt(0));
            for (int j = 0; j <= word.length(); j++) {
                String cut = word.substring(0, j);
                String newText = "<b>" + boldedName + "</b>\nis a" + (an ? "n" : "") + "<br>" +
                        "<font color=\"#fafafa\">︳</font><i>"
                        + cut + "</i>︳&#8202<br>" + finalPhrase;
                TextView tv = new TextView(this);
                tv.setGravity(Gravity.CENTER);
                tv.setText(Html.fromHtml(newText, Html.FROM_HTML_MODE_LEGACY));
                tv.setTextSize(30);
                tv.setTextColor(Color.BLACK);
                vf.addView(tv);
            }
        }
    }
    // Starting the ViewFlipper:
    vf.onFinishTemporaryDetach();
    vf.invalidate();
    vf.showNext();
    vf.setFlipInterval(10);
    vf.startFlipping();
}

Basically, what I'm trying to do is type a list of adjectives to represent what something is, like: Noun <-(bolded) is a(n) (insert adjective) <-(italicized)(text cursor) (Noun). For example, "My Company is an amazing messaging service".

My Scene transition is just an AutoTransition, nothing fancy:

showPopup.setOnClickListener(v -> {
    TransitionManager.go(socialMedia);
    // Switching the buttons:
    showPopup.setVisibility(View.GONE);
    closePopup.setVisibility(View.VISIBLE);
});

Thanks to anybody who can help!

EDIT - I have now tried using an answer from How to improve the performance of ViewFlipper/ViewAnimator, which was using android:measureAllChildren="false". This solves the lagging issue, but now when I use the animation, it sometimes makes the entire ViewFlipper flash on and then off again.


Solution

  • Yay! After a few days of scrounging around, I solved my problem. First, I used android:measureAllChildren="false" to solve the ViewFlipper lagging issues. After that, instead of using the Android built-in AutoTransition to transition between Scenes, I created my own FadeIn and FadeOut animations, and used FrameLayout.startAnimation(Animation); to animate. This helped me both control the animation time and stop the lag.