3

Hi stackoverflow community,

I'm using Android API 14 on a droid 4.0.3 device.

In the Activity I've set a Button to display a TextView on the page while it is performing an action. After the action is performed, I want the TextView to disappear again.

button1.setOnClickListener(new OnClickListener(){
    @Override
    public void onClick(View v) {
        // make textview visible 
        textView1.setVisibility(View.VISIBLE);      

        // perform action
        System.out.println("perform action");

        // make textview disappear
        textView1.setVisibility(View.GONE);
    }
});

If I remove the part that makes the TextView disappear, the TextView appears at the top of the window as expected, but I want the TextView to appear for 1-2 seconds and then disappear.

At first I wondered if I needed to do more work than just performing a small action, so I tried adding a wait and printing out text, but none of that worked. The wait always called the exception, ending the activity, and when I printed out numbers 1-1000 the view was still permanently gone.

Is there a better way to make a TextView appear and disappear on an OnClick action?

Thanks for your help!

Sam
  • 86,580
  • 20
  • 181
  • 179
satoukum
  • 1,188
  • 1
  • 21
  • 31

4 Answers4

5

Those commands are executed back-to-back. So in a technical sense, it may be visible but only for a millisecond or two. You need to distinguish when to make the view visible and when to hide it...


You said that you would like the TextView to "blink" in a sense, so let's use the Handler that is a part of every View to call a Runnable. This Runnable will simply hide the TextView a few moments later:

1) Set up a class variable:

Runnable hide = new Runnable() {
    @Override
    public void run() {
        textView1.setVisibility(View.GONE);
    }
};

2) Call the runnable in a few moments:

button1.setOnClickListener(new OnClickListener(){
    @Override
    public void onClick(View v) {
        // make textview visible for 1 second (1000 milliseconds)
        textView1.setVisibility(View.VISIBLE);      
        textView1.postDelayed(hide, 1000);
    }
});

(A Handler and Runnable does not block the UI thread.)

Sam
  • 86,580
  • 20
  • 181
  • 179
  • I figured the lines were probably performing too quickly. Is there a way to slow it down? When everything is set up properly, the action will take longer to perform, but for now I'm just focusing on UI and I'd like to slow it down... – satoukum Oct 26 '12 at 16:21
  • Do you want it to blink? Or what type of delay do you want? – Sam Oct 26 '12 at 16:22
  • A blink would work-- I just need to make sure the user has some way of knowing their click was heard! :) – satoukum Oct 26 '12 at 16:24
  • why not use click sound rather than a visual blink? people are better at recalling fast sounds that fast images. – Aiden Fry Oct 26 '12 at 16:26
  • Like you said, adding a wait(1000) would be ideal for demo purposes, but it blocks the UI thread and ends the activity... – satoukum Oct 26 '12 at 16:26
  • Hmm, the built-in Views all have a pressed state that changes the color by default... But you can always use a ColorSelector to define a unique "pressed" color. – Sam Oct 26 '12 at 16:28
  • @Adien Fry - I don't want to do a sound b/c I want this to be a silent app, thanks though! – satoukum Oct 26 '12 at 16:31
  • @Sam - Technically I could change the button to be "pressed" but in my app I really want the TextView to appear. I'm trying to model it after another app and so I want consistent functionality. – satoukum Oct 26 '12 at 16:32
  • @satoukum Ok, I added a Handler / Runnable example, let me know if you have any questions on it. – Sam Oct 26 '12 at 16:33
  • @satoukum No trouble, glad I could help! – Sam Oct 26 '12 at 16:38
2

here is example with handler (I have not compiled it!)

Handler handler = new Handler();

button1.setOnClickListener(new OnClickListener(){
    @Override
    public void onClick(View v) {
        // make textview visible 
        textView1.setVisibility(View.VISIBLE);      

        // perform action
        System.out.println("perform action");

        // make textview disappear
        handler.postDelayed(new Runnable() {
          @Override
          public void run() {
              textView1.setVisibility(View.GONE);
         }} , 2000);
    }
});
marcinj
  • 48,511
  • 9
  • 79
  • 100
  • I think this is the same as Sam's answer-- and it's great! I would upvote it, but I don't have enough reputation yet. Thanks though! – satoukum Oct 26 '12 at 16:45
  • I'll give it an upvote. But creating a new Handler isn't necessary, every View has a Handler already and direct access to `post()` and `postDelayed()`. – Sam Oct 26 '12 at 16:50
1

Use an animation

public class MainActivity extends Activity {
     TextView txt;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button b = (Button) findViewById(R.id.btn_animation);

        txt = (TextView) findViewById(R.id.textviewtest);

        b.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(final View v) {
                txt.clearAnimation();

                Animation fadeIn = new AlphaAnimation(0, 1);
                fadeIn.setInterpolator(new DecelerateInterpolator()); //add this
                fadeIn.setDuration(1000);

                Animation fadeOut = new AlphaAnimation(1, 0);
                fadeOut.setInterpolator(new AccelerateInterpolator()); //and this
                fadeOut.setStartOffset(1000);
                fadeOut.setDuration(1000);

                AnimationSet animation = new AnimationSet(false); //change to false
                animation.addAnimation(fadeIn);
                animation.addAnimation(fadeOut);

                animation.setAnimationListener( new AnimationListener() {

                    @Override
                    public void onAnimationEnd(Animation animation) {
                        // TODO Auto-generated method stub
                        txt.setVisibility(View.GONE);
                    }

                    @Override
                    public void onAnimationRepeat(Animation animation) {
                        // TODO Auto-generated method stub

                    }

                    @Override
                    public void onAnimationStart(Animation animation) {
                        // TODO Auto-generated method stub
                        txt.setVisibility(View.VISIBLE);
                    }

                });
                txt.setAnimation(animation);
            }
        });
    }

activity_main.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >


<Button
    android:id="@+id/btn_animation"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Animation" />


<TextView
    android:id="@+id/textviewtest"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:visibility="gone"
    android:text="HelloWorld" />

Frank
  • 790
  • 5
  • 10
  • I'm unfamiliar with animations. Would I use this instead of a textView? – satoukum Oct 26 '12 at 16:27
  • An animation can anime your controls. You can translate, rotate, resize and change the alpha of your control. It is much more smoother. Try the example that i made above. :) – Frank Oct 26 '12 at 16:54
0

You should use an handler to run the bit of code that sets the Visibility to GONE. Perhaps Running a task at a specific time using postDelayed might help.

Community
  • 1
  • 1
frenziedherring
  • 2,225
  • 2
  • 15
  • 23