简体   繁体   中英

Pause Between Making ImageView Invisible and Visible Android

I'm writing an Android app, and ran into a problem while I was coding the main part of the app.

I need to have an ImageView disappear for a second or two, and then reappear when tapped. The tapping part works, I use XML to make it clickable and then call a method on click. The problem is in the method that I call. I need it to:

  1. Disappear
  2. Add one to the playerscore
  3. Re-display the playerscore
  4. Reappear with a delay of a few seconds

My problem is that it does not noticeably disappear no matter what I do. I prefer to stay away from Thread.sleep() because I want the user to be able to tap other things while it is invisible (If I am misunderstanding Thread.sleep(), let me know. If it is possible to have every method be its own thread, please show me how. I am still pretty new at Java.) However, I did try to use Thread.sleep(), and it paused the line of code BEFORE the sleep statement, but did not visibly affect the amount of time between disappear and reappear. (that probably sounds confusing seeing the code will help explain it). I also tried to use a while statement to count up to 100 and then make it reappear when the counter had hit 100, but that did not work. I thought about using a timer, but I would need a very condensed example, as this timer would need to go into 24 different methods. Here is the code, it should help explain it a bit.

This is the first thing I tried, which I preferably do not want to use

public void tb1(View view){
    b1.setVisibility(View.INVISIBLE); //Make the ImageView Invisible
    playerscore ++;
    score.setText("SCORE: " + playerscore); //The sleep affected this line for some reason
    Thread.sleep(1000)
    b1.setVisibility(View.VISIBLE) //Make the ImageView Visible
 }

This is the second thing I tried.

public void tb1(View view) throws InterruptedException{
    int i = 0;
    b1.setVisibility(View.INVISIBLE);
    playerscore ++;
    score.setText("SCORE: " + playerscore);
    while (i < 100){
        i++;
    }
    if(i == 100){
    b1.setVisibility(View.VISIBLE);
    }
    }

For this one, it was like I had done nothing. Nothing was delayed.

I really don't know what try. Am I using something wrong, or just plain using the wrong thing? Please be patient with me, I am still new at Java and am not very experienced.

Thank you in advance for any/all help!


UPDATE I added the code from the answers but nothing has changed. It disappears, but does not reappear. Do I have any syntax or any of the values wrong?

  public void tb1(View view){ b1.setImageAlpha(0); b1.animate().alpha(1f).setDuration(0).setStartDelay(3000).start(); playerscore++; score.setText("SCORE: " + playerscore); } 

If you don't need any animation then just use this code, assuming b1 is your class variable:

b1.setVisibility(View.INVISIBLE);
b1.postDelayed(new Runnable() {
    @Override
    public void run() {
        b1.setVisibility(View.VISIBLE);
    }
}, 3000);

UPDATE

M-WaJeEh's PostDelayed() method is pretty cool - and it's not hard to adapt that code to animations either. The reason my original code didn't work was because we didn't read over the APIs carefully enough.

setAlpha(int) is depreciated in favor of setImageAlpha(int)

setAlpha(float) , however, is not.

The difference is that setAlpha(int) and setImageAlpha(int) sets the alpha on the image , not the view , and setAlpha(float) sets the alpha on the actual view . This is a important distinction because while a image is inside a view, the image itself cannot be animated.

Therefore, to get it to work - it should be:

    b1.setAlpha(0f);
    b1.animate().alpha(1f).setDuration(0).setStartDelay(1000).start();

Then I tried to write it so that a view would fade out, then fade in. Turns out that AnimationSet is pretty broken and doesn't animate AlphaAnimations when you have more than one of them (either that or I'm not understanding AnimationSet properly). It's a good thing PostDelayed() solves this problem.

Here's an example:

MainActivity.java

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button button = (Button) findViewById(R.id.button);

        button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            final ImageView imageView = (ImageView) findViewById(R.id.image);
            imageView.animate().alpha(0f).setDuration(500);
            imageView.postDelayed(new Runnable(){
                @Override
                public void run() {
                    imageView.animate().alpha(1f).setDuration(500);
                }
            }, 3000);
        }
    });
    }
}

We can also swap out the OnClickListener to something like this to switch between transparent and opaque on a click:

button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        ImageView imageView = (ImageView) findViewById(R.id.image);

        float alpha = imageView.getAlpha();

        if (alpha == 0f) {
            imageView.animate().alpha(1f).setDuration(500);
        } else if (alpha == 1f) {
            imageView.animate().alpha(0f).setDuration(500);
        }
    }
});

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"
    android:orientation="vertical"
    android:gravity="center" >

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="20dp"
        android:text="Animate" />

    <ImageView
        android:id="@+id/image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@android:drawable/bottom_bar" />

</LinearLayout>

And here's what it looks like. Too bad I can't post pictures yet.

Switch between transparent and opaque on click:

https://dl.dropboxusercontent.com/u/2588338/Stuff/Untitled-1.gif

Click once, fade out then fade in:

https://dl.dropboxusercontent.com/u/2588338/Stuff/Untitled-2.gif





Old Answer

You'll want to use Android's animation framework for this.

Also, the reason the second method does not work is that computers count numbers extremely fast , counting to 100 takes no time for a computer at all - and even if you were to have it count to a sufficiently high number (or say, have it sleep 10ms for each loop), it would merely do the same thing as your first method - block the main thread and not allow any user interaction.

What you want is instead of making the view disappear, set the alpha of the view to 0, then set the alpha of the view back to 1 with a delay.

So something like this:

b1.setAlpha(0);
b1.animate().alpha(1f).setDuration(0).setStartDelay(1000).start();

Specifically, for your example (as I'm a bit confused on your comment about config_shortAnimTime - that's just merely Android's system-defined values):

public void tb1(View view){

    //Make the ImageView invisible
    b1.setAlpha(0);

    // Make the ImageView visible after 1 second with no animation delay
    b1.animate().alpha(1f).setDuration(0).setStartDelay(1000).start();

    playerscore++;
    score.setText("SCORE: " + playerscore);
 }

If you did something like this instead though:

b1.animate().alpha(1f).setDuration(500).setStartDelay(2000).start();

Then b1 would be invisible for 2 seconds because of setStartDelay(), then take 500 milliseconds to fade in because of setDuration().

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM