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.google.android.setupdesign.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.google.android.setupdesign.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.google.android.setupdesign.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 { 46 void onNavigateBack(); 47 48 void onNavigateNext(); 49 } 50 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 sudNavBarTheme. 54 TypedArray attributes = 55 context.obtainStyledAttributes( 56 new int[] { 57 R.attr.sudNavBarTheme, android.R.attr.colorForeground, android.R.attr.colorBackground 58 }); 59 @StyleableRes int navBarTheme = 0; 60 @StyleableRes int colorForeground = 1; 61 @StyleableRes int colorBackground = 2; 62 int theme = attributes.getResourceId(navBarTheme, 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.SudNavBarThemeDark : R.style.SudNavBarThemeLight; 72 } 73 attributes.recycle(); 74 return theme; 75 } 76 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 87 public NavigationBar(Context context) { 88 super(getThemedContext(context)); 89 init(); 90 } 91 92 public NavigationBar(Context context, AttributeSet attrs) { 93 super(getThemedContext(context), attrs); 94 init(); 95 } 96 97 @TargetApi(VERSION_CODES.HONEYCOMB) 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. 105 private void init() { 106 View.inflate(getContext(), R.layout.sud_navbar_view, this); 107 nextButton = (Button) findViewById(R.id.sud_navbar_next); 108 backButton = (Button) findViewById(R.id.sud_navbar_back); 109 moreButton = (Button) findViewById(R.id.sud_navbar_more); 110 } 111 112 public Button getBackButton() { 113 return backButton; 114 } 115 116 public Button getNextButton() { 117 return nextButton; 118 } 119 120 public Button getMoreButton() { 121 return moreButton; 122 } 123 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 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