【发布时间】:2020-02-15 23:15:41
【问题描述】:
我正在为 Android 制作一个简单的游戏。我有许多带有按钮的视图,这些按钮在布局中设置为可见性,当我想显示它们时,我只是将可见性设置为可见。 这是布局:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
android:id="@+id/Container"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center"
android:background="#000000"
android:orientation="vertical">
</LinearLayout>
<LinearLayout
android:id="@+id/Menu"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal|center_vertical"
android:orientation="vertical"
android:padding="5dip"
android:visibility="gone"
android:background="@drawable/menu_design"
android:textColor="#ffffffff">
<TextView
android:id="@+id/MenuLabel"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:clickable="false"
android:padding="3dip"
android:layout_margin="5dip"
android:gravity="center"
android:textColor="#ffffffff"
android:textSize="20dip"
android:text="Main Menu" />
<TextView
android:id="@+id/Op1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:onClick="contin"
android:clickable="true"
android:padding="10dip"
android:layout_margin="5dip"
android:background="@drawable/button_design"
android:gravity="center"
android:textColor="#ffffffff"
android:textSize="20dip"
android:text="Continue" />
<TextView
android:id="@+id/Op2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:onClick="restart"
android:clickable="true"
android:padding="10dip"
android:layout_margin="5dip"
android:background="@drawable/button_design"
android:gravity="center"
android:textColor="#ffffffff"
android:textSize="20dip"
android:text="New Game" />
<TextView
android:id="@+id/Sound"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:onClick="sound"
android:clickable="true"
android:padding="10dip"
android:layout_margin="5dip"
android:background="@drawable/button_design"
android:gravity="center"
android:textColor="#ffffffff"
android:textSize="20dip"
android:text="Sound" />
<TextView
android:id="@+id/Settings"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:onClick="settings"
android:clickable="true"
android:padding="10dip"
android:layout_margin="5dip"
android:background="@drawable/button_design"
android:gravity="center"
android:textColor="#ffffffff"
android:textSize="20dip"
android:text="Settings" />
</LinearLayout>
<LinearLayout
android:id="@+id/GameOver"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal|center_vertical"
android:orientation="vertical"
android:padding="5dip"
android:visibility="gone"
android:background="@drawable/menu_design"
android:textColor="#ffffffff">
<TextView
android:id="@+id/Score"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:clickable="false"
android:padding="10dip"
android:layout_margin="5dip"
android:gravity="center"
android:textColor="#ffffffff"
android:textSize="23dip"
android:text="Your Score:" />
<TextView
android:id="@+id/HighScore"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:clickable="false"
android:padding="10dip"
android:layout_margin="5dip"
android:gravity="center"
android:textColor="#ffffffff"
android:textSize="20dip"
android:text="HighScore:" />
<TextView
android:id="@+id/LeaveGameOver"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:onClick="leaveGameOver"
android:clickable="true"
android:padding="10dip"
android:layout_margin="5dip"
android:background="@drawable/button_design"
android:gravity="center"
android:textColor="#ffffffff"
android:textSize="20dip"
android:text="Main Menu" />
</LinearLayout>
</FrameLayout>
当由用户触发时,它可以完美地工作。当它由游戏本身在不同的线程中触发时,我必须使用 runOnUiThread:
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
Menu.showHighscore(score,original);
}
});
这里是showHighscores:
public static void showHighscore(int s, int hs) {
gameOver = act.findViewById(R.id.GameOver);
System.out.println("Visiblity: " + gameOver.getVisibility());
score.setText("Your Score: " + s);
highScore.setText("HighScore: " + hs);
gameOver.setVisibility(View.VISIBLE);
System.out.println("NORMAL HIGHSCORE");
System.out.println("Visiblity: " + gameOver.getVisibility());
}
这很好用。如果我转到另一个应用程序并返回,则没有问题。但是当我添加启动其他活动的功能时出现了问题:评价应用程序、同意菜单和插页式广告。
在 Android 9 (API 28) 上没有问题,但在从 API 27 及以下版本开始的旧 Android 版本上,我遇到了某些 UI 更新没有发生的问题:
- 例如,上面的代码 (showHighscores) 不会使 GameOverMenu 菜单出现,即使它的状态变为可见。
- 如果我将它设置为不可见而不是在 xml 文件中消失,或者如果我在触发问题之前显示并隐藏它,它会出现,但看起来 setText 不起作用。
以下是可能引发问题的原因:
- 无论何时执行以下代码(即使在 onCreate 中),显示同意书都会触发它:
public void displayConsentForm() {
URL privacyUrl = null;
try {
// TODO: Replace with your app's privacy policy URL.
privacyUrl = new URL("https://r.flycricket.io/privacy.html");
} catch (MalformedURLException e) {
e.printStackTrace();
// Handle error.
}
consentForm = new ConsentForm.Builder(context, privacyUrl)
.withListener(new ConsentFormListener() {
@Override
public void onConsentFormLoaded() {
consentForm.show();
}
@Override
public void onConsentFormOpened() {
// Consent form was displayed.
}
@Override
public void onConsentFormClosed(ConsentStatus consentStatus, Boolean userPrefersAdFree) {
// Consent form was closed.
if(userPrefersAdFree==true)
{
startBuy();
}
else
{
ConsentInformation.getInstance(context).setConsentStatus(consentStatus);
}
}
@Override
public void onConsentFormError(String errorDescription) {
// Consent form error.
}
})
.withPersonalizedAdsOption()
.withNonPersonalizedAdsOption()
.withAdFreeOption()
.build();
consentForm.load();
}
- Rate App 功能会触发它,但前提是它是由用户交互触发的。如果我将相同的代码放在 onCreate 的末尾,以便在程序启动时执行它不会触发问题:
public void rateApp(View v) {
Uri uri = Uri.parse("market://details?id=" + context.getPackageName());
Intent goToMarket = new Intent(Intent.ACTION_VIEW, uri);
// To count with Play market backstack, After pressing back button,
// to taken back to our application, we need to add following flags to intent.
goToMarket.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY |
Intent.FLAG_ACTIVITY_NEW_DOCUMENT |
Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
try {
startActivity(goToMarket);
} catch (ActivityNotFoundException e) {
startActivity(new Intent(Intent.ACTION_VIEW,
Uri.parse("http://play.google.com/store/apps/details?id=" + context.getPackageName())));
}
}
- 显示插页式广告也会触发它。我无法在 onCreate 中确认它是否会导致问题,因为那时它还没有加载。
我认为这与开始新活动并从中恢复有关。当我暂停和恢复游戏时,我没有这个问题。
这些是我的 onPause 和 onResume:
public void onPause() {
super.onPause();
//Menu.pause();
Units.kill=true;
System.out.println("Killing");
sound.stopSounds();
while(true) {
try {
animThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
break;
}
animThread=null;
}
public void onResume() {
super.onResume();
getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
Units.kill = false;
animThread = new AnimationThread(this);
animThread.setDaemon(true);
animThread.setPriority(8);
animThread.start();
if(FullscreenActivity.sound.beam==true)FullscreenActivity.sound.startCannon();
//if(Units.showAds==true && billingClient.isReady()) checkPurchases();
}
我尝试将 onPause 代码放在 displayConsentForm 开头,将 onResume 代码放在 onConsentFormClosed 中,但没有解决问题。
【问题讨论】:
-
在
showHighscore()中尝试在更新Text Views之前设置gameOver Visibility。 -
我试过了。不幸的是没有帮助。
-
显然是由 onResume getWindow().getDecorView().setSystemUiVisibility( View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View. SYSTEM_UI_FLAG_IMMERSIVE_STICKY); getWindow().addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);有办法吗?
-
getWindow().addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);应在首次调用setContentView()或getDecorView之前使用。
标签: android multithreading user-interface interstitial