java - SetBackgroundResource() 延迟?

标签 java android xml android-layout

我正在 Android 中为一个 uni 项目实现 Simon Says,作为 Audiogames 套件应用程序的一部分。我正在尝试生成一个随机播放的 5 个按钮序列(作为开始测试),除了一件事之外一切都很顺利:按钮在它们应该亮起时(当它们在序列中的种子生成时)没有亮起但是相反,它们会在一代结束时一起点亮。

遵循我的 Java 和 XML 的完整代码(它有点困惑和不完整,所以我会指出对我来说令人不安的部分)

Java 源代码

package it.unimi.di.lim.audiogames;

import android.content.Intent;
import android.graphics.drawable.ColorDrawable;
import android.media.MediaPlayer;
import android.os.Build;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.TextView;

import java.util.LinkedList;
import java.util.Random;

public class Game2PlayActivity extends AppCompatActivity {

    private int mScore = 0;
    private LinkedList<Integer> temp = new LinkedList<>();

    private MediaPlayer mCMediaPlayer;
    private MediaPlayer mDMediaPlayer;
    private MediaPlayer mEMediaPlayer;
    private MediaPlayer mFMediaPlayer;

    private MediaPlayer.OnCompletionListener mCompletionListener = new MediaPlayer.OnCompletionListener() {
        @Override
        public void onCompletion(MediaPlayer mp) {
            releaseMediaPlayer(mp);
            turnOffButton(mp);
        }
    };

    private void releaseMediaPlayer(MediaPlayer mediaPlayer) {
        if (mediaPlayer != null) {
            mediaPlayer.release();
        }
    }

    private void turnOffButton(MediaPlayer mp) {
        Button mc_button = (Button) findViewById(R.id.c_button);
        Button md_button = (Button) findViewById(R.id.d_button);
        Button me_button = (Button) findViewById(R.id.e_button);
        Button mf_button = (Button) findViewById(R.id.f_button);
        if(mp == mCMediaPlayer) {
            mc_button.setBackgroundColor(getResources().getColor(R.color.game2_c_off));
        } else if (mp == mDMediaPlayer) {
            md_button.setBackgroundColor(getResources().getColor(R.color.game2_d_off));
        } else if (mp == mEMediaPlayer) {
            me_button.setBackgroundColor(getResources().getColor(R.color.game2_e_off));
        } else {
            mf_button.setBackgroundColor(getResources().getColor(R.color.game2_f_off));
        }
    }

    private void playButton(int i) {
        char j;
        if(i==0)
            j='0';
        else if(i==1)
            j='1';
        else if(i==2)
            j='2';
        else
            j='3';
        Button mc_button = (Button) findViewById(R.id.c_button);
        Button md_button = (Button) findViewById(R.id.d_button);
        Button me_button = (Button) findViewById(R.id.e_button);
        Button mf_button = (Button) findViewById(R.id.f_button);
        switch(j) {
            case '0':
                mc_button.setBackgroundResource(R.color.game2_c_on);
                //mCMediaPlayer = MediaPlayer.create(Game2PlayActivity.this, R.raw.c_sound);
                //mCMediaPlayer.start();
                //mCMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                 //   @Override
                 //   public void onCompletion(MediaPlayer mp) {
                 //       mCMediaPlayer.release();
                 //   }
                //});
                break;
            case '1':
                md_button.setBackgroundResource(R.color.game2_d_on);
                //mDMediaPlayer = MediaPlayer.create(Game2PlayActivity.this, R.raw.d_sound);
                //mDMediaPlayer.start();
                //mDMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                //    @Override
                //    public void onCompletion(MediaPlayer mp) {
                //        mDMediaPlayer.release();
                //    }
                //});
                break;
            case '2':
                me_button.setBackgroundResource(R.color.game2_e_on);
                //mEMediaPlayer = MediaPlayer.create(Game2PlayActivity.this, R.raw.e_sound);
                //mEMediaPlayer.start();
                //mEMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                //    @Override
                //    public void onCompletion(MediaPlayer mp) {
                //        mEMediaPlayer.release();
                //    }
                //});
                break;
            case '3':
                mf_button.setBackgroundResource(R.color.game2_f_on);
                //mFMediaPlayer = MediaPlayer.create(Game2PlayActivity.this, R.raw.f_sound);
                //mFMediaPlayer.start();
                //mFMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                //    @Override
                //    public void onCompletion(MediaPlayer mp) {
                //        mFMediaPlayer.release();
                //    }
                //});
                break;
        }
    }

    private void createSequence(int i) {
        Random rand = new Random();
        for(int j = 0; j < i; j++) {
            int seed = rand.nextInt(4);
            temp.add(seed);
            playButton(seed);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    protected void onStop() {
        super.onStop();
        releaseMediaPlayer(mCMediaPlayer);
        releaseMediaPlayer(mDMediaPlayer);
        releaseMediaPlayer(mEMediaPlayer);
        releaseMediaPlayer(mFMediaPlayer);
    }

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

        Button mc_button = (Button) findViewById(R.id.c_button);
        Button md_button = (Button) findViewById(R.id.d_button);
        Button me_button = (Button) findViewById(R.id.e_button);
        Button mf_button = (Button) findViewById(R.id.f_button);

        if (Build.VERSION.SDK_INT >= 21) {
            Window window = this.getWindow();
            window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
            window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            window.setStatusBarColor(this.getResources().getColor(R.color.game2Dark));
            window.setNavigationBarColor(this.getResources().getColor(R.color.game2Primary));
        }

        android.support.v7.app.ActionBar bar = getSupportActionBar();
        bar.setBackgroundDrawable(new ColorDrawable(getResources().getColor(R.color.game2Primary)));

        mc_button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                playButton(0);
                int check = temp.poll();
                if(check!=0) {
                    Intent gameOver = new Intent(Game2PlayActivity.this, Game2Activity.class);
                    gameOver.putExtra("score", mScore);
                    startActivity(gameOver);
                }
                if(temp.size() == 0) {
                    mScore++;
                    TextView score = (TextView) findViewById(R.id.game2_score);
                    score.setText(Integer.toString(mScore));
                }
            }
        });

        md_button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                playButton(1);
                int check = temp.poll();
                if(check!=1) {
                    Intent gameOver = new Intent(Game2PlayActivity.this, Game2Activity.class);
                    gameOver.putExtra("score", mScore);
                    startActivity(gameOver);
                }
                if(temp.size() == 0) {
                    mScore++;
                    TextView score = (TextView) findViewById(R.id.game2_score);
                    score.setText(Integer.toString(mScore));
                }
            }
        });

        me_button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                playButton(2);
                int check = temp.poll();
                if(check!=2) {
                    Intent gameOver = new Intent(Game2PlayActivity.this, Game2Activity.class);
                    gameOver.putExtra("score", mScore);
                    startActivity(gameOver);
                }
                if(temp.size() == 0) {
                    mScore++;
                    TextView score = (TextView) findViewById(R.id.game2_score);
                    score.setText(Integer.toString(mScore));
                }
            }
        });

        mf_button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                playButton(3);
                int check = temp.poll();
                if(check!=3) {
                    Intent gameOver = new Intent(Game2PlayActivity.this, Game2Activity.class);
                    gameOver.putExtra("score", mScore);
                    startActivity(gameOver);
                }
                if(temp.size() == 0) {
                    mScore++;
                    TextView score = (TextView) findViewById(R.id.game2_score);
                    score.setText(Integer.toString(mScore));
                }
            }
        });


        Button start_button = (Button) findViewById(R.id.game2_start_button);
        start_button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                createSequence(5);
            }
        });
    }
}

XML 源代码

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_height="match_parent"
    android:layout_width="match_parent"
    android:orientation="vertical"
    tools:context=".Game1PlayActivity">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:text="@string/game2_score"
        android:textSize="16sp"
        android:padding="16dp"
        android:gravity="bottom"
        android:textAlignment="center" />

    <TextView
        android:id="@+id/game2_score"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1.2"
        android:text="0"
        android:textSize="48sp"
        android:padding="16dp"
        android:gravity="top"
        android:textAlignment="center" />

    <TextView
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="0.8"
        android:text="@string/game2_criteria"
        android:textSize="16sp"
        android:padding="16dp"
        android:gravity="bottom"
        android:textAlignment="center" />

    <Button
        android:id="@+id/game2_start_button"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:text="@string/game2_start"
        android:layout_marginTop="8dp"
        android:layout_marginLeft="64dp"
        android:layout_marginRight="64dp" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="2">

        <Button
            android:id="@+id/c_button"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="@color/game2_c_off"
            android:layout_margin="16dp"
            android:text="@string/game2_c" />

        <Button
            android:id="@+id/d_button"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="@color/game2_d_off"
            android:layout_margin="16dp"
            android:text="@string/game2_d" />

    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="2">

        <Button
            android:id="@+id/e_button"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="@color/game2_e_off"
            android:layout_margin="16dp"
            android:text="@string/game2_e" />

        <Button
            android:id="@+id/f_button"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="@color/game2_f_off"
            android:layout_margin="16dp"
            android:text="@string/game2_f" />

    </LinearLayout>

</LinearLayout>

-------------------------------------------- ----------------------------------

基本上我要做的是通过单击“开始”按钮生成序列,这里是 onClickListener(5 仅用于测试目的)

Button start_button = (Button) findViewById(R.id.game2_start_button);
    start_button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            createSequence(5);
        }
    });

这会触发 createSequence() 方法,如下所示

private void createSequence(int i) {
    Random rand = new Random();
    for(int j = 0; j < i; j++) {
        int seed = rand.nextInt(4);
        temp.add(seed);
        playButton(seed);
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

到目前为止一切都很好。我认为在我糟糕的编程经验中失败的是 PlayButton() 方法

private void playButton(int i) {
    char j;
    if(i==0)
        j='0';
    else if(i==1)
        j='1';
    else if(i==2)
        j='2';
    else
        j='3';
    Button mc_button = (Button) findViewById(R.id.c_button);
    Button md_button = (Button) findViewById(R.id.d_button);
    Button me_button = (Button) findViewById(R.id.e_button);
    Button mf_button = (Button) findViewById(R.id.f_button);
    switch(j) {
        case '0':
            mc_button.setBackgroundResource(R.color.game2_c_on);
            //mCMediaPlayer = MediaPlayer.create(Game2PlayActivity.this, R.raw.c_sound);
            //mCMediaPlayer.start();
            //mCMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
            //    @Override
            //    public void onCompletion(MediaPlayer mp) {
            //        mCMediaPlayer.release();
            //    }
            //});
            break;
        case '1':
            md_button.setBackgroundResource(R.color.game2_d_on);
            //mDMediaPlayer = MediaPlayer.create(Game2PlayActivity.this, R.raw.d_sound);
            //mDMediaPlayer.start();
            //mDMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
            //    @Override
            //    public void onCompletion(MediaPlayer mp) {
            //        mDMediaPlayer.release();
            //    }
            //});
            break;
        case '2':
            me_button.setBackgroundResource(R.color.game2_e_on);
            //mEMediaPlayer = MediaPlayer.create(Game2PlayActivity.this, R.raw.e_sound);
            //mEMediaPlayer.start();
            //mEMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
            //    @Override
            //    public void onCompletion(MediaPlayer mp) {
            //        mEMediaPlayer.release();
            //    }
            //});
            break;
        case '3':
            mf_button.setBackgroundResource(R.color.game2_f_on);
            //mFMediaPlayer = MediaPlayer.create(Game2PlayActivity.this, R.raw.f_sound);
            //mFMediaPlayer.start();
            //mFMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
            //    @Override
            //    public void onCompletion(MediaPlayer mp) {
            //        mFMediaPlayer.release();
            //    }
            //});
            break;
    }
}

音频播放已被评论但过去工作得很好。这实际上都是关于那些 SetBackgroundResource 调用,它们不会立即执行,而是仅在 CreateSequence 方法中的 for 循环结束时执行。

如果有人想在 Android Studio 中实现整个项目(不推荐,因为它可能有很多错误),这里是 (25 MB):http://www.mediafire.com/file/2c86sbe3rkb231d/AudiogamesSuite.zip

提前致谢

-------------------------------------------- ----------------------------------

编辑 - 多亏了 Martin Pfeffer 和一些谷歌搜索,设法解决了这个问题。这是更新后的代码

private void createSequence(final int i) {
        Thread t = new Thread(new Runnable() {
            public void run() {
                Random rand = new Random();
                for (int j = 0; j < i; j++) {
                    final int seed = rand.nextInt(4);
                    try {
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                temp.add(seed);
                                playButton(seed);
                            }
                        });
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
        t.setDaemon(true);
        t.start();
    }

最佳答案

添加synchronized方法的说明符。

<罢工>
private synchronized void createSequence(int i) {
        // allow only one thread to be executed
}

<罢工> 编辑:

刚看到你没有使用单独的线程..所以运行这段代码来获得延迟:

new Handler().postDelayed(new Runnable(){
        public void run() {
          // do stuff             
      }}, 1000 * DELAY_IN_SECONDS);

编辑 2:

我认为您正在搜索这样的内容:

import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.TextView;

import java.util.concurrent.Callable;

public class MainActivity extends AppCompatActivity {

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

        new MyThread((TextView) findViewById(R.id.textView)).start();

    }


    class MyThread extends Thread implements Runnable {

        TextView textView;

        MyThread(TextView textView) {
            this.textView = textView;
        }

        @Override
        public void run() {
            for (int i = 0; i < 10; i++) {
                try {
                    sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                runOnMainUiThread(new Callable() {
                    @Override
                    public Object call() throws Exception {
                        textView.setText("" + System.currentTimeMillis());
                        return null;
                    }
                });

            }
        }

        void runOnMainUiThread(final Callable callable) {
            new Handler(Looper.getMainLooper()).post(new Runnable() {
                @Override
                public void run() {
                    try {
                        callable.call();
                    } catch (Exception e) {
                        Log.e("MyThread", "runOnMainUiThread: ", e);
                    }
                }
            });
        }
    }
}

如果您有任何问题,请随时提问:)

关于java - SetBackgroundResource() 延迟?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44231378/

相关文章:

sql - 如何在 MS SQL 2005 中使用 SQL XQuery 修改多个节点

python - 使用带有标签的 ElementTree 从 XML 检索文本时遇到问题

java - 有没有 Selenium 的替代品?

java - 构造函数调用给出错误继承

java - Android - JSONException 没有值(value)

android - 横向纵向

android - 按钮栏与回收站 View 问题重叠

java - 为号码指定名称

java - Java中Immutable类的实现

android - HttpResponse 响应 = httpclient.execute(httppost);即使使用 ASYNCTASK 也不能在 Android 4 中工作