现在AI这么火热,优化也方便,这里问了文心一言,如果着急用直接拿走用不用看细节,毕竟我也没看细节,直接看的效果,哈哈
public class MatrixTranslateLayout extends LinearLayout {
private int parentHeight = 0;
private int topOffset = 0;
public MatrixTranslateLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public void setParentHeight(int height) {
parentHeight = height;
}
@Override
protected void dispatchDraw(Canvas canvas) {
canvas.save();
if (topOffset == 0) {
topOffset = getHeight() / 2;
}
int top = getTop()+topOffset;
Log.e("11111",top+":"+parentHeight);
float tran = calculateTranslate(top , parentHeight);
Matrix m = canvas.getMatrix();
//tran水平平移量
m.setTranslate(tran,0);
canvas.concat(m);
super.dispatchDraw(canvas);
canvas.restore();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
/* private float calculateTranslate(int top, int h) {
if (h == 0) return 0f; // 避免除以0
int centerY = h / 2;
float distanceFromCenter = top - centerY; // 计算与中心的距离
// 1. 取绝对值,确保只向右平移(不关心方向)
float absDistance = Math.abs(distanceFromCenter);
// 2. 归一化到 [0, 1] 范围(h/2 是最大可能距离)
float normalizedDistance = Math.min(absDistance / (h / 2f), 1f);
// 3. 使用平滑曲线(如三次方函数)使平移更自然
float smoothFactor = (float) Math.pow(normalizedDistance, 1.5f); // 1.5 次方使变化更平缓
// 4. 计算最大平移量(例如视口宽度的 30%)
//如果觉得平移不够明显,可以调整 maxTranslate 0.5f
float maxTranslate = getWidth() * 0.3f;
// 5. 最终平移量(始终 ≥ 0,确保只向右移动)
return smoothFactor * maxTranslate;
}*/
/**
* 定版是这个,上面的方法也可以
*/
private float calculateTranslate(int top, int h) {
if (parentHeight == 0) return 0f;
float centerY = parentHeight / 2f;
float maxDistance = parentHeight / 2f;
float normalizedDistance = (top - centerY) / maxDistance; // [-1, 1]
// θ 范围 [0, π](半圆)
float theta = (float) ((normalizedDistance + 1) * Math.PI / 2); // [0, π]
float radius = getWidth() * 0.4f;
// 计算半圆轨迹的 x 偏移量
float xOffset = (float) (radius * Math.sin(theta)); // 0 ≤ x ≤ 2r
// 调整偏移量(可选)
xOffset = Math.abs(xOffset - radius); // 使 x 范围在 [-r, r]
return xOffset;
}
}
xOffset = Math.abs(xOffset - radius); // 使 x 范围在 [-r, r]
这里取了绝对值,如果不取绝对值就会呈现S滑动,我这里转盘在右边所以右移都是正直
如果往左移就取负值,最后的xOffse*-1即可
使用也简单,在Recyclerview单条布局最外层用
MatrixTranslateLayout包裹就行了
3165

被折叠的 条评论
为什么被折叠?



