1 /* 2 * Copyright (C) 2015 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.setupwizardlib.view; 18 19 import android.annotation.TargetApi; 20 import android.content.Context; 21 import android.content.res.TypedArray; 22 import android.graphics.Color; 23 import android.os.Build.VERSION_CODES; 24 import androidx.annotation.StyleableRes; 25 import android.util.AttributeSet; 26 import android.view.ContextThemeWrapper; 27 import android.view.View; 28 import android.widget.Button; 29 import android.widget.LinearLayout; 30 import com.android.setupwizardlib.R; 31 32 /** 33 * Custom navigation bar for use with setup wizard. This bar contains a back button, more button and 34 * next button. By default, the more button is hidden, and typically the next button will be hidden 35 * if the more button is shown. 36 * 37 * @see com.android.setupwizardlib.template.RequireScrollMixin 38 */ 39 public class NavigationBar extends LinearLayout implements View.OnClickListener { 40 41 /** 42 * An interface to listen to events of the navigation bar, namely when the user clicks on the back 43 * or next button. 44 */ 45 public interface NavigationBarListener { onNavigateBack()46 void onNavigateBack(); 47 onNavigateNext()48 void onNavigateNext(); 49 } 50 getNavbarTheme(Context context)51 private static int getNavbarTheme(Context context) { 52 // Normally we can automatically guess the theme by comparing the foreground color against 53 // the background color. But we also allow specifying explicitly using suwNavBarTheme. 54 TypedArray attributes = 55 context.obtainStyledAttributes( 56 new int[] { 57 R.attr.suwNavBarTheme, android.R.attr.colorForeground, android.R.attr.colorBackground 58 }); 59 @StyleableRes int suwNavBarTheme = 0; 60 @StyleableRes int colorForeground = 1; 61 @StyleableRes int colorBackground = 2; 62 int theme = attributes.getResourceId(suwNavBarTheme, 0); 63 if (theme == 0) { 64 // Compare the value of the foreground against the background color to see if current 65 // theme is light-on-dark or dark-on-light. 66 float[] foregroundHsv = new float[3]; 67 float[] backgroundHsv = new float[3]; 68 Color.colorToHSV(attributes.getColor(colorForeground, 0), foregroundHsv); 69 Color.colorToHSV(attributes.getColor(colorBackground, 0), backgroundHsv); 70 boolean isDarkBg = foregroundHsv[2] > backgroundHsv[2]; 71 theme = isDarkBg ? R.style.SuwNavBarThemeDark : R.style.SuwNavBarThemeLight; 72 } 73 attributes.recycle(); 74 return theme; 75 } 76 getThemedContext(Context context)77 private static Context getThemedContext(Context context) { 78 final int theme = getNavbarTheme(context); 79 return new ContextThemeWrapper(context, theme); 80 } 81 82 private Button nextButton; 83 private Button backButton; 84 private Button moreButton; 85 private NavigationBarListener listener; 86 NavigationBar(Context context)87 public NavigationBar(Context context) { 88 super(getThemedContext(context)); 89 init(); 90 } 91 NavigationBar(Context context, AttributeSet attrs)92 public NavigationBar(Context context, AttributeSet attrs) { 93 super(getThemedContext(context), attrs); 94 init(); 95 } 96 97 @TargetApi(VERSION_CODES.HONEYCOMB) NavigationBar(Context context, AttributeSet attrs, int defStyleAttr)98 public NavigationBar(Context context, AttributeSet attrs, int defStyleAttr) { 99 super(getThemedContext(context), attrs, defStyleAttr); 100 init(); 101 } 102 103 // All the constructors delegate to this init method. The 3-argument constructor is not 104 // available in LinearLayout before v11, so call super with the exact same arguments. init()105 private void init() { 106 View.inflate(getContext(), R.layout.suw_navbar_view, this); 107 nextButton = (Button) findViewById(R.id.suw_navbar_next); 108 backButton = (Button) findViewById(R.id.suw_navbar_back); 109 moreButton = (Button) findViewById(R.id.suw_navbar_more); 110 } 111 getBackButton()112 public Button getBackButton() { 113 return backButton; 114 } 115 getNextButton()116 public Button getNextButton() { 117 return nextButton; 118 } 119 getMoreButton()120 public Button getMoreButton() { 121 return moreButton; 122 } 123 setNavigationBarListener(NavigationBarListener listener)124 public void setNavigationBarListener(NavigationBarListener listener) { 125 this.listener = listener; 126 if (this.listener != null) { 127 getBackButton().setOnClickListener(this); 128 getNextButton().setOnClickListener(this); 129 } 130 } 131 132 @Override onClick(View view)133 public void onClick(View view) { 134 if (listener != null) { 135 if (view == getBackButton()) { 136 listener.onNavigateBack(); 137 } else if (view == getNextButton()) { 138 listener.onNavigateNext(); 139 } 140 } 141 } 142 } 143