22

How to get rid of unnecessary root layouts for fullscreen activities?

I have a simple fullscreen activity. The layout inspector shows a large hierarchy of root layouts provided by Android, that I don't need in fullscreen.

<code>Tools > Android > Layout Inspector</code>

Can I get rid of them?

  • If YES, how?
  • If NO, why not?

The testing setup

Open Android Studio. Create a new project. Accept the default settings. Choose "Empty Activity". You get this manifest:

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

You get this layout/activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.blcknx.myapplication.MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>

Call Tools > Android > Layout Inspector to see the generated root templates.

To make it fullscreen, just add an id HelloWorld to the TextView in the layout and update MainActivity.java:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        TextView layout = findViewById(R.id.HelloWorld);
        layout.setSystemUiVisibility(
                View.SYSTEM_UI_FLAG_LOW_PROFILE
                        | View.SYSTEM_UI_FLAG_FULLSCREEN
                        | View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                        | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
                        | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                        | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
        );
    }
}

The flags are hiding the navigation, but they don't remove the unused layouts.

Your answer

Use a simple TextView. Show it fullscreen. Check by Tools > Android > Layout Inspector how far you removed the root layouts. Show a screenshot. Show your code.

Blcknx
  • 1,921
  • 1
  • 12
  • 38

3 Answers3

8

You can get rid of action_bar_container having changed your activity's theme from DarkActionBar to NoActionBar:

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    ...
</style>

Then you'll get following tree:

enter image description here

If you want to go even more and get rid of ContentFrameLayout, than you can do this:


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        val contentView = findViewById(android.R.id.content)
        val parent = contentView.parent as ViewGroup
        parent.removeView(contentView)
        LayoutInflater.from(this).inflate(R.layout.activity_main, parent)
    }

This will be the view hierarchy tree:

enter image description here

Not sure whether you should remove android.R.id.content view, maybe some libraries are assuming that there should exist such a view.

As to action_mode_bar_stubs: you should not be concerned about them, as long as those are ViewStubs, which do not affect overall performance, because they are lazily inflated into view hierarchy.

azizbekian
  • 60,783
  • 13
  • 169
  • 249
  • This is a good part of the answer. At least the action bar container is gone, obviously in a supported way. Removing `android.R.id.content` is kind of a hack, however it reduces the clutter in the layout inspector. Will it also improve performance or is it done to late for this? As for the action mode bar stubs, they are still there. Likely Android does not want to take the user away this options. Mere speculation. This part is still open to find a non-speculative answer. – Blcknx Mar 04 '18 at 17:37
  • `Will it also improve performance or is it done to late for this?` the fewer views you have in your view hierarchy, the better performance you will get. `As for the action mode bar stubs, they are still there.` See updated answer. What do you mean by "speculations"? – azizbekian Mar 04 '18 at 17:44
  • Yes, I assume you can "hack" the stubs away in a similar way. Let's see what happens. If nothing crashes, it's possible and likely an acceptable answer. – Blcknx Mar 04 '18 at 17:46
  • Spekulation refers to the question, how is the official Android documentation addressing this questions. Do they support this kind of hacks or do they warn? – Blcknx Mar 04 '18 at 17:48
  • `Yes, I assume you can "hack" the stubs away in a similar way.` If you are not using action mode within the app, then you are free to remove those also, but it will give you 0 benefit, as long as those views do not affect on performance anyhow. I do not think this kind of actions are somehow documented. – azizbekian Mar 04 '18 at 18:04
  • Bonus question: What is the secret ingredient in `Theme.AppCompat.Light.NoActionBar`? Can you easily add it to your own theme to avoid this dependency on a deep hierarchy theme. – Blcknx Mar 04 '18 at 18:09
  • `As to action_mode_bar_stubs: you should not be concerned about them, as long as those are ViewStubs, which do not affect overall performance, because they are lazily inflated into view hierarchy.` It's not the stubs themselves. They cause this hierarchy of `LinearLayout > FrameLayout > action_bar_root`. – Blcknx Mar 04 '18 at 20:01
  • `What is the secret ingredient in Theme.AppCompat.Light.NoActionBar?` It has just two attributes specified: `windowActionBar` as false and `windowNoTitle` as true, other than that it inherits from `Theme.AppCompat.Light`. – azizbekian Mar 04 '18 at 20:07
4

Layout Inspector

Activity Code

import android.app.Activity;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.Window;
import android.view.WindowManager;

public class ThirdActivity extends Activity {

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {

    requestWindowFeature(Window.FEATURE_NO_TITLE);
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
            WindowManager.LayoutParams.FLAG_FULLSCREEN);

    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_third);
}
}

R.layout.third_activity

<?xml version="1.0" encoding="utf-8"?>
 <TextView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".ThirdActivity"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Hello World"
android:gravity="center">
 </TextView>

styles.xml

<style name="AppTheme2" parent="@android:style/Theme"/>

AndroidManifest.xml

<activity android:name=".ThirdActivity" android:theme="@style/AppTheme2">

Please don't mind the indentation.

Thanks,

Rahul
  • 4,699
  • 5
  • 26
  • 38
  • 1
    TL;DR: Don't use `AppCompatActivity`. – Eugen Pechanec Mar 10 '18 at 13:18
  • From all answers this answer reduces the layout tree to the max. I think, by combining it with the solution of azizbekian, you could even get the rid of the `ContentFrameLayout`, which in combination would be the best answer. As nobody provided the combination, I will choose this answer as the winner. What it implies to not use `AppCompatActivity` for older Androids, is a different topic. – Blcknx Mar 10 '18 at 23:17
2

Yes, you are probably looking for ConstraintLayout. It's similar to a RelativeLayout, but with more possibilities and easier to use. Because you can position views everywhere in the ConstraintLayout you can get rid of all those unnecessary layouts, thus flatten the hierarchy.

Oscar Spruit
  • 154
  • 8
  • This is NOT the xml file. This is a screenshot from `Tools > Android > LayoutInspector` taken from the **running** application. The suggested `ConstraintLayout` from the `layout/activity.xml` file starts below all this. – Blcknx Mar 03 '18 at 19:53
  • @Blcknx can you provide the xml, so I can have a better understanding of how your layout is made up? – Oscar Spruit Mar 03 '18 at 21:02
  • 2
    Again, this is not about the xml. You can just put an empty `ConstraintLayout` into the xml. Android will put all this action bar stuff on top of it. You will not find this in the xml. You find it in the running application. – Blcknx Mar 03 '18 at 21:18
  • 1
    Sorry, I understand now. After a little bit of searching I think it's just how the Android system works. Those views are probably used by the system to inflate the views of an app. – Oscar Spruit Mar 03 '18 at 22:03