1 /* 2 * Copyright (C) 2016 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.documentsui.sorting; 18 19 import android.animation.AnimatorInflater; 20 import android.animation.LayoutTransition; 21 import android.animation.ObjectAnimator; 22 import androidx.annotation.AnimatorRes; 23 import androidx.annotation.StringRes; 24 import android.content.Context; 25 import android.util.AttributeSet; 26 import android.view.Gravity; 27 import android.view.View; 28 import android.widget.ImageView; 29 import android.widget.LinearLayout; 30 import android.widget.TextView; 31 32 import com.android.documentsui.R; 33 import com.android.documentsui.sorting.SortDimension; 34 35 /** 36 * A clickable, sortable table header cell layout. 37 * 38 * It updates its display when it binds to {@link SortDimension} and changes the status of sorting 39 * when it's clicked. 40 */ 41 public class HeaderCell extends LinearLayout { 42 43 private static final long ANIMATION_DURATION = 100; 44 45 private @SortDimension.SortDirection int mCurDirection = SortDimension.SORT_DIRECTION_NONE; 46 HeaderCell(Context context)47 public HeaderCell(Context context) { 48 this(context, null); 49 } 50 HeaderCell(Context context, AttributeSet attrs)51 public HeaderCell(Context context, AttributeSet attrs) { 52 super(context, attrs); 53 54 LayoutTransition transition = getLayoutTransition(); 55 transition.setDuration(ANIMATION_DURATION); 56 transition.setStartDelay(LayoutTransition.CHANGE_APPEARING, 0); 57 transition.setStartDelay(LayoutTransition.CHANGE_DISAPPEARING, 0); 58 transition.setStartDelay(LayoutTransition.CHANGING, 0); 59 } 60 onBind(SortDimension dimension)61 void onBind(SortDimension dimension) { 62 setVisibility(dimension.getVisibility()); 63 64 if (dimension.getVisibility() == View.VISIBLE) { 65 TextView label = (TextView) findViewById(R.id.label); 66 label.setText(dimension.getLabelId()); 67 switch (dimension.getDataType()) { 68 case SortDimension.DATA_TYPE_NUMBER: 69 setDataTypeNumber(label); 70 break; 71 case SortDimension.DATA_TYPE_STRING: 72 setDataTypeString(label); 73 break; 74 default: 75 throw new IllegalArgumentException( 76 "Unknown column data type: " + dimension.getDataType() + "."); 77 } 78 79 if (mCurDirection != dimension.getSortDirection()) { 80 ImageView arrow = (ImageView) findViewById(R.id.sort_arrow); 81 switch (dimension.getSortDirection()) { 82 case SortDimension.SORT_DIRECTION_NONE: 83 arrow.setVisibility(View.GONE); 84 break; 85 case SortDimension.SORT_DIRECTION_ASCENDING: 86 showArrow(arrow, R.animator.arrow_rotate_up, 87 R.string.sort_direction_ascending); 88 break; 89 case SortDimension.SORT_DIRECTION_DESCENDING: 90 showArrow(arrow, R.animator.arrow_rotate_down, 91 R.string.sort_direction_descending); 92 break; 93 default: 94 throw new IllegalArgumentException( 95 "Unknown sort direction: " + dimension.getSortDirection() + "."); 96 } 97 98 mCurDirection = dimension.getSortDirection(); 99 } 100 } 101 } 102 showArrow( ImageView arrow, @AnimatorRes int anim, @StringRes int contentDescriptionId)103 private void showArrow( 104 ImageView arrow, @AnimatorRes int anim, @StringRes int contentDescriptionId) { 105 arrow.setVisibility(View.VISIBLE); 106 107 CharSequence description = getContext().getString(contentDescriptionId); 108 arrow.setContentDescription(description); 109 110 ObjectAnimator animator = 111 (ObjectAnimator) AnimatorInflater.loadAnimator(getContext(), anim); 112 animator.setTarget(arrow.getDrawable().mutate()); 113 animator.start(); 114 } 115 setDataTypeNumber(View label)116 private void setDataTypeNumber(View label) { 117 label.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_END); 118 setGravity(Gravity.CENTER_VERTICAL | Gravity.END); 119 } 120 setDataTypeString(View label)121 private void setDataTypeString(View label) { 122 label.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_START); 123 setGravity(Gravity.CENTER_VERTICAL | Gravity.START); 124 } 125 } 126