Android 는 지 정 된 영역 투명 영역 을 그립 니 다.
스 캔 기능 을 실현 할 때,우 리 는 중간 이 투명 한 스 캔 상 자 를 그 려 야 하고,나머지 부분 은 반투명 이다.일반적인 상황 에서 예 를 들 어 위 챗 이나 알 리 페 이의 스 캔 상 자 는 모두 사각형 입 니 다.만약 에 중간 에 스 캔 상자 가 사각형 이 라면 구 조 는 매우 간단 합 니 다.그러나 스 캔 상자 가 원 각 사각형 이나 원형 등 상황 이 라면 어떻게 합 니까?이 글 은 주로 중간 투명 띠 원 각 의 사각형 을 그 리 는 것 을 기록 하고 있다.
관례 에 따라 우 리 는 먼저 효과 도 를 살 펴 보 자.
2.절차 에 따라 코드 를 살 펴 보 겠 습 니 다.
1.Custom Drawable,중간 에 투명 영역 이 나타 나 는 drawable 지원
package per.juan.scandome;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.drawable.Drawable;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
/**
* drawable
* {@link #setSrcPath(Path)}
* Created by juan on 2018/07/20.
*/
public class CustomDrawable extends Drawable {
private Paint srcPaint;
private Path srcPath = new Path();
private Drawable innerDrawable;
public CustomDrawable(Drawable innerDrawable) {
this.innerDrawable = innerDrawable;
srcPath.addRect(100, 100, 200, 200, Path.Direction.CW);
srcPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
srcPaint.setColor(0xffffffff);
}
/**
*
*
* @param srcPath
*/
public void setSrcPath(Path srcPath) {
this.srcPath = srcPath;
}
@Override
public void draw(@NonNull Canvas canvas) {
innerDrawable.setBounds(getBounds());
if (srcPath == null || srcPath.isEmpty()) {
innerDrawable.draw(canvas);
} else {
// , , ,
int saveCount = canvas.saveLayer(0, 0, canvas.getWidth(), canvas.getHeight(), srcPaint, Canvas.ALL_SAVE_FLAG);
//dst
innerDrawable.draw(canvas);
//
srcPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
//src
canvas.drawPath(srcPath, srcPaint);
//
srcPaint.setXfermode(null);
//
canvas.restoreToCount(saveCount);
}
}
@Override
public void setAlpha(int alpha) {
innerDrawable.setAlpha(alpha);
}
@Override
public void setColorFilter(@Nullable ColorFilter colorFilter) {
innerDrawable.setColorFilter(colorFilter);
}
@Override
public int getOpacity() {
return innerDrawable.getOpacity();
}
}
(1)주로 사용 하 는 기술 은 Porter Duff Xfermode 의PorterDuff.Mode.XOR
모델 이다.(2)핵심 사상 은 먼저 drawable 전 체 를 정상적으로 그 려 낸 다음 에 지정 한 구역 을 투명 색 으로 혼합 하 는 것 이다.
2、CustomLayout
package per.juan.scandome;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Path;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;
import android.widget.FrameLayout;
/**
* layout View ,
* Created by juan on 2018/07/20.
*/
public class CustomLayout extends FrameLayout {
private Context mContext;
private CustomDrawable background;
public CustomLayout(@NonNull Context context) {
super(context);
initView(context, null, 0);
}
public CustomLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
this.mContext=context;
initView(context, attrs, 0);
}
public CustomLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView(context, attrs, defStyleAttr);
}
@SuppressLint("NewApi")
private void initView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
background = new CustomDrawable(getBackground());
setBackground(background);
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
resetBackgroundHoleArea();
}
@SuppressLint("NewApi")
private void resetBackgroundHoleArea() {
Path path = null;
// View
View view = findViewById(R.id.iv_scan);
if (view != null) {
path = new Path();
//
path.addRoundRect(view.getLeft(), view.getTop(), view.getRight(), view.getBottom(), dp2Px(mContext,10), dp2Px(mContext,10),Path.Direction.CW);
}
if (path != null) {
background.setSrcPath(path);
}
}
public int dp2Px(Context context, float dp) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dp * scale + 0.5f);
}
}
3.그리고 XML 레이아웃 에서 사용자 정의 View 를 설명 합 니 다.
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:id="@+id/frame_layout"
android:layout_height="match_parent">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@mipmap/bg_image" />
<per.juan.scandome.CustomLayout
android:layout_width="match_parent"
android:id="@+id/layout"
android:background="#8c565658"
android:layout_height="match_parent">
<!-- View , -->
<FrameLayout
android:id="@+id/iv_scan"
android:layout_width="200dp"
android center" />
</per.juan.scandome.CustomLayout>
</FrameLayout>
자,이 글 은 이렇게 되 었 습 니 다.부족 한 점 이 있 으 면 지 도 를 바 랍 니 다.감사합니다^ ^부록:
사용자 정의 Drawable:Drawable 중부 에 투명 영역 지정
총결산
이상 은 이 글 의 전체 내용 입 니 다.본 논문 의 내용 이 여러분 의 학습 이나 업무 에 어느 정도 참고 학습 가치 가 있 기 를 바 랍 니 다.궁금 한 점 이 있 으 시 면 댓 글 을 남 겨 주 셔 서 저희 에 대한 지지 에 감 사 드 립 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Kotlin의 기초 - 2부지난 글에서는 Kotlin이 무엇인지, Kotlin의 특징, Kotlin에서 변수 및 데이터 유형을 선언하는 방법과 같은 Kotlin의 기본 개념에 대해 배웠습니다. 유형 변환은 데이터 변수의 한 유형을 다른 데이터...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.