package com.example.scrollviewtest;
import android.content.Context;
import android.graphics.Canvas;
import android.media.MediaPlayer;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.Scroller;
import androidx.annotation.Nullable;
public class MyScrollView extends LinearLayout {
private LinearLayout llOne;
private LinearLayout llTwo;
private int mItemHeight = 76 * 3;
private Scroller mScroller;
private int mHalfTotalHeight;
float scaleSize = 0f;
float scaleAlpha = 0f;
private float startY;
private int mCurrentPosition = -1;
public MyScrollView(Context context) {
this(context, null);
}
public MyScrollView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public MyScrollView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
llOne = findViewById(R.id.llOne);
llTwo = findViewById(R.id.llTwo);
System.out.println("lgj onMeasure");
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
computeScale();
// 初始化最开始的状态
scaleAnimal(false);
}
private void init(Context context) {
// 平滑的打开以及关闭
mScroller = new Scroller(context);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
startY = event.getY();
break;
case MotionEvent.ACTION_MOVE:
float moveY = event.getY();
// 终点减去 起点就是 dy 的值,向上滑动,是负值,
int dy = (int) (moveY - startY);
// scrollBy 和 scrollTo 这两个方法指的是屏幕,屏幕往右是正值, 屏幕往下是正值,(相当于内容往上走)
int scrollY = getScrollY();// 这个值为正值表示,屏幕往下走,把屏幕看成静止,内容就往上走
System.out.println("lgj dy : " + dy + " scrollY : " + scrollY);
// 对边界进行控制,在移动之前,查看边界到某个位置了
if (scrollY >= mItemHeight && dy < 0) {
// 已经向上滑到顶端,dy < 0,表示此时正在向上滑动
scrollTo(0, mItemHeight);
} else if (scrollY <= 0 && dy > 0) {
// 表示已经滑动最低端,而且继续向下滑动,然后固定到最下面
scrollTo(0, 0);
} else {
scrollBy(0, -dy);
}
if (dy != 0){
scaleAnimal();
}
startY = moveY;
break;
case MotionEvent.ACTION_UP:
// 判断中间位置显示那个 item
int currentScrollY = getScrollY();
if (currentScrollY >= mItemHeight / 2) {
// 往上滑动
// scrollTo(0, itemHeight);
smoothScrollTo(mItemHeight);
scaleAnimal(true);
mCurrentPosition = 1;
} else {
// scrollTo(0, 0);
smoothScrollTo(0);
scaleAnimal(false);
mCurrentPosition = 0;
}
break;
}
return true;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
}
private void scaleAnimal(boolean isUp) {
if (isUp) {
llTwo.setScaleX(1.12f);
llTwo.setScaleY(1.12f);
llTwo.setAlpha(1f);
llOne.setScaleX(0.8f);
llOne.setScaleY(0.8f);
llOne.setAlpha(0.32f);
} else {
llOne.setScaleX(1.12f);
llOne.setScaleY(1.12f);
llOne.setAlpha(1f);
llTwo.setScaleX(0.8f);
llTwo.setScaleY(0.8f);
llTwo.setAlpha(0.32f);
}
}
// 计算大小的缩放比列以及,文字灰度的缩放比例
private void computeScale(){
mHalfTotalHeight = getHeight() / 2;
View firstView = getChildAt(0);
mItemHeight = firstView.getHeight();
// 计算第 0 个 view在父布局的 Y 轴坐标
float firstY = firstView.getBottom() - firstView.getHeight() / 2;
float tempValue = (mHalfTotalHeight - firstY) / mHalfTotalHeight;
scaleSize = (float) ((1.12 - 0.8) / tempValue);
scaleAlpha = (float) ((1 - 0.32) / tempValue);
System.out.println("lgj tempValue :" + tempValue + " scaleSize : " + scaleSize + " scaleAlpha : " + scaleAlpha + " mItemHeight :" + mItemHeight);
}
private void scaleAnimal() {
if (mHalfTotalHeight <= 0) {
return;
}
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
if (i != 0) {
View tempView = getChildAt(i);
// 获取view 在父布局Y 的坐标
int screenY = tempView.getBottom() - tempView.getHeight() / 2;
int scrollY = getScrollY();
int realScreenY = screenY - scrollY;
System.out.println("scrollY : " + scrollY + " screenY : " + screenY + " realScreenY : " + realScreenY);
float distance;
if (realScreenY > mHalfTotalHeight) {
distance = realScreenY - mHalfTotalHeight;
} else {
distance = mHalfTotalHeight - realScreenY;
}
System.out.println("lgh distance : " + distance + " mHalfTotalHeight :" + mHalfTotalHeight);
float scaleValue = (float) ((1.12 - (distance / mHalfTotalHeight) * scaleSize));
float scaleAlphaValue = (float) ((1 - (distance / mHalfTotalHeight) * scaleAlpha));
System.out.println("lgj scaleValue : " + scaleValue + " scaleAlphaValue : " + scaleAlphaValue);
tempView.setScaleX(scaleValue);
tempView.setScaleY(scaleValue);
tempView.setAlpha(scaleAlphaValue);
}
}
}
private void smoothScrollTo(int destY) {
// 起始 的 y 坐标
int scrollY = getScrollY();
// 终点左边减去起始坐标
int dy = destY - scrollY;
// 这句话的含义是个滚动器安排了一个任务
System.out.println("lgj smoothScrollTo scrollY : " + scrollY + " destY : " + destY + " dy : " + dy);
// 这里面的dy 如果是负值的话,表示屏幕往上走,那么内容就是往下走的
mScroller.startScroll(0, scrollY, 0, dy);
// 触发 draw 方法的调用,draw方法会调用computeScroll 方法
invalidate();
}
@Override
public void computeScroll() {
super.computeScroll();
// 判断滚动器的任务是否已经完成
if (mScroller.computeScrollOffset()) {
// 为true 表示任务没有完成
// 获取当前应该滚动到那个位置
int currY = mScroller.getCurrY();
scrollTo(0, currY);
invalidate();
} else {
System.out.println("lgj computeScroll 完成了。。。");
}
}
}
lgj
最新推荐文章于 2022-05-28 02:21:26 发布