1 /* 2 * Copyright (C) 2021 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.content.pm.PackageManager; 21 import android.os.Bundle; 22 import android.view.LayoutInflater; 23 import android.view.View; 24 import android.view.ViewGroup; 25 import android.widget.Toolbar; 26 27 import androidx.annotation.Nullable; 28 import androidx.fragment.app.FragmentActivity; 29 30 import com.android.settingslib.utils.BuildCompatUtils; 31 import com.android.settingslib.widget.R; 32 33 import com.google.android.material.appbar.AppBarLayout; 34 import com.google.android.material.appbar.CollapsingToolbarLayout; 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 CollapsingToolbarBaseActivity extends FragmentActivity { 41 42 private class DelegateCallback implements CollapsingToolbarDelegate.HostCallback { 43 @Nullable 44 @Override setActionBar(Toolbar toolbar)45 public ActionBar setActionBar(Toolbar toolbar) { 46 CollapsingToolbarBaseActivity.super.setActionBar(toolbar); 47 return CollapsingToolbarBaseActivity.super.getActionBar(); 48 } 49 50 @Override setOuterTitle(CharSequence title)51 public void setOuterTitle(CharSequence title) { 52 CollapsingToolbarBaseActivity.super.setTitle(title); 53 } 54 } 55 56 private CollapsingToolbarDelegate mToolbardelegate; 57 58 private int mCustomizeLayoutResId = 0; 59 60 @Override onCreate(@ullable Bundle savedInstanceState)61 protected void onCreate(@Nullable Bundle savedInstanceState) { 62 super.onCreate(savedInstanceState); 63 // for backward compatibility on R devices or wearable devices due to small device size. 64 if (mCustomizeLayoutResId > 0 && (!BuildCompatUtils.isAtLeastS() || isWatch())) { 65 super.setContentView(mCustomizeLayoutResId); 66 return; 67 } 68 69 View view = getToolbarDelegate().onCreateView(getLayoutInflater(), null); 70 super.setContentView(view); 71 } 72 73 @Override setContentView(int layoutResID)74 public void setContentView(int layoutResID) { 75 final ViewGroup parent = (mToolbardelegate == null) ? findViewById(R.id.content_frame) 76 : mToolbardelegate.getContentFrameLayout(); 77 if (parent != null) { 78 parent.removeAllViews(); 79 } 80 LayoutInflater.from(this).inflate(layoutResID, parent); 81 } 82 83 @Override setContentView(View view)84 public void setContentView(View view) { 85 final ViewGroup parent = (mToolbardelegate == null) ? findViewById(R.id.content_frame) 86 : mToolbardelegate.getContentFrameLayout(); 87 if (parent != null) { 88 parent.addView(view); 89 } 90 } 91 92 @Override setContentView(View view, ViewGroup.LayoutParams params)93 public void setContentView(View view, ViewGroup.LayoutParams params) { 94 final ViewGroup parent = (mToolbardelegate == null) ? findViewById(R.id.content_frame) 95 : mToolbardelegate.getContentFrameLayout(); 96 if (parent != null) { 97 parent.addView(view, params); 98 } 99 } 100 101 /** 102 * This method allows an activity to replace the default layout with a customize layout. Notice 103 * that it will no longer apply the features being provided by this class when this method 104 * gets called. 105 */ setCustomizeContentView(int layoutResId)106 protected void setCustomizeContentView(int layoutResId) { 107 mCustomizeLayoutResId = layoutResId; 108 } 109 110 @Override setTitle(CharSequence title)111 public void setTitle(CharSequence title) { 112 getToolbarDelegate().setTitle(title); 113 } 114 115 @Override setTitle(int titleId)116 public void setTitle(int titleId) { 117 setTitle(getText(titleId)); 118 } 119 120 @Override onNavigateUp()121 public boolean onNavigateUp() { 122 if (getSupportFragmentManager().getBackStackEntryCount() > 0) { 123 getSupportFragmentManager().popBackStackImmediate(); 124 } 125 126 // Closes the activity if there is no fragment inside the stack. Otherwise the activity will 127 // has a blank screen since there is no any fragment. 128 if (getSupportFragmentManager().getBackStackEntryCount() == 0) { 129 finishAfterTransition(); 130 } 131 return true; 132 } 133 134 @Override onBackPressed()135 public void onBackPressed() { 136 super.onBackPressed(); 137 138 // Closes the activity if there is no fragment inside the stack. Otherwise the activity will 139 // has a blank screen since there is no any fragment. onBackPressed() in Activity.java only 140 // handles popBackStackImmediate(). This will close activity to avoid a blank screen. 141 if (getSupportFragmentManager().getBackStackEntryCount() == 0) { 142 finishAfterTransition(); 143 } 144 } 145 146 /** 147 * Returns an instance of collapsing toolbar. 148 */ 149 @Nullable getCollapsingToolbarLayout()150 public CollapsingToolbarLayout getCollapsingToolbarLayout() { 151 return getToolbarDelegate().getCollapsingToolbarLayout(); 152 } 153 154 /** 155 * Return an instance of app bar. 156 */ 157 @Nullable getAppBarLayout()158 public AppBarLayout getAppBarLayout() { 159 return getToolbarDelegate().getAppBarLayout(); 160 } 161 isWatch()162 private boolean isWatch() { 163 PackageManager packageManager = getPackageManager(); 164 if (packageManager == null) { 165 return false; 166 } 167 return packageManager.hasSystemFeature(PackageManager.FEATURE_WATCH); 168 } 169 getToolbarDelegate()170 private CollapsingToolbarDelegate getToolbarDelegate() { 171 if (mToolbardelegate == null) { 172 mToolbardelegate = new CollapsingToolbarDelegate(new DelegateCallback()); 173 } 174 return mToolbardelegate; 175 } 176 } 177