착색 게임 으로 안 드 로 이 드 의 영역 그림 을 채 우 는 방법 을 설명 합 니 다.

20427 단어 Android색깔.
1.착색 게임 개요
최근 에 단체 에서 한 친구 가 단체 에서 불규칙 한 이미 지 를 채 우 는 것 을 우연히 보 았 는데 그 자체 가 배 우 는 것 을 좋아 하고 실 용적 인 태도 로 관련 자 료 를 찾 아 보 았 다.이런 착색 자료 에 대해 가장 좋 은 것 은 관련 app 을 검색 하 는 것 입 니 다.제 관찰 에 따 르 면 불규칙 한 이미 지 는 착색 게임 에 채 워 넣 는 것 이 많 지만 대체적으로 두 가지 로 나 눌 수 있 습 니 다.
  • 층 에 기반 한 충전
  • 경계 기반 충전그러면 상기 두 가지 에 대해 우 리 는 두 편의 박문 을 통 해 설명 할 것 이다.본 편 은 바로 층 을 바탕 으로 하 는 충전 방식 을 서술 하 는 것 이다.그러면 층 을 바탕 으로 하 는 충전 방식 은 무엇 입 니까?사실은 한 장의 그림 은 실제 적 으로 여러 층 으로 구 성 된 것 으로 각 층 은 일부 이미지(이미지 가 없 는 부분 은 투명)를 표시 하고 다 층 으로 중첩 한 후에 완전한 도안 을 형성 하 며 그림 층 간 은 중첩 되 는 관계 로 다음 그림 과 유사 하 다.
    2016229153022966.jpg (481×227)
    PS 를 배 웠 다 면 더 이상 알 수 없 을 것 이 라 고 믿 습 니 다.예 를 들 어 하늘 을 그 리 려 면 맨 밑 에 푸 른 하늘 을 그 릴 수 있 고 윗 층 에 흰 구름 을 그 릴 수 있 으 며 윗 층 에 작은 새 를 그 릴 수 있다.그리고 3 층 이 겹 쳐 지면 작은 새 한 마리 가 하늘 을 날 고 있 는 그림 이다.
    2.효과 와 분석
    자,이제 오늘 의 효 과 를 보 겠 습 니 다.
    2016229153049956.gif (375×330)
    ok,간단 한 착색 효 과 를 볼 수 있 습 니 다.사실은 원리 가 간단 합 니 다.우선,이 그림 은 실제 적 으로 7 층 으로 구성 되 어 있 습 니 다.
    예 를 들 어 다음 그림.
    2016229153109362.jpg (1306×890)
    만약 우리 가 이 그림 의 어느 위치 에 착색 을 해 야 한다 면,실제로는 한 층 의 불투명 한 구역 에 착색 을 해 야 한다.실제로
    사용자 가 클릭 한(x,y)->어느 층 에 떨 어 진 불투명 영역 을 판단 합 니 다->그리고 이 층 의 불투명 영역 에 착색 합 니 다.
    ok,이러한 원 리 는 명확 하 게 서술 할 수 있 습 니 다.사실은 매우 간단 합 니 다.이 원 리 를 바탕 으로 우 리 는 View 를 사용자 정의 한 다음 에 그림 을 그 릴 수 있 습 니 다.마지막 으로 상기 절차 에 따라 코드 를 작성 할 수 있 습 니 다.그러나 우 리 는 게 으 름 을 피 울 수 있 는 곳 이 있 습 니 다.사실은 우리 가 한 층 의 그림 을 그 릴 필요 가 없습니다.우 리 는 Drawable 을 이용 하여 그림 의 중첩 작업 을 완성 할 수 있 습 니 다.우 리 는 Drawable 을 Layer Drawable 이 라 고 부 릅 니 다.해당 하 는 xml 는 layer-list 입 니 다.우 리 는 Layer Drawable 을 사용 하여 우리 의 작업 을 크게 간소화 할 수 있 습 니 다.
    3.인 코딩 과 실현
    상술 한 것 은 이미 명확 하 게 묘사 되 었 으 니,제 가 다시 여러분 께 세분 화 해 드 리 겠 습 니 다.
    layer-list 에서 우리 의 drawable 을 정의 합 니 다.
    그리고 이 drawable 을 저희 View 의 배경 으로 삼 겠 습 니 다.
    복사 onTouchEvent 방법
    사용자 가 클릭 한 좌표 가 어느 층 의 불투명 한 위치 에 떨 어 졌 는 지 판단 하고 이 층 의 불투명 한 영역 색 을 바 꿉 니 다.
    (1)layer-list
    
     <?xml version="1.0" encoding="utf-8"?>
    <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
     <item
      android:drawable="@drawable/eel_mask1"/>
     <item
      android:drawable="@drawable/eel_mask2"/>
     <item
      android:drawable="@drawable/eel_mask3"/>
     <item
      android:drawable="@drawable/eel_mask4"/>
     <item
      android:drawable="@drawable/eel_mask5"/>
     <item
      android:drawable="@drawable/eel_mask6"/>
     <item
      android:drawable="@drawable/eel_mask7"/>
    </layer-list>
    
    
    ok,그러면 우리 drawable 은 ok~~말 안 했 지만 layer-list 는 많은 일 을 할 수 있 으 니 지 켜 보 세 요.
    (2)보기 코드
    
    package com.zhy.colour_app_01;
    
    import android.content.Context;
    import android.graphics.Bitmap;
    import android.graphics.Color;
    import android.graphics.PorterDuff;
    import android.graphics.drawable.BitmapDrawable;
    import android.graphics.drawable.Drawable;
    import android.graphics.drawable.LayerDrawable;
    import android.util.AttributeSet;
    import android.util.Log;
    import android.view.MotionEvent;
    import android.view.View;
    
    import java.util.Random;
    
    /**
     * Created by zhy on 15/5/14.
     */
    public class ColourImageBaseLayerView extends View
    {
    
     private LayerDrawable mDrawables;
    
     public ColourImageBaseLayerView(Context context, AttributeSet attrs)
     {
      super(context, attrs);
      mDrawables = (LayerDrawable) getBackground();
    
     }
    
     @Override
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
     {
      setMeasuredDimension(mDrawables.getIntrinsicWidth(), mDrawables.getIntrinsicHeight());
     }
    
     @Override
     public boolean onTouchEvent(MotionEvent event)
     {
      final float x = event.getX();
      final float y = event.getY();
      if (event.getAction() == MotionEvent.ACTION_DOWN)
      {
       Drawable drawable = findDrawable(x, y);
       if (drawable != null)
        drawable.setColorFilter(randomColor(), PorterDuff.Mode.SRC_IN);
      }
    
      return super.onTouchEvent(event);
     }
    
     private int randomColor()
     {
      Random random = new Random();
      int color = Color.argb(255, random.nextInt(256), random.nextInt(256), random.nextInt(256));
      return color;
     }
    
     private Drawable findDrawable(float x, float y)
     {
      final int numberOfLayers = mDrawables.getNumberOfLayers();
      Drawable drawable = null;
      Bitmap bitmap = null;
      for (int i = numberOfLayers - 1; i >= 0; i--)
      {
       drawable = mDrawables.getDrawable(i);
       bitmap = ((BitmapDrawable) drawable).getBitmap();
       try
       {
        int pixel = bitmap.getPixel((int) x, (int) y);
        if (pixel == Color.TRANSPARENT)
        {
         continue;
        }
       } catch (Exception e)
       {
        continue;
       }
       return drawable;
      }
      return null;
     }
    
    }
    
    
    ok,코드 도 간단 합 니 다.먼저 drawable 을 view 의 배경 으로 한 다음 에 구조 에서 drawable(Layer Drawable)을 가 져 옵 니 다.다음 에 onTouchEvent 를 복사 하고 사용자 가 클릭 한(x,y)을 캡 처 합 니 다.(x,y)에 따라 현재 클릭 한 층 이 어느 층 인지 찾 습 니 다.(비 투명 영역 에서 클릭 해 야 합 니 다)마지막 으로 setColorFilter 설정 을 통 해 색상 을 바 꾸 면 됩 니 다.easy 죠?마지막 으로 레이아웃 파일 을 붙 입 니 다.
    (3)레이아웃 파일
    
    <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"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        android:paddingBottom="@dimen/activity_vertical_margin"
        tools:context=".MainActivity">
    
     <com.zhy.colour_app_01.ColourImageBaseLayerView
      android:background="@drawable/eel"
      android:layout_width="match_parent"
      android:layout_centerInParent="true"
      android:layout_height="match_parent"/>
    
    </RelativeLayout>
    
    
    4.경계 채 우기
    1.그림 의 충전 에는 두 가지 고전 알고리즘 이 있 습 니 다.
    하 나 는 피 드 충전 법 이다.피 드 충전 법 이론 적 으로 임의의 구역 과 도형 을 채 울 수 있 지만 이런 알고리즘 은 대량의 반복 적 인 스 택 과 대규모 재 귀 가 존재 하여 충전 효율 을 낮 출 수 있다.
    다른 하 나 는 스캐닝 라인 충전 법 이다.
    메모:실제로 이미지 채 우 는 알고리즘 이 많 습 니 다.관심 이 있 으 면 Google 학술 지 를 찾 아 보 세 요.
    ok,다음은 효과 도 를 살 펴 보 겠 습 니 다.
    2016229153312837.gif (447×699)
    ok,이런 컬러 충전 이 전편 의 베이스 층 보다 소재 준비 에 있어 서 훨씬 쉬 운 것 을 볼 수 있 습 니 다~~~
    2.원리 분석
    먼저 원 리 를 약술 하고 우 리 는 클릭 할 때 클릭 점 의'색'을 얻 은 다음 에 우리 가 선택 한 알고리즘 에 따라 색 을 채 우 면 된다.
    알고리즘 1:피 드 충전 법,4 연결/8 연결
    알고리즘 소개:어떤 영역 을 빨간색 으로 채 우 겠 다 고 가정 합 니 다.
    사용자 가 클릭 한 픽 셀 을 시작 으로 상하 좌우(8 연 결 된 왼쪽 위,왼쪽 아래,오른쪽 위,오른쪽 아래)로 색상 을 판단 하고 네 방향 에 있 는 색상 이 현재 클릭 한 픽 셀 과 일치 하면 색상 을 대상 색 으로 변경 합 니 다.그리고 이 과정 을 계속 하 겠 습 니 다.
    ok,이것 은 재 귀적 인 과정 을 볼 수 있 습 니 다.1 개 에서 4 개,4 개 에서 16 개 까지 계속 연장 되 는 것 을 볼 수 있 습 니 다.만약 이러한 알고리즘 에 따른다 면,당신 은 이러한 코드 를 쓸 것 입 니 다.
    
    /**
      * @param pixels     
      * @param w    
      * @param h    
      * @param pixel       
      * @param newColor    
      * @param i     
      * @param j     
      */
     private void fillColor01(int[] pixels, int w, int h, int pixel, int newColor, int i, int j)
     {
      int index = j * w + i;
      if (pixels[index] != pixel || i >= w || i < 0 || j < 0 || j >= h)
       return;
      pixels[index] = newColor;
      // 
      fillColor01(pixels, w, h, pixel, newColor, i, j - 1);
      // 
      fillColor01(pixels, w, h, pixel, newColor, i + 1, j);
      // 
      fillColor01(pixels, w, h, pixel, newColor, i, j + 1);
      // 
      fillColor01(pixels, w, h, pixel, newColor, i - 1, j);
     }
    
    
    코드 는 간단 하지만 실행 하면 StackOverflow Exception 이상 이 발생 합 니 다.이 이상 은 주로 대량의 재 귀 로 인 한 것 입 니 다.간단 하지만 모 바 일 기기 에서 이 방법 을 사용 하면 안 된다.
    그래서 저 는 이 방법 이 재 귀 깊이 가 너무 많은 것 이 아니 라 Stack 을 사용 하여 픽 셀 점 을 저장 하고 재 귀 깊이 와 횟수 를 줄 일 수 있다 고 생각 했 습 니 다.그래서 저 는 코드 를 다음 과 같은 방식 으로 바 꿀 수 있 습 니 다.
    
    /**
      * @param pixels     
      * @param w    
      * @param h    
      * @param pixel       
      * @param newColor    
      * @param i     
      * @param j     
      */
     private void fillColor(int[] pixels, int w, int h, int pixel, int newColor, int i, int j)
     {
      mStacks.push(new Point(i, j));
    
      while (!mStacks.isEmpty())
      {
       Point seed = mStacks.pop();
       Log.e("TAG", "seed = " + seed.x + " , seed = " + seed.y);
    
       int index = seed.y * w + seed.x;
    
       pixels[index] = newColor;
       if (seed.y > 0)
       {
        int top = index - w;
        if (pixels[top] == pixel)
        {
    
         mStacks.push(new Point(seed.x, seed.y - 1));
        }
       }
    
       if (seed.y < h - 1)
       {
        int bottom = index + w;
        if (pixels[bottom] == pixel)
        {
         mStacks.push(new Point(seed.x, seed.y + 1));
        }
       }
    
       if (seed.x > 0)
       {
        int left = index - 1;
        if (pixels[left] == pixel)
        {
         mStacks.push(new Point(seed.x - 1, seed.y));
        }
       }
    
       if (seed.x < w - 1)
       {
        int right = index + 1;
        if (pixels[right] == pixel)
        {
         mStacks.push(new Point(seed.x + 1, seed.y));
        }
       }
    
      }
    
    
     }
    
    
    방법의 사상 도 비교적 간단 하 다.현재 픽 셀 을 창고 에 넣 은 다음 에 창고 에서 착색 한 다음 에 각각 네 가지 방향 을 판단 하고 조건 에 부합 하면 창고 에 들어간다(창고 가 비어 있 지 않 으 면 지속 적 으로 운행 한다).ok,이 방법 은 저도 뛰 어 보 려 고 했 습 니 다.네,이번 에는 틀 리 지 않 을 겁 니 다.하지만 속도 가 너무 느 려 요~~느 려 서 받 아들 일 수 없습니다.관심 이 있 으 면 시도 해 보 세 요.ANR 이 라면 기 다 려 보 세 요).
    이렇게 보면 첫 번 째 알고리즘 은 우리 가 고려 하지 않 고 사용 할 방법 이 없다.주요 원인 은 사각형 의 같은 색 구역 에 대해 모두 채 워 야 한다 고 가정 하 는 것 이 고 알고리즘 하 나 는 여전히 각종 스 택 이다.그래서 두 번 째 알고리즘 을 고려 합 니 다.
    스캐닝 라인 충전 법
    스캐너 피 드 충전 알고리즘 의 해석 과 스캐너 피 드 충전 알고리즘 을 참고 할 수 있 습 니 다.
    알고리즘 사상:
    피 드 점 을 저장 하기 위해 빈 스 택 을 초기 화하 고 피 드 점(x,y)을 스 택 에 넣 습 니 다.
    스 택 이 비어 있 는 지 여 부 를 판단 합 니 다.스 택 이 비어 있 으 면 알고리즘 을 끝 냅 니 다.그렇지 않 으 면 스 택 꼭대기 요 소 를 현재 스 캔 라인 의 피 드 점(x,y)으로 꺼 내 고 y 는 현재 스 캔 라인 입 니 다.
    피 드 점(x,y)에서 출발 하여 현재 스캐닝 라인 을 따라 왼쪽,오른쪽 두 방향 으로 경계 까지 채 웁 니 다.구간 의 왼쪽,오른쪽 점 좌 표를 각각 xLeft 와 xRight 로 표시 합 니 다.
    현재 스 캔 라인 과 인접 한 y-1 과 y+1 두 개의 스 캔 라인 이 구간[xLeft,xRight]에 있 는 픽 셀 을 각각 검사 하고 xRight 부터 xLeft 방향 으로 검색 합 니 다.스 캔 구간 이 AAABAAC(A 는 피 드 점 색상)이 라 고 가정 하면 B 와 C 앞의 A 를 피 드 점 으로 스 택 에 누 른 다음(2)단계 로 돌아 갑 니 다.
    상기 참고 문헌[4]을 참고 하여 수정 을 했 습 니 다.글[4]에서 알고리즘 을 설명 하고 테스트 에 문제 가 있어 서 수정 을 했 습 니 다.
    이 알고리즘 을 볼 수 있 습 니 다.기본적으로 한 줄 한 줄 착색 되 어 있 습 니 다.그러면 큰 덩어리 에 착색 이 필요 한 구역 의 효율 이 알고리즘 보다 훨씬 높 습 니 다.
    ok,알고리즘 에 대한 절차 가 모호 하 다 고 생각 합 니 다.잠시 후에 저희 코드 를 참조 할 수 있 습 니 다.알고리즘 을 선택 한 후 인 코딩 을 시작 합 니 다.
    3.인 코딩 실현
    우리 코드 에 경계 색 을 도 입 했 습 니 다.설정 하면 착색 경 계 는 이 경계 색 을 참고 합 니 다.그렇지 않 으 면 피 드 색 과 일치 하지 않 으 면 경계 색 이 됩 니 다.
    (1)구조 방법 과 측정
    
    public class ColourImageView extends ImageView
    {
    
     private Bitmap mBitmap;
     /**
      *      
      */
     private int mBorderColor = -1;
    
     private boolean hasBorderColor = false;
    
     private Stack<Point> mStacks = new Stack<Point>();
    
     public ColourImageView(Context context, AttributeSet attrs)
     {
      super(context, attrs);
    
      TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.ColourImageView);
      mBorderColor = ta.getColor(R.styleable.ColourImageView_border_color, -1);
      hasBorderColor = (mBorderColor != -1);
    
      L.e("hasBorderColor = " + hasBorderColor + " , mBorderColor = " + mBorderColor);
    
      ta.recycle();
    
     }
    
     @Override
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
     {
      super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    
      int viewWidth = getMeasuredWidth();
      int viewHeight = getMeasuredHeight();
    
      //      ,     view   
      setMeasuredDimension(viewWidth,
        getDrawable().getIntrinsicHeight() * viewWidth / getDrawable().getIntrinsicWidth());
      L.e("view's width = " + getMeasuredWidth() + " , view's height = " + getMeasuredHeight());
    
      //  drawable,      view     bitmap
      BitmapDrawable drawable = (BitmapDrawable) getDrawable();
      Bitmap bm = drawable.getBitmap();
      mBitmap = Bitmap.createScaledBitmap(bm, getMeasuredWidth(), getMeasuredHeight(), false);
     }
    
    
    이미지 뷰 계승 을 선택 한 것 을 볼 수 있 습 니 다.그림 을 src 로 설정 하면 됩 니 다.
    구조 방법 에서 사용자 정의 경계 색 을 가 져 옵 니 다.당연히 설정 하지 않 아 도 됩 니 다~~
    재 작성 측정 의 목적 은 View 와 같은 크기 의 Bitmap 를 얻 기 위해 서 입 니 다.
    이제 클릭 입 니 다.
    4.onTouchEvent
    
    @Override
     public boolean onTouchEvent(MotionEvent event)
     {
      final int x = (int) event.getX();
      final int y = (int) event.getY();
      if (event.getAction() == MotionEvent.ACTION_DOWN)
      {
       //  
       fillColorToSameArea(x, y);
      }
    
      return super.onTouchEvent(event);
     }
    
     /**
      *   x,y      ,    
      *
      * @param x
      * @param y
      */
     private void fillColorToSameArea(int x, int y)
     {
      Bitmap bm = mBitmap;
    
      int pixel = bm.getPixel(x, y);
      if (pixel == Color.TRANSPARENT || (hasBorderColor && mBorderColor == pixel))
      {
       return;
      }
      int newColor = randomColor();
    
      int w = bm.getWidth();
      int h = bm.getHeight();
      //   bitmap     
      int[] pixels = new int[w * h];
      bm.getPixels(pixels, 0, w, 0, 0, w, h);
      //  
      fillColor(pixels, w, h, pixel, newColor, x, y);
      //    bitmap
      bm.setPixels(pixels, 0, w, 0, 0, w, h);
      setImageDrawable(new BitmapDrawable(bm));
    
     }
    
    
    볼 수 있 습 니 다.우 리 는 onTouchEvent 에서(x,y)를 얻 은 다음 에 변 경 된 좌 표를 얻 을 수 있 습 니 다.
    클릭 점 색상 을 획득 하여 전체 bitmap 의 픽 셀 그룹 을 획득 합 니 다.
    이 배열 의 색 을 바 꿉 니 다.
    그리고 bitmap 에 다시 설정 하고 ImageView 에 다시 설정 합 니 다.
    포 인 트 는 fillColor 를 통 해 배열 의 색 을 바 꾸 는 것 입 니 다.
    
    /**
      * @param pixels     
      * @param w    
      * @param h    
      * @param pixel       
      * @param newColor    
      * @param i     
      * @param j     
      */
     private void fillColor(int[] pixels, int w, int h, int pixel, int newColor, int i, int j)
     {
      //  1:    (x, y)  ;
      mStacks.push(new Point(i, j));
    
      //  2:       ,
      //           ,                   (x, y),
      // y       ;
      while (!mStacks.isEmpty())
      {
    
    
       /**
        *   3:    (x, y)  ,        、       ,
        *     。        、      xLeft xRight;
        */
       Point seed = mStacks.pop();
       //L.e("seed = " + seed.x + " , seed = " + seed.y);
       int count = fillLineLeft(pixels, pixel, w, h, newColor, seed.x, seed.y);
       int left = seed.x - count + 1;
       count = fillLineRight(pixels, pixel, w, h, newColor, seed.x + 1, seed.y);
       int right = seed.x + count;
    
    
       /**
        *   4:
        *              y - 1 y + 1        [xLeft, xRight]    ,
        *  xRight   xLeft    ,        AAABAAC(A      ),
        *    B C   A         ,     (2) ;
        */
       // y-1   
       if (seed.y - 1 >= 0)
        findSeedInNewLine(pixels, pixel, w, h, seed.y - 1, left, right);
       // y+1   
       if (seed.y + 1 < h)
        findSeedInNewLine(pixels, pixel, w, h, seed.y + 1, left, right);
      }
    
    
     }
    
    
    내 가 이 알고리즘 의 네 가지 절 차 를 이 방법 에 명확 하 게 표시 한 것 을 볼 수 있다.자,마지막 으로 의존 하 는 세부 적 인 방법 입 니 다.
    
     /**
      *         
      *
      * @param pixels
      * @param pixel
      * @param w
      * @param h
      * @param i
      * @param left
      * @param right
      */
     private void findSeedInNewLine(int[] pixels, int pixel, int w, int h, int i, int left, int right)
     {
      /**
       *          
       */
      int begin = i * w + left;
      /**
       *          
       */
      int end = i * w + right;
    
      boolean hasSeed = false;
    
      int rx = -1, ry = -1;
    
      ry = i;
    
      /**
       *  end begin,        (AAABAAAB, B  A     )
       */
      while (end >= begin)
      {
       if (pixels[end] == pixel)
       {
        if (!hasSeed)
        {
         rx = end % w;
         mStacks.push(new Point(rx, ry));
         hasSeed = true;
        }
       } else
       {
        hasSeed = false;
       }
       end--;
      }
     }
    
     /**
      *     ,       
      *
      * @return
      */
     private int fillLineRight(int[] pixels, int pixel, int w, int h, int newColor, int x, int y)
     {
      int count = 0;
    
      while (x < w)
      {
       //    
       int index = y * w + x;
       if (needFillPixel(pixels, pixel, index))
       {
        pixels[index] = newColor;
        count++;
        x++;
       } else
       {
        break;
       }
    
      }
    
      return count;
     }
    
    
     /**
      *     ,        
      *
      * @return
      */
     private int fillLineLeft(int[] pixels, int pixel, int w, int h, int newColor, int x, int y)
     {
      int count = 0;
      while (x >= 0)
      {
       //     
       int index = y * w + x;
    
       if (needFillPixel(pixels, pixel, index))
       {
        pixels[index] = newColor;
        count++;
        x--;
       } else
       {
        break;
       }
    
      }
      return count;
     }
    
     private boolean needFillPixel(int[] pixels, int pixel, int index)
     {
      if (hasBorderColor)
      {
       return pixels[index] != mBorderColor;
      } else
      {
       return pixels[index] == pixel;
      }
     }
    
     /**
      *         
      *
      * @return
      */
     private int randomColor()
     {
      Random random = new Random();
      int color = Color.argb(255, random.nextInt(256), random.nextInt(256), random.nextInt(256));
      return color;
     }
    
    
    ok,여기까지 코드 소개 완료~~~
    마지막 으로 레이아웃 파일 을 붙 여 주세요~~
    
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:zhy="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        android:paddingBottom="@dimen/activity_vertical_margin"
        tools:context=".MainActivity">
     <com.zhy.colour_app_01.ColourImageView
      zhy:border_color="#FF000000"
      android:src="@drawable/image_007"
      android:background="#33ff0000"
      android:layout_width="match_parent"
      android:layout_centerInParent="true"
      android:layout_height="match_parent"/>
    
    </RelativeLayout>
    
    
    <?xml version="1.0" encoding="utf-8"?>
    <resources>
     <declare-styleable name="ColourImageView">
      <attr name="border_color" format="color|reference"></attr>
     </declare-styleable>
    </resources>
    

    좋은 웹페이지 즐겨찾기