6
A
回答
2
U可以參考在GIT城市流動抽屜
鏈接:https://github.com/mxn21/FlowingDrawer
在此示例中,他們使用的是「LeftDrawerLayout 「一個自定義的類來處理這個效果,它的屬性由FlowingView設置。
使用此命令創建自定義類。
0
這是我的解決方案的原型:
我創建的自定義FrameLayout
和覆蓋onDraw
方法。這是它是什麼樣子:
我會添加註釋和說明,它是如何工作的,很快!
public class CurvedFrameLayout extends FrameLayout {
private Paint paint;
private Path path;
private int width;
private int height;
private float leftCurvePosition = 0.5f;
private float topCurvePosition = 0.5f;
private float rightCurvePosition = 0.5f;
private float bottomCurvePosition = 0.5f;
private int minimumCurve = 50;
private int maximumCurve = 100;
private int minimumLeftCurve = minimumCurve;
private int minimumTopCurve = minimumCurve;
private int minimumRightCurve = minimumCurve;
private int minimumBottomCurve = minimumCurve;
private int maximumLeftCurve = maximumCurve;
private int maximumTopCurve = maximumCurve;
private int maximumRightCurve = maximumCurve;
private int maximumBottomCurve = maximumCurve;
private float leftCurveOffset = 0f;
private float topCurveOffset = 0f;
private float rightCurveOffset = 0f;
private float bottomCurveOffset = 0f;
private int curveRadius = 150;
private float elevation = 4f;
private float cornerRadius = 50f;
private float margin = elevation;
private int color = Color.LTGRAY;
public CurvedFrameLayout(Context context) {
super(context);
init(context, null);
}
public CurvedFrameLayout(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
public CurvedFrameLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs);
}
private void init(Context context, AttributeSet attrs) {
if (attrs != null) {
TypedArray a = context.getTheme().obtainStyledAttributes(
attrs,
R.styleable.CurvedFrameLayout,
0, 0);
try {
leftCurvePosition = a.getFloat(R.styleable.CurvedFrameLayout_leftCurvePosition, 0.5f);
topCurvePosition = a.getFloat(R.styleable.CurvedFrameLayout_topCurvePosition, 0.5f);
rightCurvePosition = a.getFloat(R.styleable.CurvedFrameLayout_rightCurvePosition, 0.5f);
bottomCurvePosition = a.getFloat(R.styleable.CurvedFrameLayout_bottomCurvePosition, 0.5f);
minimumCurve = a.getDimensionPixelSize(R.styleable.CurvedFrameLayout_minimumCurve, 50);
maximumCurve = a.getDimensionPixelSize(R.styleable.CurvedFrameLayout_maximumCurve, 100);
minimumLeftCurve = a.getDimensionPixelSize(R.styleable.CurvedFrameLayout_minimumLeftCurve, 50);
minimumTopCurve = a.getDimensionPixelSize(R.styleable.CurvedFrameLayout_minimumTopCurve, 50);
minimumRightCurve = a.getDimensionPixelSize(R.styleable.CurvedFrameLayout_minimumRightCurve, 50);
minimumBottomCurve = a.getDimensionPixelSize(R.styleable.CurvedFrameLayout_minimumBottomCurve, 50);
maximumLeftCurve = a.getDimensionPixelSize(R.styleable.CurvedFrameLayout_maximumLeftCurve, 100);
maximumTopCurve = a.getDimensionPixelSize(R.styleable.CurvedFrameLayout_maximumTopCurve, 100);
maximumRightCurve = a.getDimensionPixelSize(R.styleable.CurvedFrameLayout_maximumRightCurve, 100);
maximumBottomCurve = a.getDimensionPixelSize(R.styleable.CurvedFrameLayout_maximumBottomCurve, 100);
leftCurveOffset = a.getFloat(R.styleable.CurvedFrameLayout_leftCurveOffset, 0f);
topCurveOffset = a.getFloat(R.styleable.CurvedFrameLayout_topCurveOffset, 0f);
rightCurveOffset = a.getFloat(R.styleable.CurvedFrameLayout_rightCurveOffset, 0f);
bottomCurveOffset = a.getFloat(R.styleable.CurvedFrameLayout_bottomCurveOffset, 0f);
curveRadius = a.getDimensionPixelSize(R.styleable.CurvedFrameLayout_curveRadius, 150);
cornerRadius = a.getDimensionPixelSize(R.styleable.CurvedFrameLayout_cornerRadius, 50);
elevation = a.getDimensionPixelSize(R.styleable.CurvedFrameLayout_elevation, 0);
margin = elevation;
color = a.getColor(R.styleable.CurvedFrameLayout_color, Color.LTGRAY);
} finally {
a.recycle();
}
}
setWillNotDraw(false);
paint = new Paint();
//setLayerType(LAYER_TYPE_SOFTWARE, paint);
paint.setColor(color);
paint.setShadowLayer(elevation, 0f, 0f, Color.LTGRAY);
path = new Path();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
drawLayout(canvas);
}
private void drawLayout(Canvas canvas) {
float cornerRadiusMargin = cornerRadius + margin;
float widthMinusMargin = width - margin;
float widthMinusMarginMinusCornerR = widthMinusMargin - cornerRadius;
float heightMinusMargin = height - margin;
float heightMinusMarginMinusCornerR = heightMinusMargin - cornerRadius;
//Top-left corner
path.reset();
path.moveTo(margin, cornerRadiusMargin);
path.quadTo(margin, margin, cornerRadiusMargin, margin);
//Top line
drawTopEdge(cornerRadiusMargin, margin, widthMinusMarginMinusCornerR, margin);
//Top-right corner
path.quadTo(widthMinusMargin, margin, widthMinusMargin, cornerRadiusMargin);
//Right line
drawRightEdge(widthMinusMargin, cornerRadiusMargin, widthMinusMargin, heightMinusMarginMinusCornerR);
//Bottom-right corner
path.quadTo(widthMinusMargin, heightMinusMargin, widthMinusMarginMinusCornerR, heightMinusMargin);
//Bottom line
path.lineTo(cornerRadiusMargin, heightMinusMargin);
//Bottom-left corner
path.quadTo(margin, heightMinusMargin, margin, heightMinusMarginMinusCornerR);
//Left line
drawLeftEdge(margin, heightMinusMarginMinusCornerR, margin, cornerRadiusMargin);
canvas.drawPath(path, paint);
canvas.clipPath(path, Region.Op.REPLACE);
}
private void drawTopEdge(float x1, float y1, float x2, float y2) {
float curveCenterX = (x1 + x2) * topCurvePosition;
float curveDeltaY = positionForOffset(minimumTopCurve, maximumTopCurve, topCurveOffset);
int curveX = curveRadius/2;
path.lineTo(curveCenterX - curveRadius, y1);
path.rCubicTo(curveX, 0, curveX, curveDeltaY, curveRadius, curveDeltaY);
path.rCubicTo(curveX, 0, curveX, -curveDeltaY, curveRadius, -curveDeltaY);
path.lineTo(x2, y2);
}
private void drawRightEdge(float x1, float y1, float x2, float y2) {
float curveCenterY = (y1 + y2) * rightCurvePosition;
float curveDeltaX = positionForOffset(minimumRightCurve, maximumRightCurve, rightCurveOffset);
path.lineTo(x1, curveCenterY - curveRadius);
int curveY = curveRadius/2;
path.rCubicTo(0, curveY, -curveDeltaX, curveY, -curveDeltaX, curveRadius);
path.rCubicTo(0, curveY, curveDeltaX, curveY, curveDeltaX, curveRadius);
path.lineTo(x2, y2);
}
private void drawLeftEdge(float x1, float y1, float x2, float y2) {
float curveCenterY = (y1 + y2) * leftCurvePosition;
float curveDeltaX = positionForOffset(minimumLeftCurve, maximumLeftCurve, leftCurveOffset);
path.lineTo(x1, curveCenterY + curveRadius);
int curveY = -curveRadius/2;
path.rCubicTo(0, curveY, curveDeltaX, curveY, curveDeltaX, -curveRadius);
path.rCubicTo(0, curveY, -curveDeltaX, curveY, -curveDeltaX, -curveRadius);
path.lineTo(x2, y2);
}
private float positionForOffset(float start, float end, float offset) {
return start + (end - start) * offset;
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
width = w;
height = h;
}
public void setLeftCurveOffset(float leftCurveOffset) {
this.leftCurveOffset = leftCurveOffset;
invalidate();
}
public void setRightCurveOffset(float rightCurveOffset) {
this.rightCurveOffset = rightCurveOffset;
invalidate();
}
}
此時,代碼是不完美的,但只要我提高這個代碼,我會更新的答案。
相關問題
- 1. css自定義形狀的背景色
- 2. CSS背景切割
- 3. 帶邊框和背景圖像的自定義CSS形狀
- 4. 960gs和邊緣的背景
- 5. Android Rounded邊緣的背景
- 6. 自定義背景?
- 7. 自定義背景
- 8. 我可以在OpenLayers中自定義多邊形的背景嗎?
- 9. 自定義狀態欄背景
- 10. EDITTEXT自定義偏移矩形背景
- 11. 的JPanel自定義背景
- 12. 在自定義背景後重置EditText的背景
- 13. 股利與切出邊緣,邊界和透明背景
- 14. 模糊背景上的尖銳邊緣
- 15. 背景的邊緣和IE調整
- 16. 自定義UIPickerView背景
- 17. Java swing自定義背景
- 18. 自定義CAB背景android
- 19. JScrollPanel與自定義背景
- 20. EditText自定義背景
- 21. 設置自定義形狀和PNG圖像的背景
- 22. 可設置背景顏色的Silverlight自定義形狀區域
- 23. 在shinydashboard body中切割背景顏色
- 24. 使六邊形形狀的邊框,圓角和透明背景
- 25. CSS:邊緣內只有背景顏色
- 26. 背景圖片x px從右邊緣
- 27. 背景圖像左邊緣問題
- 28. 背景切換?
- 29. 使用自定義背景drawables時損壞的EditText背景
- 30. UIBarButtonItem上的自定義背景/透明背景?
https://developer.android.com/reference/android/support/v4/view/ViewPager.OnPageChangeListener.html#onPageScrolled(int,float,int) –
@AnkitPopli我知道如何聽'ViewPager',但我需要知道如何創建邊緣並在拖動時進行自定義。 – RediOne1
創建一個繪製矩形區域[](]的自定義視圖,並根據頁面滾動的增量更改其半徑。如果我獲得時間,我將嘗試發佈解決方案。 –