1 /*
2  * Copyright (C) 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.settingslib.collapsingtoolbar;
18 
19 import android.app.ActionBar;
20 import android.os.Bundle;
21 import android.view.LayoutInflater;
22 import android.view.View;
23 import android.view.ViewGroup;
24 import android.widget.Toolbar;
25 
26 import androidx.annotation.Nullable;
27 import androidx.appcompat.app.AppCompatActivity;
28 
29 import com.android.settingslib.utils.BuildCompatUtils;
30 import com.android.settingslib.widget.R;
31 
32 import com.google.android.material.appbar.AppBarLayout;
33 import com.google.android.material.appbar.CollapsingToolbarLayout;
34 import com.google.android.material.color.DynamicColors;
35 
36 /**
37  * A base Activity that has a collapsing toolbar layout is used for the activities intending to
38  * enable the collapsing toolbar function.
39  */
40 public class CollapsingToolbarAppCompatActivity extends AppCompatActivity {
41 
42     private class DelegateCallback implements CollapsingToolbarDelegate.HostCallback {
43         @Nullable
44         @Override
setActionBar(Toolbar toolbar)45         public ActionBar setActionBar(Toolbar toolbar) {
46             return null;
47         }
48 
49         @Nullable
50         @Override
setActionBar( androidx.appcompat.widget.Toolbar toolbar)51         public androidx.appcompat.app.ActionBar setActionBar(
52                 androidx.appcompat.widget.Toolbar toolbar) {
53             CollapsingToolbarAppCompatActivity.super.setSupportActionBar(toolbar);
54             return CollapsingToolbarAppCompatActivity.super.getSupportActionBar();
55         }
56 
57         @Override
setOuterTitle(CharSequence title)58         public void setOuterTitle(CharSequence title) {
59             CollapsingToolbarAppCompatActivity.super.setTitle(title);
60         }
61     }
62 
63     private CollapsingToolbarDelegate mToolbardelegate;
64 
65     private int mCustomizeLayoutResId = 0;
66 
67     @Override
onCreate(@ullable Bundle savedInstanceState)68     protected void onCreate(@Nullable Bundle savedInstanceState) {
69         super.onCreate(savedInstanceState);
70         if (BuildCompatUtils.isAtLeastS()) {
71             DynamicColors.applyToActivityIfAvailable(this);
72         }
73         setTheme(R.style.Theme_SubSettingsBase);
74 
75         if (mCustomizeLayoutResId > 0 && !BuildCompatUtils.isAtLeastS()) {
76             super.setContentView(mCustomizeLayoutResId);
77             return;
78         }
79 
80         View view = getToolbarDelegate().onCreateView(getLayoutInflater(), null, this);
81         super.setContentView(view);
82     }
83 
84     @Override
setContentView(int layoutResID)85     public void setContentView(int layoutResID) {
86         final ViewGroup parent = (mToolbardelegate == null) ? findViewById(R.id.content_frame)
87                 : mToolbardelegate.getContentFrameLayout();
88         if (parent != null) {
89             parent.removeAllViews();
90         }
91         LayoutInflater.from(this).inflate(layoutResID, parent);
92     }
93 
94     @Override
setContentView(View view)95     public void setContentView(View view) {
96         final ViewGroup parent = (mToolbardelegate == null) ? findViewById(R.id.content_frame)
97                 : mToolbardelegate.getContentFrameLayout();
98         if (parent != null) {
99             parent.addView(view);
100         }
101     }
102 
103     @Override
setContentView(View view, ViewGroup.LayoutParams params)104     public void setContentView(View view, ViewGroup.LayoutParams params) {
105         final ViewGroup parent = (mToolbardelegate == null) ? findViewById(R.id.content_frame)
106                 : mToolbardelegate.getContentFrameLayout();
107         if (parent != null) {
108             parent.addView(view, params);
109         }
110     }
111 
112     /**
113      * This method allows an activity to replace the default layout with a customize layout. Notice
114      * that it will no longer apply the features being provided by this class when this method
115      * gets called.
116      */
setCustomizeContentView(int layoutResId)117     protected void setCustomizeContentView(int layoutResId) {
118         mCustomizeLayoutResId = layoutResId;
119     }
120 
121     @Override
setTitle(CharSequence title)122     public void setTitle(CharSequence title) {
123         getToolbarDelegate().setTitle(title);
124     }
125 
126     @Override
setTitle(int titleId)127     public void setTitle(int titleId) {
128         setTitle(getText(titleId));
129     }
130 
131     @Override
onSupportNavigateUp()132     public boolean onSupportNavigateUp() {
133         if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
134             getSupportFragmentManager().popBackStackImmediate();
135         }
136 
137         // Closes the activity if there is no fragment inside the stack. Otherwise the activity will
138         // has a blank screen since there is no any fragment.
139         if (getSupportFragmentManager().getBackStackEntryCount() == 0) {
140             finishAfterTransition();
141         }
142         return true;
143     }
144 
145     @Override
onBackPressed()146     public void onBackPressed() {
147         super.onBackPressed();
148 
149         // Closes the activity if there is no fragment inside the stack. Otherwise the activity will
150         // has a blank screen since there is no any fragment. onBackPressed() in Activity.java only
151         // handles popBackStackImmediate(). This will close activity to avoid a blank screen.
152         if (getSupportFragmentManager().getBackStackEntryCount() == 0) {
153             finishAfterTransition();
154         }
155     }
156 
157     /**
158      * Returns an instance of collapsing toolbar.
159      */
160     @Nullable
getCollapsingToolbarLayout()161     public CollapsingToolbarLayout getCollapsingToolbarLayout() {
162         return getToolbarDelegate().getCollapsingToolbarLayout();
163     }
164 
165     /**
166      * Return an instance of app bar.
167      */
168     @Nullable
getAppBarLayout()169     public AppBarLayout getAppBarLayout() {
170         return getToolbarDelegate().getAppBarLayout();
171     }
172 
getToolbarDelegate()173     private CollapsingToolbarDelegate getToolbarDelegate() {
174         if (mToolbardelegate == null) {
175             mToolbardelegate = new CollapsingToolbarDelegate(new DelegateCallback());
176         }
177         return mToolbardelegate;
178     }
179 }
180