![](/img/trans.png)
[英]How to create a rectangle with centered circle shape and icon inside of it in Android?
[英]How to create a 'transparent circle inside rectangle' shape in XML in Android?
我正在嘗試在我的應用中創建以下設計。
它是主UI上面的疊加層。 嘗試使用主UI頂部的布局創建它,其背景為以XML創建的半透明形狀。 然而,即使閱讀了多篇文章,我也無法弄明白。
我嘗試了以下方法,但它沒有用。 創建一個200dp筆划的環形,並將其設置為imageview的源,然后將scaletype設置為centerCrop,但形狀不像位圖那樣縮放。
形狀XML:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:innerRadius="0dp"
android:shape="ring"
android:thicknessRatio="2"
android:useLevel="false" >
<solid android:color="@android:color/transparent" />
<stroke
android:width="200dp"
android:color="#80000000" />
</shape>
疊加布局:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/onboarding_background"
android:scaleType="centerCrop"/>
</RelativeLayout>
有關如何執行此操作或代碼的任何指示都非常有用。
我最近一直在玩類似的東西,並為你量身定做。 所有的魔力都發生在onDraw上:
public class FocusView extends View {
private Paint mTransparentPaint;
private Paint mSemiBlackPaint;
private Path mPath = new Path();
public FocusView(Context context) {
super(context);
initPaints();
}
public FocusView(Context context, AttributeSet attrs) {
super(context, attrs);
initPaints();
}
public FocusView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initPaints();
}
private void initPaints() {
mTransparentPaint = new Paint();
mTransparentPaint.setColor(Color.TRANSPARENT);
mTransparentPaint.setStrokeWidth(10);
mSemiBlackPaint = new Paint();
mSemiBlackPaint.setColor(Color.TRANSPARENT);
mSemiBlackPaint.setStrokeWidth(10);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mPath.reset();
mPath.addCircle(canvas.getWidth() / 2, canvas.getHeight() / 2, 550, Path.Direction.CW);
mPath.setFillType(Path.FillType.INVERSE_EVEN_ODD);
canvas.drawCircle(canvas.getWidth() / 2, canvas.getHeight() / 2, 550, mTransparentPaint);
canvas.drawPath(mPath, mSemiBlackPaint);
canvas.clipPath(mPath);
canvas.drawColor(Color.parseColor("#A6000000"));
}
}
這里的技巧是創建一個Path(透明圓),以便我們可以將路徑的繪制方法設置為“路徑之外”而不是“路徑內部”。 最后,我們可以簡單地將畫布剪切到該路徑,並填充黑色。
對於您來說,您只需要將Color.BLACK
更改為您的顏色,以及更改所需的半徑。
編輯:哦,只需以編程方式添加它: FocusView view = new FocusView(context)
your_layout.addView(view)
FocusView view = new FocusView(context)
your_layout.addView(view)
或者通過XML:
<package_path_to_.FocusView
android:layout_width="match_parent"
android:layout_height="match_parent" />
編輯2:我剛剛看到你想要這個用於你的應用程序的入職。 您可以考慮查看https://github.com/iammert/MaterialIntroView
您可以使用PorterDuffXferMode和自定義視圖。
這張照片提供了不同模式的好例子(參見A出B): AlphaCompositing
我們的想法是創建自定義視圖,不透明的黑色矩形和圓形。 當您應用PorterDuffXferMode.SRC_OUT時,它將從矩形“擦除”圓圈,因此您將得到您想要的結果。
在自定義視圖中,您應該覆蓋dispatchDraw(Canvas canvas)方法,並在幀上繪制結果位圖。
然后,您可以將MapView和自定義視圖放在FrameLayout中並享受結果。
我遇到了這樣一個問題,即代碼無法在NSimon的api lvl 16上運行。 我修復了代碼,現在它支持api 16+。
public class FocusView extends View {
private Paint mPaint;
private Paint mStrokePaint;
private Path mPath = new Path();
public FocusView(Context context) {
super(context);
initPaints();
}
public FocusView(Context context, AttributeSet attrs) {
super(context, attrs);
initPaints();
}
public FocusView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initPaints();
}
private void initPaints() {
mPaint = new Paint();
mPaint.setColor(Color.parseColor("#A6000000"));
mStrokePaint = new Paint();
mStrokePaint.setColor(Color.YELLOW);
mStrokePaint.setStrokeWidth(2);
mStrokePaint.setStyle(Paint.Style.STROKE);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mPath.reset();
float radius = 0;
float strokeWidth = 0;
if (canvas.getWidth() < canvas.getHeight()) {
radius = canvas.getWidth() / 2 - 10;
strokeWidth = (canvas.getHeight() - canvas.getWidth())/2;
} else {
radius = canvas.getHeight() / 2 - 10;
strokeWidth = (canvas.getWidth() - canvas.getHeight())/2;
}
mPaint.setStrokeWidth(strokeWidth);
mPath.addCircle(canvas.getWidth() / 2, canvas.getHeight() / 2, radius, Path.Direction.CW);
mPath.setFillType(Path.FillType.INVERSE_EVEN_ODD);
canvas.drawCircle(canvas.getWidth() / 2, canvas.getHeight() / 2, radius, mStrokePaint);
canvas.drawPath(mPath, mPaint);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.