Làm thế nào để ẩn thanh điều hướng vĩnh viễn trong hoạt động Android?


80

Tôi muốn ẩn thanh điều hướng vĩnh viễn trong hoạt động của mình (không phải toàn bộ hệ thống). bây giờ tôi đang sử dụng đoạn mã này

getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);

Nó ẩn thanh nhưng khi người dùng chạm vào màn hình, nó sẽ hiển thị trở lại. có cách nào để ẩn nó vĩnh viễn cho đến khi hoạt động onStop();



Rất nhiều chi tiết hay và cụ thể được trình bày ở đây, trong liên kết chính thức của Google / Android này: Bật chế độ toàn màn hình .
Chris Sprague,

Cờ tự động xóa khi người dùng chạm vào màn hình theo tài liệu hướng dẫn. Bạn phải thực hiện các thay đổi đối với thiết kế giao diện người dùng của mình để luôn ẩn thanh điều hướng.
user1154390

Câu trả lời:


118

Đoạn mã:

FullScreenFragment.java

HideNavigationBarComponent.java


Điều này dành cho Android 4.4+

Hãy thử chế độ nhập vai https://developer.android.com/training/system-ui/immersive.html

Đoạn mã nhanh (cho một lớp Hoạt động ):

private int currentApiVersion;

@Override
@SuppressLint("NewApi")
protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);

    currentApiVersion = android.os.Build.VERSION.SDK_INT;

    final int flags = 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;

    // This work only for android 4.4+
    if(currentApiVersion >= Build.VERSION_CODES.KITKAT)
    {

        getWindow().getDecorView().setSystemUiVisibility(flags);

        // Code below is to handle presses of Volume up or Volume down.
        // Without this, after pressing volume buttons, the navigation bar will
        // show up and won't hide
        final View decorView = getWindow().getDecorView();
        decorView
            .setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener()
            {

                @Override
                public void onSystemUiVisibilityChange(int visibility)
                {
                    if((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0)
                    {
                        decorView.setSystemUiVisibility(flags);
                    }
                }
            });
    }

}


@SuppressLint("NewApi")
@Override
public void onWindowFocusChanged(boolean hasFocus)
{
    super.onWindowFocusChanged(hasFocus);
    if(currentApiVersion >= Build.VERSION_CODES.KITKAT && hasFocus)
    {
        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);
    }
}

Nếu bạn gặp sự cố khi nhấn Tăng âm lượng hoặc Giảm âm lượng mà thanh điều hướng của bạn hiển thị. Tôi đã thêm mã vào onCreatexem setOnSystemUiVisibilityChangeListener

Đây là một câu hỏi liên quan khác:

Điều hướng ở chế độ nhập vai trở nên dính sau khi nhấn âm lượng hoặc thu nhỏ-khôi phục


4
Khi người dùng vuốt trên cùng / dưới cùng của màn hình, điều đó sẽ hiển thị các thanh điều hướng Bán trong suốt tạm thời xuất hiện và sau đó ẩn lại. CÓ KHẢ NĂNG HÃY NÓI QUÁ KHÔNG?
Finder

@KarthickRamu Tôi tìm thấy một cách, chỉ cần nhìn vào câu trả lời của tôi xuống :)
Muhammed Refaat

1
@MuhammedRefaat Gợi ý của bạn cần một thiết bị đã được root :(
Finder

1
@DawidDrozd Cảm ơn bạn, nhưng tôi gặp sự cố, bố cục gốc hoạt động của tôi là RelativeLayout và nó có chế độ xem con được đặt android: layout_alignParentBottom = "true", thanh điều hướng biến mất nhưng chế độ xem con không di chuyển xuống cạnh dưới cùng của màn hình, như thể thanh điều hướng được đặt thành ẩn không biến mất, bạn có thể giúp gì không?
Jack

1
Nếu bạn muốn tận dụng không gian mà thanh điều hướng đã chiếm, bạn phải xóa tất cả các lần xuất hiện android:fitsSystemWindows="true"khỏi chế độ xem của mình. Android Studio bao gồm thuộc tính này khi tạo một số bố cục. Xem stackoverflow.com/a/42501330/650894
Joe Lapp

65

Làm cái này.

public void FullScreencall() {
    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;
        decorView.setSystemUiVisibility(uiOptions);
    }
}

Điều này hoạt động 100% và bạn có thể làm tương tự cho các phiên bản API thấp hơn, ngay cả khi đó là câu trả lời muộn, tôi hy vọng nó sẽ giúp ích cho người khác.

Nếu bạn muốn điều này là vĩnh viễn, chỉ cần gọi FullscreenCall()bên trong onResume()phương thức của bạn .


2
Tôi khuyên bạn nên xem qua developer.android.com/training/system-ui/immersive.html , giải thích rằng phương pháp của bạn chỉ cần ẩn thanh cho đến khi có tương tác và lặp lại ngay sau khi tương tác hoàn tất.
Giỏ hàng bị bỏ rơi

Cảm ơn bạn rất nhiều - Điều đó đã làm được! : D: +1
Christopher Stock

7

Đối với những người đang tìm kiếm một giải pháp đơn giản hơn, tôi nghĩ bạn có thể chỉ cần một dòng mã này trong onStart()

  getWindow().getDecorView().setSystemUiVisibility(
            View.SYSTEM_UI_FLAG_HIDE_NAVIGATION|
            View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);

Nó được gọi là chế độ Chìm. Bạn có thể xem tài liệu chính thức để biết các khả năng khác.


Tôi gặp lỗi (không tìm thấy biểu tượng View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);) super.onStart (); } `` '
Bilal Yaqoob

4

Theo trang web Nhà phát triển Android

Tôi nghĩ rằng bạn không thể (theo như tôi biết) ẩn thanh điều hướng vĩnh viễn ..

Tuy nhiên, bạn có thể làm một thủ thuật. Đó là một thủ thuật tâm trí bạn.

Chỉ khi màn navigation barhình hiển thị khi người dùng chạm vào màn hình. Ngay lập tức ẩn nó lại. Nó vui.

Kiểm tra cái này .

void setNavVisibility(boolean visible) {
int newVis = SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
        | SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
        | SYSTEM_UI_FLAG_LAYOUT_STABLE;
if (!visible) {
    newVis |= SYSTEM_UI_FLAG_LOW_PROFILE | SYSTEM_UI_FLAG_FULLSCREEN
            | SYSTEM_UI_FLAG_HIDE_NAVIGATION;
}

// If we are now visible, schedule a timer for us to go invisible.
if (visible) {
    Handler h = getHandler();
    if (h != null) {
        h.removeCallbacks(mNavHider);
        if (!mMenusOpen && !mPaused) {
            // If the menus are open or play is paused, we will not auto-hide.
            h.postDelayed(mNavHider, 1500);
        }
    }
}

// Set the new desired visibility.
setSystemUiVisibility(newVis);
mTitleView.setVisibility(visible ? VISIBLE : INVISIBLE);
mPlayButton.setVisibility(visible ? VISIBLE : INVISIBLE);
mSeekView.setVisibility(visible ? VISIBLE : INVISIBLE);
}

Xem phần này để biết thêm thông tin về điều này ..

Ẩn thanh hệ thống trong máy tính bảng


3

Sử dụng:-

view.setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);

Trong Máy tính bảng chạy Android 4+, không thể ẩn Hệ thống / Thanh điều hướng.

Từ tài liệu :

SYSTEM_UI_FLAG_HIDE_NAVIGATION là một cờ mới yêu cầu ẩn hoàn toàn thanh điều hướng. Lưu ý rằng điều này chỉ hoạt động đối với thanh điều hướng được sử dụng bởi một số thiết bị cầm tay (nó không ẩn thanh hệ thống trên máy tính bảng).


2

Đó là giải pháp của tôi:

Đầu tiên, xác định boolean cho biết thanh điều hướng có hiển thị hay không.

boolean navigationBarVisibility = true //because it's visible when activity is created

Thứ hai tạo phương pháp ẩn thanh điều hướng.

private void setNavigationBarVisibility(boolean visibility){
    if(visibility){
        View decorView = getWindow().getDecorView();
        int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                | View.SYSTEM_UI_FLAG_FULLSCREEN;
        decorView.setSystemUiVisibility(uiOptions);
        navigationBarVisibility = false;
    }

    else
        navigationBarVisibility = true;
}

Theo mặc định, nếu bạn nhấp vào hoạt động sau khi ẩn thanh điều hướng, thanh điều hướng sẽ hiển thị. Vì vậy, chúng tôi có trạng thái của nó nếu nó hiển thị, chúng tôi sẽ ẩn nó.

Bây giờ đặt OnClickListener thành chế độ xem của bạn. Tôi sử dụng một bề mặt để đối với tôi:

    playerSurface.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            setNavigationBarVisibility(navigationBarVisibility);
        }
    });

Ngoài ra, chúng ta phải gọi phương thức này khi hoạt động được khởi chạy. Bởi vì chúng tôi muốn ẩn nó ngay từ đầu.

        setNavigationBarVisibility(navigationBarVisibility);

2

Đó là sự cố bảo mật: https://stackoverflow.com/a/12605313/1303691

do đó không thể ẩn Điều hướng trên máy tính bảng vĩnh viễn chỉ với một lệnh gọi khi bắt đầu tạo chế độ xem. Nó sẽ bị ẩn đi, nhưng nó sẽ bật lên khi chạm vào Màn hình. Vì vậy, chỉ cần chạm thứ hai vào màn hình của bạn có thể gây ra onClickEvent trên bố cục của bạn. Do đó, bạn cần chặn cuộc gọi này, nhưng tôi chưa quản lý được, tôi sẽ cập nhật câu trả lời của mình khi tôi phát hiện ra. Hay bây giờ bạn đã có câu trả lời?


1

Tôi nghĩ mã đòn sẽ giúp bạn và thêm những mã đó trước setContentView ()

getWindow().setFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS, WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);

Thêm những đoạn mã đó vào sau setContentView () getWindow (). GetDecorView (). SetSystemUiVisibility (View.SYSTEM_UI_FLAG_LOW_PROFILE);


1
Lĩnh vực đòi hỏi trình độ API trên 21
zackygaurav

1

Các câu trả lời khác chủ yếu sử dụng các cờ cho setSystemUiVisibility()phương thức in View. Tuy nhiên, API này không được dùng nữa kể từ Android 11. Hãy xem bài viết của tôi về cách sửa đổi khả năng hiển thị giao diện người dùng hệ thống để biết thêm thông tin. Bài báo cũng giải thích cách xử lý các vết cắt đúng cách hoặc cách lắng nghe các thay đổi về khả năng hiển thị.

Dưới đây là các đoạn mã để hiển thị / ẩn các thanh hệ thống với API mới cũng như đoạn mã không dùng nữa để tương thích ngược:

/**
 * Hides the system bars and makes the Activity "fullscreen". If this should be the default
 * state it should be called from [Activity.onWindowFocusChanged] if hasFocus is true.
 * It is also recommended to take care of cutout areas. The default behavior is that the app shows
 * in the cutout area in portrait mode if not in fullscreen mode. This can cause "jumping" if the
 * user swipes a system bar to show it. It is recommended to set [WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER],
 * call [showBelowCutout] from [Activity.onCreate]
 * (see [Android Developers article about cutouts](https://developer.android.com/guide/topics/display-cutout#never_render_content_in_the_display_cutout_area)).
 * @see showSystemUI
 * @see addSystemUIVisibilityListener
 */
fun Activity.hideSystemUI() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
        window.insetsController?.let {
            // Default behavior is that if navigation bar is hidden, the system will "steal" touches
            // and show it again upon user's touch. We just want the user to be able to show the
            // navigation bar by swipe, touches are handled by custom code -> change system bar behavior.
            // Alternative to deprecated SYSTEM_UI_FLAG_IMMERSIVE.
            it.systemBarsBehavior = WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
            // make navigation bar translucent (alternative to deprecated
            // WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION)
            // - do this already in hideSystemUI() so that the bar
            // is translucent if user swipes it up
            window.navigationBarColor = getColor(R.color.internal_black_semitransparent_light)
            // Finally, hide the system bars, alternative to View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
            // and SYSTEM_UI_FLAG_FULLSCREEN.
            it.hide(WindowInsets.Type.systemBars())
        }
    } else {
        // Enables regular immersive mode.
        // For "lean back" mode, remove SYSTEM_UI_FLAG_IMMERSIVE.
        // Or for "sticky immersive," replace it with SYSTEM_UI_FLAG_IMMERSIVE_STICKY
        @Suppress("DEPRECATION")
        window.decorView.systemUiVisibility = (
                // Do not let system steal touches for showing the navigation bar
                View.SYSTEM_UI_FLAG_IMMERSIVE
                        // Hide the nav bar and status bar
                        or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                        or View.SYSTEM_UI_FLAG_FULLSCREEN
                        // Keep the app content behind the bars even if user swipes them up
                        or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                        or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN)
        // make navbar translucent - do this already in hideSystemUI() so that the bar
        // is translucent if user swipes it up
        @Suppress("DEPRECATION")
        window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION)
    }
}

/**
 * Shows the system bars and returns back from fullscreen.
 * @see hideSystemUI
 * @see addSystemUIVisibilityListener
 */
fun Activity.showSystemUI() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
        // show app content in fullscreen, i. e. behind the bars when they are shown (alternative to
        // deprecated View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION and View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN)
        window.setDecorFitsSystemWindows(false)
        // finally, show the system bars
        window.insetsController?.show(WindowInsets.Type.systemBars())
    } else {
        // Shows the system bars by removing all the flags
        // except for the ones that make the content appear under the system bars.
        @Suppress("DEPRECATION")
        window.decorView.systemUiVisibility = (
                View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                        or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN)
    }
}

Tôi đã thử mã của bạn với cờ BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE trên trình mô phỏng, nhưng thanh điều hướng sẽ bật lên và vẫn hiển thị khi tôi chạm vào màn hình. Bất kỳ ý tưởng nào khác tôi nên đặt để có được chức năng STICKY trên Android 11 không?
Angel Koh

@AngelKoh Bạn phải gọi hideSystemUI () theo cách thủ công nếu muốn ẩn nó. Kiểm tra bài báo được đề cập trong câu trả lời của tôi, nó chứa tất cả những chi tiết này. Chế độ dính có nghĩa là các thanh sẽ trong suốt nếu người dùng vuốt chúng lên và ứng dụng cũng sẽ nhận được các sự kiện chạm (xem developer.android.com/training/system-ui/… ).
Miloš Černilovský

có hideSystemUI () được gọi và Ui bị ẩn lần đầu tiên. tuy nhiên khi tôi chạm vào màn hình sau đó, thanh điều hướng bật ra và vẫn hiển thị.
Angel Koh

Mục đích của BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE là ngăn hệ thống đánh cắp các thao tác chạm và hiển thị các thanh. Vì vậy, tôi không chắc điều gì có thể gây ra điều này mà không thấy / gỡ lỗi ứng dụng thực.
Miloš Černilovský

0

Thử cái này:

View decorView = getWindow().getDecorView();
int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
          | View.SYSTEM_UI_FLAG_FULLSCREEN;
decorView.setSystemUiVisibility(uiOptions);

NO nó cho tôi kết quả tương tự
Sujith Manjavana

0

Tôi nghĩ rằng mã này sẽ giải quyết vấn đề của bạn. Sao chép và dán mã này vào MainActivity.java của bạn

@Override
protected void onCreate(Bundle savedInstanceState) {                          
    super.onCreate(savedInstanceState);

    View decorView = getWindow().getDecorView();
    decorView.setOnSystemUiVisibilityChangeListener
    (new View.OnSystemUiVisibilityChangeListener() {
        @Override
        public void onSystemUiVisibilityChange(int visibility) {

            if ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) {
                hideNavigationBar();
            } 
        }
    });
}



private void hideNavigationBar() {
   getWindow().getDecorView().setSystemUiVisibility(
        View.SYSTEM_UI_FLAG_HIDE_NAVIGATION|
        View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
}

Nó sẽ hoạt động trên Android-10. Tôi hy vọng nó sẽ giúp.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.