1/* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 * in compliance with the License. You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software distributed under the License 10 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 * or implied. See the License for the specific language governing permissions and limitations under 12 * the License. 13 */ 14 15package android.support.v17.leanback.widget; 16 17import static android.support.v7.widget.RecyclerView.HORIZONTAL; 18import static android.support.v7.widget.RecyclerView.VERTICAL; 19import static android.support.v17.leanback.widget.BaseGridView.ITEM_ALIGN_OFFSET_PERCENT_DISABLED; 20 21import android.graphics.Rect; 22import android.support.v17.leanback.widget.GridLayoutManager.LayoutParams; 23import android.view.View; 24import android.view.ViewGroup; 25 26/** 27 * Defines alignment position on two directions of an item view. Typically item 28 * view alignment is at the center of the view. The class allows defining 29 * alignment at left/right or fixed offset/percentage position; it also allows 30 * using descendant view by id match. 31 */ 32class ItemAlignment { 33 34 final static class Axis { 35 private int mOrientation; 36 private int mOffset = 0; 37 private float mOffsetPercent = 50; 38 private int mViewId = 0; 39 private boolean mOffsetWithPadding = false; 40 private Rect mRect = new Rect(); 41 42 Axis(int orientation) { 43 mOrientation = orientation; 44 } 45 46 public void setItemAlignmentOffset(int offset) { 47 mOffset = offset; 48 } 49 50 public int getItemAlignmentOffset() { 51 return mOffset; 52 } 53 54 public void setItemAlignmentOffsetWithPadding(boolean withPadding) { 55 mOffsetWithPadding = withPadding; 56 } 57 58 public boolean isItemAlignmentOffsetWithPadding() { 59 return mOffsetWithPadding; 60 } 61 62 public void setItemAlignmentOffsetPercent(float percent) { 63 if ( (percent < 0 || percent > 100) && 64 percent != ITEM_ALIGN_OFFSET_PERCENT_DISABLED) { 65 throw new IllegalArgumentException(); 66 } 67 mOffsetPercent = percent; 68 } 69 70 public float getItemAlignmentOffsetPercent() { 71 return mOffsetPercent; 72 } 73 74 public void setItemAlignmentViewId(int viewId) { 75 mViewId = viewId; 76 } 77 78 public int getItemAlignmentViewId() { 79 return mViewId; 80 } 81 82 /** 83 * get alignment position relative to optical left/top of itemView. 84 */ 85 public int getAlignmentPosition(View itemView) { 86 LayoutParams p = (LayoutParams) itemView.getLayoutParams(); 87 View view = itemView; 88 if (mViewId != 0) { 89 view = itemView.findViewById(mViewId); 90 if (view == null) { 91 view = itemView; 92 } 93 } 94 int alignPos; 95 if (mOrientation == HORIZONTAL) { 96 if (mOffset >= 0) { 97 alignPos = mOffset; 98 if (mOffsetWithPadding) { 99 alignPos += view.getPaddingLeft(); 100 } 101 } else { 102 alignPos = view == itemView ? p.getOpticalWidth(view) : view.getWidth() 103 + mOffset; 104 if (mOffsetWithPadding) { 105 alignPos -= view.getPaddingRight(); 106 } 107 } 108 if (mOffsetPercent != ITEM_ALIGN_OFFSET_PERCENT_DISABLED) { 109 alignPos += ((view == itemView ? p.getOpticalWidth(view) : view.getWidth()) 110 * mOffsetPercent) / 100f; 111 } 112 if (itemView != view) { 113 mRect.left = alignPos; 114 ((ViewGroup) itemView).offsetDescendantRectToMyCoords(view, mRect); 115 alignPos = mRect.left - p.getOpticalLeftInset(); 116 } 117 } else { 118 if (mOffset >= 0) { 119 alignPos = mOffset; 120 if (mOffsetWithPadding) { 121 alignPos += view.getPaddingTop(); 122 } 123 } else { 124 alignPos = view == itemView ? p.getOpticalHeight(view) : view.getHeight() 125 + mOffset; 126 if (mOffsetWithPadding) { 127 alignPos += view.getPaddingBottom(); 128 } 129 } 130 if (mOffsetPercent != ITEM_ALIGN_OFFSET_PERCENT_DISABLED) { 131 alignPos += ((view == itemView ? p.getOpticalHeight(view) : view.getHeight()) 132 * mOffsetPercent) / 100f; 133 } 134 if (itemView != view) { 135 mRect.top = alignPos; 136 ((ViewGroup) itemView).offsetDescendantRectToMyCoords(view, mRect); 137 alignPos = mRect.top - p.getOpticalTopInset(); 138 } 139 } 140 return alignPos; 141 } 142 } 143 144 private int mOrientation = HORIZONTAL; 145 146 final public Axis vertical = new Axis(VERTICAL); 147 148 final public Axis horizontal = new Axis(HORIZONTAL); 149 150 private Axis mMainAxis = horizontal; 151 152 private Axis mSecondAxis = vertical; 153 154 final public Axis mainAxis() { 155 return mMainAxis; 156 } 157 158 final public Axis secondAxis() { 159 return mSecondAxis; 160 } 161 162 final public void setOrientation(int orientation) { 163 mOrientation = orientation; 164 if (mOrientation == HORIZONTAL) { 165 mMainAxis = horizontal; 166 mSecondAxis = vertical; 167 } else { 168 mMainAxis = vertical; 169 mSecondAxis = horizontal; 170 } 171 } 172 173 final public int getOrientation() { 174 return mOrientation; 175 } 176 177 178} 179