Android 사용자 정의 View 점선 그리 기 방법 상세 설명

머리말
솔직히 이 수 요 를 처음 봤 을 때 첫 번 째 반응 은 Canvas 는 drawLine 방법 만 있 고 drawDashLine 방법 은 없 었 어 요!이 걸 어떻게 해,설마 내 가 끊임없이 draw Line 을 만들어 야 하나?1 초도 안 돼 서 나 는 이 생각 을 포기 했다.너무 징 그 러 워 서.방법 은 분명히 있 을 것 이다.단지 나 는 모 를 뿐이다.
그리 기 방법
가장 쉬 운 방법 은 Shape Drawable 을 이용 하 는 것 입 니 다.예 를 들 어 점선 으로 두 개의 컨트롤 을 분리 하려 면 이 두 개의 컨트롤 에 View 를 추가 하고 점선 배경 을 줄 수 있 습 니 다.
응,이론 적 으로 는 이 렇 고 실현 도 간단 해.

<!-- drawable    -->
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
 android:shape="line">
 <stroke
 android:width="1dp"
 android:color="@color/dash_line"
 android:dashGap="2dp"
 android:dashWidth="3dp"/>
</shape>

<!--      -->
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
 xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:tools="http://schemas.android.com/tools"
 android:id="@+id/activity_main"
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 android:orientation="vertical"
 android:gravity="center"
 tools:context="hope.example.dashlinedemo.MainActivity">

 <TextView
 android:layout_width="match_parent"
 android:layout_height="40dp"
 android:gravity="center"
 android:text="       "/>

 <View
 android:layout_width="match_parent"
 android:layout_height="2dp"
 android:background="@drawable/dash_line" />

 <TextView
 android:layout_width="match_parent"
 android:layout_height="40dp"
 android:gravity="center"
 android:text="      " />
</LinearLayout>
다 쓰 면 Android Studio 미리 보기 기능 에서 효 과 를 볼 수 있 습 니 다.

쉽 지 않 아 요?가만,우선 너무 일찍 기뻐 하지 말고,진짜 비행기 에서 뛰 어 봐,효과 가 먼저 야.

이게 뭐야,분명히 점선 이 맞 는데,Studio 의 미리 보기 에서 도 코드 가 문제 가 없다 는 것 을 알 수 있어.사실은 이것 은 우리 의 현재 핸드폰 은 기본적으로 하드웨어 가속 을 켰 기 때 문 입 니 다.dashGap 은 하드웨어 가속 을 지원 하지 않 습 니 다.우 리 는 View 의 매개 변 수 를 수정 하고 하드웨어 가속 을 끄 면 됩 니 다.

<View
 android:layout_width="match_parent"
 android:layout_height="2dp"
 android:background="@drawable/dash_line"
 android:layerType="software"/>
Shape Drawable 을 사용 하여 점선 을 실현 하 는 방식 은 간단 하지만 간단 하 다 는 것 은 유연 하지 않다 는 것 을 의미한다.예 를 들 어 점선 을 요구 하 는 것 은 사용자 의 조작 에 따라 추가 할 지 말 지 를 판단 하 는 것 이다.이런 상황 에서 Canvas 를 사용 하 는 것 이 편리 하 다.
앞에서 말 했 듯 이 Canvas 는 draw Line 방법 만 있 고 draw Dash Line 방법 은 없습니다.하지만 무엇 을 그 릴 지 는 Canvas 가 결정 하지만 어떻게 그 릴 지 는 붓 Paint 가 결정 한 다 는 것 을 알 아야 한다.다음은 이 신기 한 붓 이 직선 을 어떻게 허 하 게 그 려 주 는 지 보 자.
Paint 는setPathEffect(PathEffect effect)이런 방법 이 있 습 니 다.Path Effect 는 모두 다섯 가지 유형 이 있 습 니 다.ComposePath Effect,Corner Path Effect,DashPath Effect,Discrete Path Effect,Path DashEffect,SumPath Effect,그 중의 DashPath Effect 는 바로 우리 가 필요 로 하 는 점선 효과 입 니 다.다른 몇 가지 효 과 는 여러분 이 직접 시도 해 보 세 요.
Dashpath Effect 의 생 성 은 두 개의 인자 가 필요 합 니 다.하나의 float 배열 은 실제 라인 과 공백 부분의 길 이 를 대표 합 니 다.예 를 들 어 내 가 준 매개 변 수 는new float[] {10, 5}이다.그러면 점선 의 한 단 위 는 10 픽 셀 의 실선 에 5 픽 셀 의 공백 을 더 한 다음 에 이 단위 로 계속 반복 해서 그 려 서 점선 을 형성한다.만약 에 설 정 된 인자 가 new float[]{10,5,20,10}이 라면 점선 의 한 단 위 는 10 픽 셀 실선,5 픽 셀 공백,20 픽 셀 실선,10 픽 셀 공백 으로 구 성 된 점선 구간 이다.
다른 매개 변 수 는 오프셋 을 대표 합 니 다.보통 우 리 는 0 으로 설정 하면 됩 니 다.점선 의 애니메이션 효 과 를 실현 하려 면 이 값 을 계속 바 꾸 어 점선 을 움 직 일 수 있 습 니 다.
이 어 이 사용자 정의 View 를 실현 하고 위 xml 파일 의 점선(View)을 대체 하면 됩 니 다.

public class DashLineView extends View {

 private Paint mPaint;

 public DashLineView(Context context, AttributeSet attrs) {
 super(context, attrs);

 mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
 mPaint.setColor(getResources().getColor(R.color.dash_line));
 mPaint.setStrokeWidth(3);
 mPaint.setPathEffect(new DashPathEffect(new float[] {5, 5}, 0));

 }

 @Override
 protected void onDraw(Canvas canvas) {
 int centerY = getHeight() / 2;
 canvas.drawLine(0, centerY, getWidth(), centerY, mPaint);
 }
}
코드 가 달 린 후에 점선 이 직선 으로 변 한 것 을 발견 하여 전혀 효과 가 없 었 다.위 에서 Shape Drawable 을 사용 한 경험 이 있 으 면 우 리 는 이것 이 하드웨어 가속 으로 인 한 것 이 라 고 추측 할 이유 가 있 습 니 다.공식 문서 하드웨어 가속 에 있어 하드웨어 가속 으로 인 한 것 임 을 알 수 있 습 니 다.
(PS:사실 실제 상황 은 제 가 먼저 View 를 사용자 정의 한 후에 야 Shape Drawable 이 점선 효과 가 없다 는 것 을 알 게 된 것 도 하드웨어 가속 으로 인 한 것 일 수 있 습 니 다.)

onDraw 방법 을 다시 수정 합 니 다.다시 운행 한 후에 점선 이 정상적으로 나 타 났 다.

@Override
protected void onDraw(Canvas canvas) {
 int centerY = getHeight() / 2;
 setLayerType(LAYER_TYPE_SOFTWARE, null);
 canvas.drawLine(0, centerY, getWidth(), centerY, mPaint);
}
shape Drawable 과 drawLine 방법 을 사용 하면 허 선의 효 과 를 실현 할 수 있 지만 하드웨어 가속 을 지원 하지 않 는 다 는 단점 도 뚜렷 하 다.위의 코드 는 간단 하기 때문에 끊 기 는 문 제 를 일 으 키 지 않 습 니 다.그러나 사용자 정의 View 가 복잡 합 니 다.예 를 들 어 사용자 가 사각형 상 자 를 그 릴 때 사용자 가 끌 어 낸 도형 이 정사각형 이 라면 우 리 는 대각 점선 을 그 려 서 사용자 에 게 알려 줍 니 다.이런 상황 에서 하드웨어 가속 을 지원 하지 않 는 단점 이 드 러 날 수 있다.다행히 우 리 는 점선 을 그 리 는 다른 방법 이 있다.setPath Effect 방법 은 직선 을 지원 하지 않 을 뿐 입 니 다.직선 을 그 리 는 다른 방법 이 있 는 지 찾 아 보 겠 습 니 다.drawPath 는 여러 가지 경 로 를 그 릴 수 있 습 니 다.물론 직선 을 그 려 줄 수도 있 습 니 다.큰 인재 가 있다 고 하지만 소 용이 있 습 니 다.
코드 를 어떻게 쓰 는 지 다시 보 자.

public class DashLineView extends View {

 private Paint mPaint;
 private Path mPath;

 public DashLineView(Context context, AttributeSet attrs) {
 super(context, attrs);

 mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
 mPaint.setColor(getResources().getColor(R.color.dash_line));
 //       ,       
 mPaint.setStyle(Paint.Style.STROKE);
 mPaint.setStrokeWidth(3);
 mPaint.setPathEffect(new DashPathEffect(new float[] {15, 5}, 0));

 mPath = new Path();
 }

 @Override
 protected void onDraw(Canvas canvas) {
 int centerY = getHeight() / 2;
 mPath.reset();
 mPath.moveTo(0, centerY);
 mPath.lineTo(getWidth(), centerY);
 canvas.drawPath(mPath, mPaint);
 }
}
setLayerType(LAYER_TYPE_SOFTWARE, null);이 코드 를 제거 한 후에 도 점선 을 그 려 하드웨어 가속 을 지원 한 다 는 것 을 증명 한다.
이로써 우 리 는 이미 점선 의 그리 기 를 완벽 하 게 실현 하 였 으 나,이 글 은 아직 끝나 지 않 았 다!우리 가 그린 점선 은 옹 골 진 사각형 이다.만약 우리 가 이것 을 옹 골 진 원형 으로 구성 하 라 고 요구한다 면?아니면 다른 도형 으로 구 성 된 건 가요?이 럴 때 우 리 는 PathDashPathEffect 로 실현 할 수 있 습 니 다.잘 보 세 요.DashPathEffect 가 아니 라 PathPathEffect 입 니 다!PathDashPathEffect 는 허 선의 스타일 을 정의 하 는 경 로 를 추가 할 수 있 습 니 다.우 리 는setPathEffect()을 고 쳐 서 효 과 를 보 았 다.

Path path = new Path();
path.addCircle(0, 0, 3, Path.Direction.CW);
mPaint.setPathEffect(new PathDashPathEffect(path, 15, 0, PathDashPathEffect.Style.ROTATE));
사실 원형 으로 이 루어 진 점선 도 예 쁘 잖 아 요.점선 그리 기 는 여기까지 입 니 다.하지만 이 점선 에 효 과 를 더 해 달라 면 요?예 를 들 어 점선 은 중간 에서 완전히 불투명 하고 양쪽 은 점점 투명 해진 다.때 리 고 싶 은 거 아니 야,못 쓰 는 것 도 아니 고,그렇게 많은 요 구 를 왜 해!어 쩔 수 없 지,무리하게 하 자.Paint 는 또 다른 방법 이 있 습 니 다.setShader(Shader shader) Shader 는 착색 기 라 고 이해 할 수 있 습 니 다.이 를 이용 하면 선형 변색 을 실현 할 수 있 습 니 다.코드 봐 봐.먼저.
효 과 를 살 리 기 위해 점선 의 색 을 검은색 으로 바 꿉 니 다.

//         
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
 super.onSizeChanged(w, h, oldw, oldh);

 //           ,         。
 // color          ->   ->   ->   。
 // float   color    :
 // 0 -> 0.3 (   ->  )
 // 0.3 - 0.7 (  ->  ,    )
 // 0.7 -> 1 (  ->   )
 mPaint.setShader(new LinearGradient(0, 0, getWidth(), 0,
  new int[] {Color.TRANSPARENT, Color.BLACK, Color.BLACK, Color.TRANSPARENT},
  new float[] {0, 0.3f, 0.7f, 1f}, Shader.TileMode.CLAMP));
}

효 과 는 괜 찮 잖 아.물론 그림 에 적용 되 는 이런 장면 은 아니 지.자,이번 에는 정말 다 했 습 니 다.점선 을 그 리 는 것 은 어렵 지 않 지만 주의해 야 할 부분(하드웨어 가속)이 있 습 니 다.그리고 다시 자세히 놀 겠 습 니 다.간단 하지만 수작 을 부 릴 수 있 습 니 다.
총결산
이상 은 이 글 의 전체 내용 입 니 다.본 논문 의 내용 이 여러분 의 안 드 로 이 드 개발 자 들 에 게 어느 정도 도움 이 되 기 를 바 랍 니 다.궁금 한 점 이 있 으 시 면 댓 글 을 남 겨 주 셔 서 저희 에 대한 지지 에 감 사 드 립 니 다.

좋은 웹페이지 즐겨찾기