【问题标题】:View.setVisibility(View.VISIBLE) stops working after after starting another activity only if that view was not visible before on Android API <28View.setVisibility(View.VISIBLE) 在启动另一个活动后停止工作,前提是该视图之前在 Android API <28 上不可见
【发布时间】: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


【解决方案1】:

就像 Rishabh 指出的那样,我不应该在 setContentView() 之后拥有 getWindow().addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);。这就是造成问题的原因。

【讨论】:

    猜你喜欢
    • 2013-06-28
    • 1970-01-01
    • 1970-01-01
    • 2011-12-09
    • 1970-01-01
    • 2013-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多