アプリで次のデザインを作成しようとしています。
メインUIの上にオーバーレイします。 XMLで作成された半透明の形状として背景を持つメインUIの上にレイアウトを使用してこれを作成しようとしています。しかし、複数の投稿を読んだ後でも、私はそれを理解することができません。
次の方法を試しましたが、うまくいきませんでした。 200dpのストロークでリングシェイプを作成し、それをイメージビューのソースとして設定してから、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"));
}
}
_
ここでの秘訣は、パス(透明な円)を作成して、パスの描画方法を「パスの内側」ではなく「パスの外側」に設定できるようにすることです。最後に、キャンバスをそのパスにクリップして、黒い色を塗りつぶすだけです。
あなたのために、あなたはただ_Color.BLACK
_をあなたの色に変えるだけでなく、希望の半径を変える必要があるでしょう。
編集:ああ、それをプログラムで追加するだけです:FocusView view = new FocusView(context)
your_layout.addView(view)
またはXMLで:
_<package_path_to_.FocusView
Android:layout_width="match_parent"
Android:layout_height="match_parent" />
_
EDIT2:アプリのオンボーディングにこれが必要だと思ったところです。 https://github.com/iammert/MaterialIntroView を見てみることを検討してください。
NSimonのapilvl16でコードが機能しないという問題が発生しました。コードを修正し、API16以降をサポートするようになりました。
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);
}
}
PorterDuffXferMode とそのためのカスタムビューを使用できます。
この写真で提供されているさまざまなモードの良い例(A Out Bを参照): AlphaCompositing
アイデアは、不透明な黒い長方形とその上に円を描くカスタムビューを作成することです。 PorterDuffXferMode.SRC_OUTを適用すると、長方形から円が「消去」されるため、希望どおりの結果が得られます。
カスタムビューでは、dispatchDraw(Canvas canvas)メソッドをオーバーライドし、結果のビットマップをフレームに描画する必要があります。
次に、MapViewとカスタムビューをFrameLayoutに配置して、結果を楽しむことができます。