简体   繁体   English

View.setVisibility(View.VISIBLE) 在开始另一个活动后停止工作,前提是该视图之前在 Android API <28 上不可见

[英]View.setVisibility(View.VISIBLE) stops working after after starting another activity only if that view was not visible before on Android API <28

I am making a simple game for Android.我正在为 Android 制作一个简单的游戏。 I have a number of views with buttons that are set to visibility to gone in the layout and when I want to show them I just set visibility to visible.我有许多带有按钮的视图,这些按钮在布局中设置为可见性,当我想显示它们时,我只是将可见性设置为可见。 Here is the layout:这是布局:

<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>

This works flawlessly when triggered by user.当由用户触发时,这可以完美地工作。 When its triggered by the game itself in a different thread I have to use runOnUiThread:当它由游戏本身在不同的线程中触发时,我必须使用 runOnUiThread:

activity.runOnUiThread(new Runnable() {
    @Override
    public void run() {
        Menu.showHighscore(score,original);
    }
});

Here is showHighscores:这是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());

}

This worked fine.这工作得很好。 There are no problems if I go to another app and back.如果我 go 到另一个应用程序并返回,则没有问题。 But problems appeared when I added features that start other activities: rate app, consent menu and interstitial ads.但是当我添加启动其他活动的功能时出现了问题:评价应用程序、同意菜单和插页式广告。

There are no problems on Android 9 (API 28), but on older Android versions starting from API 27 and down I have problems with certain UI updates not happening: Android 9 (API 28) 上没有问题,但在从 API 27 及以下版本开始的旧 Android 版本上,我遇到了某些 UI 更新未发生的问题:

  • For example the above code (showHighscores) will not make the GameOverMenu menu appear, even though its status changes to visible.例如,上面的代码 (showHighscores) 不会使 GameOverMenu 菜单出现,即使它的状态变为可见。
  • If I set it to invisible instead of gone in the xml file OR if I show it and hide before the problem is triggered, it WILL appear, but it will look like setText didn't work.如果我将它设置为不可见而不是在 xml 文件中消失,或者如果我在触发问题之前显示并隐藏它,它将出现,但看起来 setText 不起作用。

Here is what can trigger the problem:以下是可能引发问题的原因:

  • Showing consent form will always trigger it, regardless when the code below is executed (even in onCreate):无论何时执行以下代码(即使在 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 feature will trigger it, but only if it was triggered by user interaction. Rate App 功能会触发它,但前提是它是由用户交互触发的。 If I put the same code at the end of onCreate so it executes when the program starts it DOES NOT trigger the problem:如果我将相同的代码放在 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())));
        }
    }
  • Showing an interstitial also triggers it.显示插页式广告也会触发它。 I wasn't able to confirm whether it causes problem when in onCreate, because at that point it didn't load yet.我无法在 onCreate 中确认它是否会导致问题,因为那时它还没有加载。

I think this has something to do with starting new activity and coming back from it.我认为这与开始新活动并从中恢复有关。 I don't have this problem when I pause and resume the game.当我暂停和恢复游戏时,我没有这个问题。

These are my onPause and onResume:这些是我的 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();

}

I tried to put onPause code at the beginning of displayConsentForm and onResume code into onConsentFormClosed but it didn't solve the problem.我尝试将 onPause 代码放在 displayConsentForm 开头,将 onResume 代码放入 onConsentFormClosed ,但它没有解决问题。

Like Rishabh pointed out, I shouldn't have had getWindow().addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);就像 Rishabh 指出的那样,我不应该有getWindow().addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS); after setContentView() .setContentView()之后。 That's what was causing the problems.这就是造成问题的原因。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在view.setVisibility(View.GONE)和view.setVisibility(View.VISIBLE)之后刷新RelativeLayout - RelativeLayout refresh after view.setVisibility(View.GONE) and view.setVisibility(View.VISIBLE) setvisibility(view.oneible)在setvisibility之后无效(view.gone) - setvisibility(view.visible) not working after setvisibility(view.gone) 带自定义适配器的View.setVisibility(View.VISIBLE) - View.setVisibility(View.VISIBLE) with custom adapter Android setVisibility(View.Visible)不适用于布局 - Android setVisibility(View.Visible) not working on a layout 设置为不可见后,setVisibility(View.Visible)不起作用 - setVisibility(View.Visible) not working after setting to invisible 调用setVisibility(View.VISIBLE)后未绘制Android Listview项 - Android Listview Item not drawn after setVisibility(View.VISIBLE) is called 在KITKAT中屏幕旋转后,Android setVisibility(View.VISIBLE)根本无法正常工作 - Android setVisibility(View.VISIBLE) not working at all after screen rotation in KITKAT View.setVisibility(View.VISIBLE)是否强制视图重绘,即使它已经可见? - Does View.setVisibility(View.VISIBLE) forces the view to redraw even if it's already visible? setVisibility(View.VISIBLE)到imageView不起作用 - setVisibility(View.VISIBLE) to imageView is not working 如何从 View.gone 恢复视图。 在 xml 中使用 'android:visibility="gone"' 后 setVisibility(View.VISIBLE) 不工作 - How to recover view from View.gone. setVisibility(View.VISIBLE) not working after using 'android:visibility="gone"' in xml
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM