44
44
import android .view .LayoutInflater ;
45
45
import android .view .View ;
46
46
import android .view .ViewGroup ;
47
+ import android .view .ViewParent ;
47
48
import android .view .accessibility .AccessibilityNodeInfo ;
48
49
import android .widget .EditText ;
49
50
import android .widget .ImageButton ;
63
64
import androidx .core .widget .TextViewCompat ;
64
65
import androidx .customview .view .AbsSavedState ;
65
66
import com .google .android .material .appbar .AppBarLayout ;
67
+ import com .google .android .material .appbar .AppBarLayout .LiftOnScrollProgressListener ;
66
68
import com .google .android .material .color .MaterialColors ;
67
69
import com .google .android .material .internal .ThemeEnforcement ;
68
70
import com .google .android .material .internal .ToolbarUtils ;
71
+ import com .google .android .material .resources .MaterialResources ;
69
72
import com .google .android .material .shape .MaterialShapeDrawable ;
70
73
import com .google .android .material .shape .MaterialShapeUtils ;
71
74
import com .google .android .material .shape .ShapeAppearanceModel ;
@@ -132,6 +135,10 @@ public class SearchBar extends Toolbar {
132
135
private static final String NAMESPACE_APP = "http://schemas.android.com/apk/res-auto" ;
133
136
134
137
private final TextView textView ;
138
+ private final int backgroundColor ;
139
+
140
+ private boolean liftOnScroll ;
141
+ @ Nullable private final ColorStateList liftOnScrollColor ;
135
142
private final boolean layoutInflated ;
136
143
private final boolean defaultMarginsEnabled ;
137
144
private final SearchBarAnimationHelper searchBarAnimationHelper ;
@@ -148,6 +155,19 @@ public class SearchBar extends Toolbar {
148
155
private MaterialShapeDrawable backgroundShape ;
149
156
private boolean textCentered ;
150
157
158
+ private final LiftOnScrollProgressListener liftColorListener =
159
+ new LiftOnScrollProgressListener () {
160
+
161
+ @ Override
162
+ public void onUpdate (float elevation , int appBarLayoutColor , float progress ) {
163
+ if (liftOnScrollColor != null ) {
164
+ int mixedColor =
165
+ MaterialColors .layer (backgroundColor , liftOnScrollColor .getDefaultColor (), progress );
166
+ backgroundShape .setFillColor (ColorStateList .valueOf (mixedColor ));
167
+ }
168
+ }
169
+ };
170
+
151
171
public SearchBar (@ NonNull Context context ) {
152
172
this (context , null );
153
173
}
@@ -175,7 +195,9 @@ public SearchBar(@NonNull Context context, @Nullable AttributeSet attrs, int def
175
195
176
196
ShapeAppearanceModel shapeAppearanceModel =
177
197
ShapeAppearanceModel .builder (context , attrs , defStyleAttr , DEF_STYLE_RES ).build ();
178
- int backgroundColor = a .getColor (R .styleable .SearchBar_backgroundTint , 0 );
198
+ backgroundColor = a .getColor (R .styleable .SearchBar_backgroundTint , 0 );
199
+ liftOnScrollColor =
200
+ MaterialResources .getColorStateList (context , a , R .styleable .SearchBar_liftOnScrollColor );
179
201
float elevation = a .getDimension (R .styleable .SearchBar_elevation , 0 );
180
202
defaultMarginsEnabled = a .getBoolean (R .styleable .SearchBar_defaultMarginsEnabled , true );
181
203
defaultScrollFlagsEnabled = a .getBoolean (R .styleable .SearchBar_defaultScrollFlagsEnabled , true );
@@ -192,6 +214,7 @@ public SearchBar(@NonNull Context context, @Nullable AttributeSet attrs, int def
192
214
float strokeWidth = a .getDimension (R .styleable .SearchBar_strokeWidth , -1 );
193
215
int strokeColor = a .getColor (R .styleable .SearchBar_strokeColor , Color .TRANSPARENT );
194
216
textCentered = a .getBoolean (R .styleable .SearchBar_textCentered , false );
217
+ liftOnScroll = a .getBoolean (R .styleable .SearchBar_liftOnScroll , false );
195
218
196
219
a .recycle ();
197
220
@@ -225,6 +248,18 @@ private void validateAttributes(@Nullable AttributeSet attributeSet) {
225
248
}
226
249
}
227
250
251
+ @ Nullable
252
+ private AppBarLayout getAppBarLayoutParentIfExists () {
253
+ ViewParent v = getParent ();
254
+ while (v != null ) {
255
+ if (v instanceof AppBarLayout ) {
256
+ return (AppBarLayout ) v ;
257
+ }
258
+ v = v .getParent ();
259
+ }
260
+ return null ;
261
+ }
262
+
228
263
private void initNavigationIcon () {
229
264
// If no navigation icon, set up the default one; otherwise, re-set it for tinting if needed.
230
265
setNavigationIcon (getNavigationIcon () == null ? defaultNavigationIcon : getNavigationIcon ());
@@ -417,13 +452,56 @@ private int getNewMargin(int currentMargin) {
417
452
return additionalMarginStart ;
418
453
}
419
454
455
+ /**
456
+ * Sets whether the {@link SearchBar} lifts when a parent {@link AppBarLayout} lifts on scroll.
457
+ */
458
+ public void setLiftOnScroll (boolean liftOnScroll ) {
459
+ this .liftOnScroll = liftOnScroll ;
460
+ if (liftOnScroll ) {
461
+ addLiftOnScrollProgressListener ();
462
+ } else {
463
+ removeLiftOnScrollProgressListener ();
464
+ }
465
+ }
466
+
467
+ /**
468
+ * Returns whether or not the {@link SearchBar} lifts when a parent {@link AppBarLayout} lifts
469
+ * on scroll.
470
+ */
471
+ public boolean isLiftOnScroll () {
472
+ return liftOnScroll ;
473
+ }
474
+
475
+ private void addLiftOnScrollProgressListener () {
476
+ AppBarLayout appBarLayout = getAppBarLayoutParentIfExists ();
477
+ if (appBarLayout != null && liftOnScrollColor != null ) {
478
+ appBarLayout .addLiftOnScrollProgressListener (liftColorListener );
479
+ }
480
+ }
481
+
482
+ private void removeLiftOnScrollProgressListener () {
483
+ AppBarLayout appBarLayout = getAppBarLayoutParentIfExists ();
484
+ if (appBarLayout != null ) {
485
+ appBarLayout .removeLiftOnScrollProgressListener (liftColorListener );
486
+ }
487
+ }
488
+
420
489
@ Override
421
490
protected void onAttachedToWindow () {
422
491
super .onAttachedToWindow ();
423
492
424
493
MaterialShapeUtils .setParentAbsoluteElevation (this , backgroundShape );
425
494
setDefaultMargins ();
426
495
setOrClearDefaultScrollFlags ();
496
+ if (liftOnScroll ) {
497
+ addLiftOnScrollProgressListener ();
498
+ }
499
+ }
500
+
501
+ @ Override
502
+ protected void onDetachedFromWindow () {
503
+ super .onDetachedFromWindow ();
504
+ removeLiftOnScrollProgressListener ();
427
505
}
428
506
429
507
/**
0 commit comments