| /* |
| * Copyright (C) 2014 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.android.setupwizard.navigationbar; |
| |
| import android.app.Activity; |
| import android.app.Fragment; |
| import android.content.Context; |
| import android.content.res.TypedArray; |
| import android.graphics.Color; |
| import android.os.Bundle; |
| import android.util.AttributeSet; |
| import android.view.ContextThemeWrapper; |
| import android.view.LayoutInflater; |
| import android.view.View; |
| import android.view.View.OnClickListener; |
| import android.view.ViewGroup; |
| import android.view.ViewTreeObserver; |
| import android.view.ViewTreeObserver.OnPreDrawListener; |
| import android.widget.Button; |
| |
| /** |
| * Fragment class for controlling the custom navigation bar shown during setup wizard. Apps in the |
| * Android tree can use this by including the common.mk makefile. Apps outside of the tree can |
| * create a library project out of the source. |
| */ |
| public class SetupWizardNavBar extends Fragment implements OnPreDrawListener, OnClickListener { |
| private static final String TAG = "SetupWizardNavBar"; |
| private static final int IMMERSIVE_FLAGS = |
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY; |
| private int mSystemUiFlags = IMMERSIVE_FLAGS | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION; |
| |
| private ViewGroup mNavigationBarView; |
| private Button mNextButton; |
| private Button mBackButton; |
| private NavigationBarListener mCallback; |
| |
| public interface NavigationBarListener { |
| public void onNavigationBarCreated(SetupWizardNavBar bar); |
| public void onNavigateBack(); |
| public void onNavigateNext(); |
| } |
| |
| public SetupWizardNavBar() { |
| // no-arg constructor for fragments |
| } |
| |
| @Override |
| public void onAttach(Activity activity) { |
| super.onAttach(activity); |
| mCallback = (NavigationBarListener) activity; |
| } |
| |
| @Override |
| public View onCreateView(LayoutInflater inflater, ViewGroup container, |
| Bundle savedInstanceState) { |
| Context context = new ContextThemeWrapper(getActivity(), getNavbarTheme()); |
| inflater = LayoutInflater.from(context); |
| mNavigationBarView = (ViewGroup) inflater.inflate(R.layout.setup_wizard_navbar_layout, |
| container, false); |
| mNextButton = (Button) mNavigationBarView.findViewById(R.id.setup_wizard_navbar_next); |
| mBackButton = (Button) mNavigationBarView.findViewById(R.id.setup_wizard_navbar_back); |
| mNextButton.setOnClickListener(this); |
| mBackButton.setOnClickListener(this); |
| return mNavigationBarView; |
| } |
| |
| @Override |
| public void onViewCreated(View view, Bundle savedInstanceState) { |
| super.onViewCreated(view, savedInstanceState); |
| mCallback.onNavigationBarCreated(this); |
| mNavigationBarView.setSystemUiVisibility(mSystemUiFlags); |
| |
| // Set the UI flags before draw because the visibility might change in unexpected / |
| // undetectable times, like transitioning from a finishing activity that had a keyboard |
| ViewTreeObserver viewTreeObserver = mNavigationBarView.getViewTreeObserver(); |
| viewTreeObserver.addOnPreDrawListener(this); |
| } |
| |
| @Override |
| public boolean onPreDraw() { |
| // View.setSystemUiVisibility checks if the visibility changes before applying them |
| // so the performance impact is contained |
| mNavigationBarView.setSystemUiVisibility(mSystemUiFlags); |
| return true; |
| } |
| |
| /** |
| * Sets whether system navigation bar should be hidden. |
| * @param useImmersiveMode True to activate immersive mode and hide the system navigation bar |
| */ |
| public void setUseImmersiveMode(boolean useImmersiveMode) { |
| // By default, enable layoutHideNavigation if immersive mode is used |
| setUseImmersiveMode(useImmersiveMode, useImmersiveMode); |
| } |
| |
| public void setUseImmersiveMode(boolean useImmersiveMode, boolean layoutHideNavigation) { |
| if (useImmersiveMode) { |
| mSystemUiFlags |= IMMERSIVE_FLAGS; |
| if (layoutHideNavigation) { |
| mSystemUiFlags |= View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION; |
| } |
| } else { |
| mSystemUiFlags &= ~(IMMERSIVE_FLAGS | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION); |
| } |
| mNavigationBarView.setSystemUiVisibility(mSystemUiFlags); |
| } |
| |
| private int getNavbarTheme() { |
| // Normally we can automatically guess the theme by comparing the foreground color against |
| // the background color. But we also allow specifying explicitly using |
| // setup_wizard_navbar_theme. |
| TypedArray attributes = getActivity().obtainStyledAttributes( |
| new int[] { |
| R.attr.setup_wizard_navbar_theme, |
| android.R.attr.colorForeground, |
| android.R.attr.colorBackground }); |
| int theme = attributes.getResourceId(0, 0); |
| if (theme == 0) { |
| // Compare the value of the foreground against the background color to see if current |
| // theme is light-on-dark or dark-on-light. |
| float[] foregroundHsv = new float[3]; |
| float[] backgroundHsv = new float[3]; |
| Color.colorToHSV(attributes.getColor(1, 0), foregroundHsv); |
| Color.colorToHSV(attributes.getColor(2, 0), backgroundHsv); |
| boolean isDarkBg = foregroundHsv[2] > backgroundHsv[2]; |
| theme = isDarkBg ? R.style.setup_wizard_navbar_theme_dark : |
| R.style.setup_wizard_navbar_theme_light; |
| } |
| attributes.recycle(); |
| return theme; |
| } |
| |
| @Override |
| public void onClick(View v) { |
| if (v == mBackButton) { |
| mCallback.onNavigateBack(); |
| } else if (v == mNextButton) { |
| mCallback.onNavigateNext(); |
| } |
| } |
| |
| public Button getBackButton() { |
| return mBackButton; |
| } |
| |
| public Button getNextButton() { |
| return mNextButton; |
| } |
| |
| public static class NavButton extends Button { |
| |
| public NavButton(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { |
| super(context, attrs, defStyleAttr, defStyleRes); |
| } |
| |
| public NavButton(Context context, AttributeSet attrs, int defStyleAttr) { |
| super(context, attrs, defStyleAttr); |
| } |
| |
| public NavButton(Context context, AttributeSet attrs) { |
| super(context, attrs); |
| } |
| |
| public NavButton(Context context) { |
| super(context); |
| } |
| |
| @Override |
| public void setEnabled(boolean enabled) { |
| super.setEnabled(enabled); |
| // The color of the button is #de000000 / #deffffff when enabled. When disabled, apply |
| // additional 23% alpha, so the overall opacity is 20%. |
| setAlpha(enabled ? 1.0f : 0.23f); |
| } |
| } |
| |
| } |