Files
Lawnchair/src/com/android/launcher3/allapps/LetterListTextView.java
T
Brandon Dayauon 9d60a18c5c Only have private space drawable section for beginning of private space section and keep letters for everything else.
spec: https://www.figma.com/design/uMzPkNMZpb7EyfHDo8usIa/V-%E2%80%A2-Toast-Butter?node-id=2746-180205&node-type=frame&m=dev
As of recent request: Only using the bubble background for everything and have private space go back to using letters.

Will include divider in followup.

bug:358673724
Test photo: https://drive.google.com/file/d/1dC3fgfWiumhyLm4vI-VfnXIYQyjPyrnk/view?usp=sharing
Flag: com.android.launcher3.letter_fast_scroller

Change-Id: I30487581eec4bd3e1921de4e3d899cfe2e2a703f
2024-10-10 16:31:39 -07:00

152 lines
6.0 KiB
Java

/*
* Copyright (C) 2024 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.launcher3.allapps;
import static androidx.constraintlayout.widget.ConstraintSet.MATCH_CONSTRAINT;
import static androidx.constraintlayout.widget.ConstraintSet.WRAP_CONTENT;
import android.content.Context;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.widget.TextView;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.core.graphics.ColorUtils;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.util.Themes;
/**
* A TextView that is used to display the letter list in the fast scroller.
*/
public class LetterListTextView extends TextView {
private static final float ABSOLUTE_TRANSLATION_X = 30f;
private static final float ABSOLUTE_SCALE = 1.4f;
private final Drawable mLetterBackground;
private final int mLetterListTextWidthAndHeight;
private final int mTextColor;
private final int mBackgroundColor;
private final int mSelectedColor;
public LetterListTextView(Context context) {
this(context, null, 0);
}
public LetterListTextView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public LetterListTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mLetterBackground = context.getDrawable(R.drawable.bg_letter_list_text);
mLetterListTextWidthAndHeight = context.getResources().getDimensionPixelSize(
R.dimen.fastscroll_list_letter_size);
mTextColor = Themes.getAttrColor(context, R.attr.materialColorOnSurface);
mBackgroundColor = Themes.getAttrColor(context, R.attr.materialColorSurfaceContainer);
mSelectedColor = Themes.getAttrColor(context, R.attr.materialColorOnSecondary);
}
@Override
public void onFinishInflate() {
super.onFinishInflate();
setBackground(mLetterBackground);
setTextColor(mTextColor);
setClickable(false);
setWidth(mLetterListTextWidthAndHeight);
setTextSize(mLetterListTextWidthAndHeight);
setVisibility(VISIBLE);
}
/**
* Applies a viewId to the letter list text view and sets the background and text based on the
* sectionInfo.
*/
public void apply(AlphabeticalAppsList.FastScrollSectionInfo fastScrollSectionInfo,
int viewId) {
setId(viewId);
setText(fastScrollSectionInfo.sectionName);
ConstraintLayout.LayoutParams lp = new ConstraintLayout.LayoutParams(
MATCH_CONSTRAINT, WRAP_CONTENT);
lp.dimensionRatio = "v,1:1";
setLayoutParams(lp);
}
/**
* Animates the letter list text view based on the current finger position.
*
* @param currentFingerY The Y position of where the finger is placed on the fastScroller in
* pixels.
*/
public void animateBasedOnYPosition(int currentFingerY) {
if (getBackground() == null) {
return;
}
float cutOffMin = currentFingerY - (getHeight() * 2);
float cutOffMax = currentFingerY + (getHeight() * 2);
float cutOffDistance = cutOffMax - cutOffMin;
// Update the background blend color
boolean isWithinAnimationBounds = getY() < cutOffMax && getY() > cutOffMin;
if (isWithinAnimationBounds) {
getBackground().setColorFilter(new PorterDuffColorFilter(
getBlendColorBasedOnYPosition(currentFingerY, cutOffDistance),
PorterDuff.Mode.MULTIPLY));
} else {
getBackground().setColorFilter(new PorterDuffColorFilter(
mBackgroundColor, PorterDuff.Mode.MULTIPLY));
}
translateBasedOnYPosition(currentFingerY, cutOffDistance, isWithinAnimationBounds);
scaleBasedOnYPosition(currentFingerY, cutOffDistance, isWithinAnimationBounds);
}
private int getBlendColorBasedOnYPosition(int y, float cutOffDistance) {
float raisedCosineBlend = (float) Math.cos(((y - getY()) / (cutOffDistance)) * Math.PI);
float blendRatio = Utilities.boundToRange(raisedCosineBlend, 0f, 1f);
return ColorUtils.blendARGB(mBackgroundColor, mSelectedColor, blendRatio);
}
private void scaleBasedOnYPosition(int y, float cutOffDistance,
boolean isWithinAnimationBounds) {
float raisedCosineScale = (float) Math.cos(((y - getY()) / (cutOffDistance)) * Math.PI)
* ABSOLUTE_SCALE;
if (isWithinAnimationBounds) {
raisedCosineScale = Utilities.boundToRange(raisedCosineScale, 1f, ABSOLUTE_SCALE);
setScaleX(raisedCosineScale);
setScaleY(raisedCosineScale);
} else {
setScaleX(1);
setScaleY(1);
}
}
private void translateBasedOnYPosition(int y, float cutOffDistance,
boolean isWithinAnimationBounds) {
float raisedCosineTranslation =
(float) Math.cos(((y - getY()) / (cutOffDistance)) * Math.PI)
* ABSOLUTE_TRANSLATION_X;
if (isWithinAnimationBounds) {
raisedCosineTranslation = -1 * Utilities.boundToRange(raisedCosineTranslation,
0, ABSOLUTE_TRANSLATION_X);
setTranslationX(raisedCosineTranslation);
} else {
setTranslationX(0);
}
}
}