Android 사용자 정의 View 접선 도 효과 구현
1.홈 페이지 레이아웃 파일 은 다음 과 같 습 니 다.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
xmlns:app="http://schemas.android.com/apk/res/ting.example.linecharview">
<ting.example.linecharview.LineCharView
android:id="@+id/test"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:xytextcolor="@color/bg"
app:xytextsize="20sp"
app:interval="80dp"
/>
</RelativeLayout>
그 중에서linecharview
는 사용자 정의View
이 고app:xx
는 바로 이View
의 각종 속성 이다.2.
values
의 attrs 파일 에 다음 과 같은 xml 를 추가 하여linecharview
의 각종 속성 을 정의 합 니 다.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="LineChar">
<attr name="xylinecolor" format="color"/><!-- xy -->
<attr name="xylinewidth" format="dimension"/><!-- xy -->
<attr name="xytextcolor" format="color"/><!-- xy -->
<attr name="xytextsize" format="dimension"/><!-- xy -->
<attr name="linecolor" format="color"/><!-- -->
<attr name="interval" format="dimension"/><!-- x -->
<attr name="bgcolor" format="color"/><!-- -->
</declare-styleable>
</resources>
3.다음 에 개 류LineCharView
계승View
을 구축 하고 다음 과 같은 변 수 를 설명 한다.
<span style="white-space:pre"> </span>private int xori;// x
private int yori;// y
private int xinit;// x
private int minXinit;// , x
private int maxXinit;// , x
private int xylinecolor;//xy
private int xylinewidth;//xy
private int xytextcolor;//xy
private int xytextsize;//xy
private int linecolor;//
private int interval;//
private int bgColor;//
private List<String> x_coords;//x
private List<String> x_coord_values;//
private int width;//
private int heigth;//
private int imageWidth;//
private float textwidth;//y
float startX=0;// , x
구조 함수 에서 각 속성 값 읽 기:
public LineCharView(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray typedArray= context.obtainStyledAttributes(attrs, R.styleable.LineChar);
xylinecolor=typedArray.getColor(R.styleable.LineChar_xylinecolor, Color.GRAY);
xylinewidth=typedArray.getInt(R.styleable.LineChar_xylinewidth, 5);
xytextcolor=typedArray.getColor(R.styleable.LineChar_xytextcolor, Color.BLACK);
xytextsize=typedArray.getLayoutDimension(R.styleable.LineChar_xytextsize, 20);
linecolor=typedArray.getColor(R.styleable.LineChar_linecolor, Color.GRAY);
interval=typedArray.getLayoutDimension(R.styleable.LineChar_interval, 100);
bgColor=typedArray.getColor(R.styleable.LineChar_bgcolor, Color.WHITE);
typedArray.recycle();
x_coords=new ArrayList<String>();
x_coord_values=new ArrayList<String>();
}
4.그 다음 에 다시 쓰기onLayout
방법 으로 컨트롤 의 너비 와 좌표 축의 원점 좌 표를 계산 할 수 있 습 니 다.좌표 축 원점 의 x 좌 표 는 y 축 문자 의 너비,y 축 너비 와 거리 y 의 수평 거 리 를 통 해 계산 할 수 있 습 니 다.여기 서 y 축 문 자 는 4 가지 상태(A,B,C,D)만 있 고 아래 의 방법 으로 원점 의 x 좌 표를 계산 할 수 있 습 니 다.
Paint paint=new Paint();
paint.setTextSize(xytextsize);
textwidth= paint.measureText("A");
xori=(int) (textwidth+6+2*xylinewidth);//6 y
원점 의 y 좌표 도 비슷 한 방법 으로 계산 할 수 있다.
yori=heigth-xytextsize-2*xylinewidth-3; //3 x ,heigth 。
보 여 줘 야 할 데이터 양 이 많 을 때 모두 보 여줄 수 없 을 때 미끄럼 접선 도 를 통 해 보 여 줘 야 합 니 다.우 리 는 첫 번 째 x 좌표 만 제어 하면 interval 이라는 속성 을 통 해 뒤의 각 점 의 좌 표를 계산 할 수 있 습 니 다.그러나 모든 데 이 터 를 인터페이스 밖으로 미 끄 러 뜨리 는 것 을 방지 하기 위해 서 는 미 끄 러 질 때 제어 해 야 합 니 다.사실은 첫 번 째 점 x 좌표 의 범 위 를 제어 하 는 것 이다.첫 번 째 점 의 x 좌표 의 최소 치 는 컨트롤 의 폭 을 통 해 원점 x 좌 표를 빼 고 모든 접선 그림 의 수평 거 리 를 줄 일 수 있다.코드 는 다음 과 같다.
minXinit=width-xori-x_coords.size()*interval;
컨트롤 은 기본적으로 첫 번 째 전시 에서 첫 번 째 점 과 y 축의 수평 거 리 는interval
의 절반 과 같 습 니 다.미 끄 러 질 때 첫 번 째 점 이 이 위치 에 나타 나 면 더 이상 오른쪽으로 미 끄 러 지 는 것 을 허용 하지 않 기 때문에 첫 번 째 점 x 좌표 의 최대 치 는 이 시작 x 좌 표를 기다 리 고 있 습 니 다.
xinit=interval/2+xori;
maxXinit=xinit;
다시 쓰기onLayout
방법의 코드 는 다음 과 같다.
@Override
protected void onLayout(boolean changed, int left, int top, int right,
int bottom) {
if(changed){
width=getWidth();
heigth=getHeight();
Paint paint=new Paint();
paint.setTextSize(xytextsize);
textwidth= paint.measureText("A");
xori=(int) (textwidth+6+2*xylinewidth);//6 y
yori=heigth-xytextsize-2*xylinewidth-3;//3 x
xinit=interval/2+xori;
imageWidth= BitmapFactory.decodeResource(getResources(), R.drawable.facea).getWidth();
minXinit=width-xori-x_coords.size()*interval;
maxXinit=xinit;
setBackgroundColor(bgColor);
}
super.onLayout(changed, left, top, right, bottom);
}
5.그 다음 에 접 는 선,x 좌표 축 에 있 는 작은 원점 과 접 는 선 에 있 는 표정 을 그 릴 수 있 습 니 다.코드 는 다음 과 같 습 니 다:
// X , ,
@SuppressLint("ResourceAsColor")
private void drawX (Canvas canvas) {
Paint x_coordPaint =new Paint();
x_coordPaint.setTextSize(xytextsize);
x_coordPaint.setStyle(Paint.Style.FILL);
Path path=new Path();
// ,
for(int i=0;i<x_coords.size();i++){
int x=i*interval+xinit;
if(i==0){
path.moveTo(x, getYValue(x_coord_values.get(i)));
}else{
path.lineTo(x, getYValue(x_coord_values.get(i)));
}
x_coordPaint.setColor(xylinecolor);
canvas.drawCircle(x, yori, xylinewidth*2, x_coordPaint);
String text=x_coords.get(i);
x_coordPaint.setColor(xytextcolor);
canvas.drawText(text, x-x_coordPaint.measureText(text)/2, yori+xytextsize+xylinewidth*2, x_coordPaint);
}
x_coordPaint.setStyle(Paint.Style.STROKE);
x_coordPaint.setStrokeWidth(xylinewidth);
x_coordPaint.setColor(linecolor);
//
canvas.drawPath(path, x_coordPaint);
//
for(int i=0;i<x_coords.size();i++){
int x=i*interval+xinit;
canvas.drawBitmap(getYBitmap(x_coord_values.get(i)), x-imageWidth/2, getYValue(x_coord_values.get(i))-imageWidth/2, x_coordPaint);
}
// x
x_coordPaint.setStyle(Paint.Style.FILL);
x_coordPaint.setColor(bgColor);
x_coordPaint.setXfermode(new PorterDuffXfermode( PorterDuff.Mode.SRC_OVER));
RectF rectF=new RectF(0, 0, xori, heigth);
canvas.drawRect(rectF, x_coordPaint);
}
상기 코드 는 먼저x_coords
와x_coord_values
두 개의 List 집합 을 통 해 좌표 점,접 는 선,표정 을 그립 니 다.왼쪽으로 미 끄 러 질 때 좌표 점,접 는 선 을 Y 축의 왼쪽 에 그 릴 수 있 기 때문에 이 를 절단 해 야 합 니 다.그 중에서getYValue
와 getYBitmap 방법 은x_coord_values
의 값 으로 y 좌표 와 해당 하 는 표정 을 계산 할 수 있다.두 가지 방법 은 다음 과 같다.
// y
private float getYValue(String value)
{
if(value.equalsIgnoreCase("A")){
return yori-interval/2;
}
else if(value.equalsIgnoreCase("B")){
return yori-interval;
}
else if(value.equalsIgnoreCase("C")){
return (float) (yori-interval*1.5);
}
else if(value.equalsIgnoreCase("D")){
return yori-interval*2;
}else{
return yori;
}
}
//
private Bitmap getYBitmap(String value){
Bitmap bitmap=null;
if(value.equalsIgnoreCase("A")){
bitmap=BitmapFactory.decodeResource(getResources(), R.drawable.facea);
}
else if(value.equalsIgnoreCase("B")){
bitmap=BitmapFactory.decodeResource(getResources(), R.drawable.faceb);
}
else if(value.equalsIgnoreCase("C")){
bitmap=BitmapFactory.decodeResource(getResources(), R.drawable.facec);
}
else if(value.equalsIgnoreCase("D")){
bitmap=BitmapFactory.decodeResource(getResources(), R.drawable.faced);
}
return bitmap;
}
6.좌표 점,접 는 선,표정 을 그 렸 습 니 다.그 다음 에 간단 하면 x y 축 을 그 릴 수 있 습 니 다.x y 축 은 원점 좌표 만 확정 하면 매우 간단 합 니 다.코드 는 다음 과 같 습 니 다.
//
private void drawXY(Canvas canvas){
Paint paint=new Paint();
paint.setColor(xylinecolor);
paint.setStrokeWidth(xylinewidth);
canvas.drawLine(xori, 0, xori, yori, paint);
canvas.drawLine(xori, yori, width, yori, paint);
}
7.마지막 으로 Y 축의 좌표 작은 원점 과 y 축의 문 자 를 그 릴 수 있 습 니 다.
// Y
private void drawY(Canvas canvas){
Paint paint=new Paint();
paint.setColor(xylinecolor);
paint.setStyle(Paint.Style.FILL);
for(int i=1;i<5 ;i++){
canvas.drawCircle(xori, yori-(i*interval/2), xylinewidth*2, paint);
}
paint.setTextSize(xytextsize);
paint.setColor(xytextcolor);
canvas.drawText("D",xori-textwidth-6-xylinewidth , yori-(2*interval)+xytextsize/2, paint);
canvas.drawText("C",xori-textwidth-6-xylinewidth , (float) (yori-(1.5*interval)+xytextsize/2), paint);
canvas.drawText("B",xori-textwidth-6-xylinewidth , yori-interval+xytextsize/2, paint);
canvas.drawText("A",xori-textwidth-6-xylinewidth , (float) (yori-(0.5*interval)+xytextsize/2), paint);
}
8.상기 세 가지 방법 을 다 썼 습 니 다.다시 쓰기onDraw
방법 만 있 으 면 그 릴 수 있 습 니 다.
@Override
protected void onDraw(Canvas canvas) {
drawX(canvas);
drawXY(canvas);
drawY(canvas);
}
9.수평 으로 미 끄 러 지기 위해 서 는 컨트롤 의 onTouchEvent 방법 을 다시 써 야 합 니 다.미 끄 러 질 때 손가락 이 미 끄 러 지 는 거 리 를 실시 간 으로 계산 하여 첫 번 째 점 의 x 좌 표를 바 꾼 다음 에 호출invalidate();
하면 컨트롤 을 새로 고 쳐 서 미 끄 러 지 는 효 과 를 얻 을 수 있 습 니 다.
@Override
public boolean onTouchEvent(MotionEvent event) {
// ,
if(interval*x_coord_values.size()<=width-xori){
return false;
}
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
startX=event.getX();
break;
case MotionEvent.ACTION_MOVE:
float dis=event.getX()-startX;
startX=event.getX();
if(xinit+dis>maxXinit){
xinit=maxXinit;
}else if(xinit+dis<minXinit){
xinit=minXinit;
}else{
xinit=(int) (xinit+dis);
}
invalidate();
break;
}
return true;
}
10.마지막 으로 데이터 원본 을 설정 하 는 방법 을 추가 합 니 다.설정x_coords
,x_coord_values
이 두 개List
를 집합 하고 설정 이 완 료 된 후에 호출invalidate()
하여 컨트롤 새로 고침 을 합 니 다.
/**
*
* @param x_coords
* @param x_coord_values
*/
public void setValue( List<String> x_coords ,List<String> x_coord_values) {
if(x_coord_values.size()!=x_coords.size()){
throw new IllegalArgumentException(" !");
}
this.x_coord_values=x_coord_values;
this.x_coords=x_coords;
invalidate();
}
총결산안 드 로 이 드 사용자 정의 뷰 가 접 힌 그림 효 과 를 실현 하 는 모든 내용 입 니 다.안 드 로 이 드 개발 에 도움 이 되 기 를 바 랍 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Kotlin의 기초 - 2부지난 글에서는 Kotlin이 무엇인지, Kotlin의 특징, Kotlin에서 변수 및 데이터 유형을 선언하는 방법과 같은 Kotlin의 기본 개념에 대해 배웠습니다. 유형 변환은 데이터 변수의 한 유형을 다른 데이터...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.