This is not an "opinion-based question". I need to know what to do in this situation because good performance is necessary. I need a solution to reduce long inflate time, Or alternative views for material component views.
- last days created an app and it is layout & styles 95% from material design/component.
- The app logic (java code) was simple and not complex (no hard process).
- Layouts hierarchy was simple as mush it could be, avoid depth / nested view groups, using constraintlayout.
- The device I use is Samsung A30 (not weak or old).
The app was slow at startup and navigation between fragments & activities(2). So looking at what is going in the back scene is a must(CPU profile).
What I found was like a bomb for me, All Material Design/Component views take so much time to inflate.
examples:
CoordinateLayout take 40Ms to inflate
FloatActionButton take 100Ms to inflate
BottomNavigation take 220Ms to inflate
BottomAppBar take 40Ms to inflate
TextInputLayout take 100Ms to inflate
TextInputEditText take 30Ms to inflate
MateriaCardView take 30Ms to inflate
MotoinLayout take 35Mx to inflate
. . .
Examples of my layouts (layout used in profile): DashBoard Activity Layout:
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
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:id="@ id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".DashBoardActivity">
<androidx.fragment.app.FragmentContainerView
android:id="@ id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="@dimen/my50dp"
app:defaultNavHost="true"
app:navGraph="@navigation/dash_board_navigation" />
<com.google.android.material.bottomappbar.BottomAppBar
android:id="@ id/bottomAppBar"
style="@style/Widget.MaterialComponents.BottomAppBar.Colored"
android:layout_width="match_parent"
android:layout_height="@dimen/my50dp"
android:layout_gravity="bottom"
app:contentInsetEnd="0dp"
app:contentInsetLeft="0dp"
app:contentInsetRight="0dp"
app:contentInsetStart="0dp"
app:contentInsetStartWithNavigation="0dp"
app:elevation="@dimen/my0dp"
app:fabAlignmentMode="center"
app:fabAnimationMode="slide">
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@ id/bottomNavigationBar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/transparent"
app:elevation="@dimen/my0dp"
app:menu="@menu/dash_board_nav_menu" />
</com.google.android.material.bottomappbar.BottomAppBar>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@ id/fba"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:hideOnScroll="true"
app:layout_anchor="@id/bottomAppBar"
app:layout_scrollFlags="scroll|enterAlways"
app:srcCompat="@drawable/ion" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
First Fragment of navHost(landing fragment) Layout: ( a simple list of products with search by name)
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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=".fragment.DashboardMainFragment">
<com.google.android.material.textfield.TextInputLayout
android:id="@ id/searchAutoCompleteTextLayout"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="@dimen/my10dp"
android:layout_weight="1"
android:hint="@string/search_product_hint"
app:boxStrokeColor="@color/auto_complete_text_input_layout_color"
app:endIconDrawable="@drawable/icon_clear"
app:endIconMode="clear_text"
app:endIconTint="@color/icon_tint_color"
app:layout_constraintEnd_toStartOf="@id/barCodeSearch"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.appcompat.widget.AppCompatAutoCompleteTextView
android:id="@ id/searchAutoCompleteText"
style="@style/Widget.MaterialComponents.AutoCompleteTextView.OutlinedBox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:background="@null"
android:drawableStart="@drawable/icon_search"
android:drawableTint="@color/icon_tint_color"
android:dropDownHeight="@dimen/my150dp"
android:imeOptions="actionDone"
android:inputType="textAutoComplete"
android:lines="1"
android:singleLine="true"
app:endIconMode="clear_text" />
</com.google.android.material.textfield.TextInputLayout>
<ImageView
android:id="@ id/image"
android:layout_width="@dimen/my50dp"
android:layout_height="@dimen/my50dp"
android:layout_margin="@dimen/my10dp"
android:layout_weight="0"
android:src="@drawable/image"
app:layout_constraintBottom_toBottomOf="@id/searchAutoCompleteTextLayout"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/searchAutoCompleteTextLayout"
app:tint="@color/icon_tint_color" />
<com.gotocodo.hanoty.customview.CustomRecyclerView
android:id="@ id/custom_recycler_view"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_margin="@dimen/my10dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/searchAutoCompleteTextLayout" />
</androidx.constraintlayout.widget.ConstraintLayout>
Note: there is no app logic(java code), just implementing UI. Note: CustomRecyclerView take only 15-20Ms on inflate
one question was repeating inside my mind: "material design/component developers care about performance ? or only the good look of design" (all my respect for them).
CodePudding user response:
I found a solution, combining "AsyncLayoutInflater" "ViewStub" to fix the performance (Inflate) issue, and a (optional) progress bar showing that we are loading data :D then hide it on callback.