ViewBindingAdapter.java revision c7cd9c61e55b43b712d20f855ca59d6fbc49e5b1
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 */ 16package android.databinding.adapters; 17 18import android.annotation.TargetApi; 19import android.databinding.BindingAdapter; 20import android.databinding.BindingMethod; 21import android.databinding.BindingMethods; 22import android.os.Build; 23import android.os.Build.VERSION; 24import android.os.Build.VERSION_CODES; 25import android.view.View; 26import android.view.View.OnAttachStateChangeListener; 27import com.android.databinding.library.baseAdapters.R; 28 29@BindingMethods({ 30 @BindingMethod(type = View.class, attribute = "android:backgroundTint", method = "setBackgroundTintList"), 31 @BindingMethod(type = View.class, attribute = "android:fadeScrollbars", method = "setScrollbarFadingEnabled"), 32 @BindingMethod(type = View.class, attribute = "android:getOutline", method = "setOutlineProvider"), 33 @BindingMethod(type = View.class, attribute = "android:nextFocusForward", method = "setNextFocusForwardId"), 34 @BindingMethod(type = View.class, attribute = "android:nextFocusLeft", method = "setNextFocusLeftId"), 35 @BindingMethod(type = View.class, attribute = "android:nextFocusRight", method = "setNextFocusRightId"), 36 @BindingMethod(type = View.class, attribute = "android:nextFocusUp", method = "setNextFocusUpId"), 37 @BindingMethod(type = View.class, attribute = "android:nextFocusDown", method = "setNextFocusDownId"), 38 @BindingMethod(type = View.class, attribute = "android:requiresFadingEdge", method = "setVerticalFadingEdgeEnabled"), 39 @BindingMethod(type = View.class, attribute = "android:scrollbarDefaultDelayBeforeFade", method = "setScrollBarDefaultDelayBeforeFade"), 40 @BindingMethod(type = View.class, attribute = "android:scrollbarFadeDuration", method = "setScrollBarFadeDuration"), 41 @BindingMethod(type = View.class, attribute = "android:scrollbarSize", method = "setScrollBarSize"), 42 @BindingMethod(type = View.class, attribute = "android:scrollbarStyle", method = "setScrollBarStyle"), 43 @BindingMethod(type = View.class, attribute = "android:transformPivotX", method = "setPivotX"), 44 @BindingMethod(type = View.class, attribute = "android:transformPivotY", method = "setPivotY"), 45 @BindingMethod(type = View.class, attribute = "android:onDrag", method = "setOnDragListener"), 46 @BindingMethod(type = View.class, attribute = "android:onClick", method = "setOnClickListener"), 47 @BindingMethod(type = View.class, attribute = "android:onApplyWindowInsets", method = "setOnApplyWindowInsetsListener"), 48 @BindingMethod(type = View.class, attribute = "android:onCreateContextMenu", method = "setOnCreateContextMenuListener"), 49 @BindingMethod(type = View.class, attribute = "android:onFocusChange", method = "setOnFocusChangeListener"), 50 @BindingMethod(type = View.class, attribute = "android:onGenericMotion", method = "setOnGenericMotionListener"), 51 @BindingMethod(type = View.class, attribute = "android:onHover", method = "setOnHoverListener"), 52 @BindingMethod(type = View.class, attribute = "android:onKey", method = "setOnKeyListener"), 53 @BindingMethod(type = View.class, attribute = "android:onLongClick", method = "setOnLongClickListener"), 54 @BindingMethod(type = View.class, attribute = "android:onSystemUiVisibilityChange", method = "setOnSystemUiVisibilityChangeListener"), 55 @BindingMethod(type = View.class, attribute = "android:onTouch", method = "setOnTouchListener"), 56}) 57public class ViewBindingAdapter { 58 public static int FADING_EDGE_NONE = 0; 59 public static int FADING_EDGE_HORIZONTAL = 1; 60 public static int FADING_EDGE_VERTICAL = 2; 61 62 @BindingAdapter({"android:padding"}) 63 public static void setPadding(View view, float paddingFloat) { 64 final int padding = pixelsToDimensionPixelSize(paddingFloat); 65 view.setPadding(padding, padding, padding, padding); 66 } 67 68 @BindingAdapter({"android:paddingBottom"}) 69 public static void setPaddingBottom(View view, float paddingFloat) { 70 final int padding = pixelsToDimensionPixelSize(paddingFloat); 71 view.setPadding(view.getPaddingLeft(), view.getPaddingTop(), view.getPaddingRight(), 72 padding); 73 } 74 75 @BindingAdapter({"android:paddingEnd"}) 76 public static void setPaddingEnd(View view, float paddingFloat) { 77 final int padding = pixelsToDimensionPixelSize(paddingFloat); 78 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { 79 view.setPaddingRelative(view.getPaddingStart(), view.getPaddingTop(), padding, 80 view.getPaddingBottom()); 81 } else { 82 view.setPadding(view.getPaddingLeft(), view.getPaddingTop(), padding, 83 view.getPaddingBottom()); 84 } 85 } 86 87 @BindingAdapter({"android:paddingLeft"}) 88 public static void setPaddingLeft(View view, float paddingFloat) { 89 final int padding = pixelsToDimensionPixelSize(paddingFloat); 90 view.setPadding(padding, view.getPaddingTop(), view.getPaddingRight(), 91 view.getPaddingBottom()); 92 } 93 94 @BindingAdapter({"android:paddingRight"}) 95 public static void setPaddingRight(View view, float paddingFloat) { 96 final int padding = pixelsToDimensionPixelSize(paddingFloat); 97 view.setPadding(view.getPaddingLeft(), view.getPaddingTop(), padding, 98 view.getPaddingBottom()); 99 } 100 101 @BindingAdapter({"android:paddingStart"}) 102 public static void setPaddingStart(View view, float paddingFloat) { 103 final int padding = pixelsToDimensionPixelSize(paddingFloat); 104 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { 105 view.setPaddingRelative(padding, view.getPaddingTop(), view.getPaddingEnd(), 106 view.getPaddingBottom()); 107 } else { 108 view.setPadding(padding, view.getPaddingTop(), view.getPaddingRight(), 109 view.getPaddingBottom()); 110 } 111 } 112 113 @BindingAdapter({"android:paddingTop"}) 114 public static void setPaddingTop(View view, float paddingFloat) { 115 final int padding = pixelsToDimensionPixelSize(paddingFloat); 116 view.setPadding(view.getPaddingLeft(), padding, view.getPaddingRight(), 117 view.getPaddingBottom()); 118 } 119 120 @BindingAdapter({"android:requiresFadingEdge"}) 121 public static void setRequiresFadingEdge(View view, int value) { 122 final boolean vertical = (value & FADING_EDGE_VERTICAL) != 0; 123 final boolean horizontal = (value & FADING_EDGE_HORIZONTAL) != 0; 124 view.setVerticalFadingEdgeEnabled(vertical); 125 view.setHorizontalFadingEdgeEnabled(horizontal); 126 } 127 128 @BindingAdapter({"android:onClickListener", "android:clickable"}) 129 public static void setClickListener(View view, View.OnClickListener clickListener, 130 boolean clickable) { 131 view.setOnClickListener(clickListener); 132 view.setClickable(clickable); 133 } 134 135 @BindingAdapter({"android:onClick", "android:clickable"}) 136 public static void setOnClick(View view, View.OnClickListener clickListener, 137 boolean clickable) { 138 view.setOnClickListener(clickListener); 139 view.setClickable(clickable); 140 } 141 142 @BindingAdapter({"android:onLongClickListener", "android:longClickable"}) 143 public static void setOnLongClickListener(View view, View.OnLongClickListener clickListener, 144 boolean clickable) { 145 view.setOnLongClickListener(clickListener); 146 view.setLongClickable(clickable); 147 } 148 149 @BindingAdapter({"android:onLongClick", "android:longClickable"}) 150 public static void setOnLongClick(View view, View.OnLongClickListener clickListener, 151 boolean clickable) { 152 view.setOnLongClickListener(clickListener); 153 view.setLongClickable(clickable); 154 } 155 156 @BindingAdapter(value = {"android:onViewDetachedFromWindow", "android:onViewAttachedToWindow"}, 157 requireAll = false) 158 public static void setOnAttachStateChangeListener(View view, 159 final OnViewDetachedFromWindow detach, final OnViewAttachedToWindow attach) { 160 if (VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB_MR1) { 161 final OnAttachStateChangeListener newListener; 162 if (detach == null && attach == null) { 163 newListener = null; 164 } else { 165 newListener = new OnAttachStateChangeListener() { 166 @Override 167 public void onViewAttachedToWindow(View v) { 168 if (attach != null) { 169 attach.onViewAttachedToWindow(v); 170 } 171 } 172 173 @Override 174 public void onViewDetachedFromWindow(View v) { 175 if (detach != null) { 176 detach.onViewDetachedFromWindow(v); 177 } 178 } 179 }; 180 } 181 final OnAttachStateChangeListener oldListener = ListenerUtil.trackListener(view, 182 newListener, R.id.onAttachStateChangeListener); 183 if (oldListener != null) { 184 view.removeOnAttachStateChangeListener(oldListener); 185 } 186 if (newListener != null) { 187 view.addOnAttachStateChangeListener(newListener); 188 } 189 } 190 } 191 192 @BindingAdapter("android:onLayoutChange") 193 public static void setOnLayoutChangeListener(View view, View.OnLayoutChangeListener oldValue, 194 View.OnLayoutChangeListener newValue) { 195 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { 196 if (oldValue != null) { 197 view.removeOnLayoutChangeListener(oldValue); 198 } 199 if (newValue != null) { 200 view.addOnLayoutChangeListener(newValue); 201 } 202 } 203 } 204 205 // Follows the same conversion mechanism as in TypedValue.complexToDimensionPixelSize as used 206 // when setting padding. It rounds off the float value unless the value is < 1. 207 // When a value is between 0 and 1, it is set to 1. A value less than 0 is set to -1. 208 private static int pixelsToDimensionPixelSize(float pixels) { 209 final int result = (int) (pixels + 0.5f); 210 if (result != 0) { 211 return result; 212 } else if (pixels == 0) { 213 return 0; 214 } else if (pixels > 0) { 215 return 1; 216 } else { 217 return -1; 218 } 219 } 220 221 @TargetApi(VERSION_CODES.HONEYCOMB_MR1) 222 public interface OnViewDetachedFromWindow { 223 void onViewDetachedFromWindow(View v); 224 } 225 226 @TargetApi(VERSION_CODES.HONEYCOMB_MR1) 227 public interface OnViewAttachedToWindow { 228 void onViewAttachedToWindow(View v); 229 } 230} 231