Android12 - トーストの動作変更 + ボトムナビゲーションバーの適応

序文

私たちはゲーム製品を作っているので、未成年者ポリシーに関連する制限に関する新しい指示があり、サーバー側でインターフェイスが変更された後、フロントエンドで適応の問題が発生し、それが大きく影響します。 UIに影響を与えます。

 トーストを使用して長いテキストを表示すると、表示が不完全になるのはなぜですか。

検索の結果、Google は Android 12、targetSdkVersion>31 以降に調整を行ったことが判明しました。

 長文の表示にはトーストを使うのは非推奨ですが、他に方法がないのでプロジェクトチームに説明できず、ポップアップウィンドウを使うのは適切ではないので、考えるしかありません。アダプテーションについて 他にも実装方法はあるのでダメなら方法を探すかToastをカスタマイズするか?

そうなんです、結局ToastにはsetViewメソッドが用意されているので、あとはレイアウトを作って入れるだけです。コードをここに直接貼り付けます

import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
import android.os.Build;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Display;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.widget.TextView;
import android.widget.Toast;

public class BToast extends Toast {
    private BToast(Context context) {
        super(context);
    }
    private static BToast toast;
    private static void cancelToast() {
        //为什么把这个if语句去掉,就会异常终止呢?
        //因为程序第一次进来时, toast时为空的,第二次及以后, 它才不为空,才能执行toast.cancel()。
        if (toast != null) {
            toast.cancel();
        }
    }
    public void cancel() {
        super.cancel();
    }
    public void show() {
        super.show();
    }

    public static void initToast( Context context, CharSequence text,boolean NavigationBar) {
        //第二次点击及以后,它会先取消上一次的Toast, 然后show本次的Toast。
        cancelToast();
        toast = new BToast(context);

        View mView = LayoutInflater.from(context).inflate(RGet.$L("tc_activity_toast"), null);
        TextView mText = mView.findViewById(RGet.$ID("toast_show"));
        mText.setText(text);
        toast.setView(mView);
        int  height =  0;
        if(NavigationBar){
            height =  getNavigationBarHeight(context)/2;
        }
        Log.d("BToast",height+"");
        toast.setGravity(Gravity.TOP, -height, 70);
        toast.setDuration(Toast.LENGTH_LONG);
        toast.show();
    }

    //屏幕高度
    public  static int getHeight(Activity activity) {
        DisplayMetrics dm = new DisplayMetrics();
        WindowManager windowManager = (WindowManager) activity.getSystemService(Context.WINDOW_SERVICE);
        windowManager.getDefaultDisplay().getMetrics(dm);
        return dm.widthPixels;
    }

    //真实高度
    public static int getRealHeight(Activity activity) {
        WindowManager windowManager = (WindowManager) activity.getSystemService(Context.WINDOW_SERVICE);
        Display display = windowManager.getDefaultDisplay();
        DisplayMetrics dm = new DisplayMetrics();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            display.getRealMetrics(dm);
        } else {
            display.getMetrics(dm);
        }
        int realHeight = dm.widthPixels;
        return realHeight;
    }



    public static int getNavigationBarHeight(Context context) {
        Resources resources = context.getResources();
        int resourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android");
        return resourceId != 0 ? resources.getDimensionPixelSize(resourceId) : 0;
    }

レイアウト レイアウト

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/toast_backgound"
    >
    <TextView
        android:id="@+id/toast_show"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:layout_marginLeft="10dp"
        android:layout_marginRight="10dp"
        android:padding="8dp"
        android:text=""
        android:textColor="#000000"
        android:gravity="center"
        android:textSize="14sp" />
</LinearLayout>

 トースト_バックグラウンド.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <corners android:radius="10dp"/>
    <solid android:color="#ffffffff"/>
</shape>

移行

BToast.initToast(this,"",isshowNavigationBar);

 

とてもシンプルですが、まだ終わっていません。テキストの表示が長すぎる問題は解決されましたが、下部のナビゲーション バーを備えた携帯電話では、トーストの表示が中央に表示されていないことがわかります。次に情報を確認すると、下部のナビゲーション バーが表示されていることを確認します。オンラインで検索された適応もすべて True を返します。それがあってもなくても、それは面倒です。この偉人のブログを読んだ後、ついに解決策を見つけました。

https://blog.csdn.net/qq_20451879/article/details/79109501

下部の仮想ナビゲーション バー

仮想ボタンの有無

注意:指的是当前手机是否设置有虚拟按键!而不是指虚拟按键是否显示!

 public static boolean isHaveSoftKey(Activity activity) {
     Display d = activity.getWindowManager().getDefaultDisplay();
     DisplayMetrics realDisplayMetrics = new DisplayMetrics();
     d.getRealMetrics(realDisplayMetrics);
     int realHeight = realDisplayMetrics.heightPixels;
     int realWidth = realDisplayMetrics.widthPixels;
     DisplayMetrics displayMetrics = new DisplayMetrics();
     d.getMetrics(displayMetrics);
     int displayHeight = displayMetrics.heightPixels;
     int displayWidth = displayMetrics.widthPixels;
     return (realWidth - displayWidth) > 0 || (realHeight - displayHeight) > 0;
 }

下部の仮想ボタンの高さ

 public static int getBottomSoftKeysHeight(Activity activity) {
     Display d = activity.getWindowManager().getDefaultDisplay();
     DisplayMetrics realDisplayMetrics = new DisplayMetrics();
     d.getRealMetrics(realDisplayMetrics);
     int realHeight = realDisplayMetrics.heightPixels;
     DisplayMetrics displayMetrics = new DisplayMetrics();
     d.getMetrics(displayMetrics);
     int displayHeight = displayMetrics.heightPixels;
     return (realHeight - displayHeight);
 }

非表示、表示 - 下部の仮想ナビゲーション バー

  /**
     * @param state   true 隐藏  false 还原显示
     */
    public static void hideBottomMenu(Context context,boolean state){
        Intent barIntent = new Intent();
        barIntent.setAction("com.alf.switch_status_bar");
        barIntent.putExtra("hide", state);
        context.sendBroadcast(barIntent);
    }
————————————————
版权声明:本文为CSDN博主「Modu_Liu」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_20451879/article/details/79109501

非表示 - 下部の仮想ナビゲーション バー

    private void hideBottomMenu() {
        int flags = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
                View.SYSTEM_UI_FLAG_FULLSCREEN |
                View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
                View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY |
                View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
                View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
        View decorView = getWindow().getDecorView();
        decorView.setSystemUiVisibility(flags);
    }

非表示 - 下部の仮想ナビゲーション バー

隐藏底部虚拟按键,但是如果你在底部网上滑动还是显示的出来的

    private void hideBottomMenu() {
        //android 隐藏底部虚拟按键
        //隐藏虚拟按键,并且全屏
        if (Build.VERSION.SDK_INT > 11 && Build.VERSION.SDK_INT < 19) { // lower api
            View v = this.getWindow().getDecorView();
            v.setSystemUiVisibility(View.GONE);
        } else if (Build.VERSION.SDK_INT >= 19) {
            //for new api versions.
            View decorView = getWindow().getDecorView();
            int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                    | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
                    | View.SYSTEM_UI_FLAG_FULLSCREEN;
            decorView.setSystemUiVisibility(uiOptions);
        }
    }

关于这个功能我在网上找了很多半成品,大部分都无效,所幸拼拼凑凑实现了此项功能,亲测可用!

以下のコードを貼り付けてください。

ナビゲーションアクティビティ
建议:可以将NavigationActivity的关键代码移植到我们项目的BaseActivity,同时此类中的一些Log完全可以删掉,这里打Log只是为了看一些执行流程 ~


import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.ViewTreeObserver;
import android.widget.FrameLayout;

public class NavigationActivity extends Activity implements ViewTreeObserver.OnGlobalLayoutListener {
    FrameLayout content;
    private static final String TAG = "BaseActivityForAuto";
    private boolean mLayoutComplete = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        content = (FrameLayout) findViewById(android.R.id.content);
        content.post(new Runnable() {
            @Override
            public void run() {
                mLayoutComplete = true;
                Log.e(TAG, "content 布局完成");
            }
        });
        content.getViewTreeObserver().addOnGlobalLayoutListener(NavigationActivity.this);
    }


    @Override
    public void onGlobalLayout() {
        Log.e(TAG, "onGlobalLayout");
        if (!mLayoutComplete)
            return;
        onNavigationBarStatusChanged();
    }

    protected void onNavigationBarStatusChanged() {
        // 子类重写该方法,实现自己的逻辑即可。
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        content.getViewTreeObserver().removeOnGlobalLayoutListener(this);
    }
}

主な活動
此处的MainActivity替代到对应的需求类即可,但是要记得继承上方的父类 - - ~

因为我们的游戏是横屏,所以这里的判断高度,实质上是宽度。

import android.content.Context;
import android.os.Build;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Display;
import android.view.WindowManager;

public class MainActivity extends NavigationActivity {

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

    boolean isshowNavigationBar = true;

    @Override
    protected void onNavigationBarStatusChanged() {
        super.onNavigationBarStatusChanged();
        int displayWidth = BToast.getHeight(this)+BToast.getNavigationBarHeight(this);
        int basicWidth = BToast.getRealHeight(this);
        Log.e("tag", "宽度" + displayWidth);
        Log.e("tag", "真实宽度" + basicWidth);
        if (displayWidth < basicWidth) {
            isshowNavigationBar = true;
            Log.e("tag", "底部导航显示");
        } else {
            isshowNavigationBar = false;
            Log.e("tag", "底部导航隐藏");
        }
    }
}

要約する

この小さな問題を通じて、Android のバージョンのアップデートに伴い、動作に多くの変更が発生しており、時代に追いつく必要があることがわかりました。下部のナビゲーション バーの適応に関する記事はインターネット上に多数ありますが、試してみたところ、どれも効果は同じであまり役に立たず、自分のビジネスと相手のビジネスが一致していない可能性があります。つまり、問題を無事に解決できた兄のModu_Liuに今でも感謝したいと思います。尊敬!

おすすめ

転載: blog.csdn.net/qq_34123324/article/details/131230802