Android Studio 로 library 를 빌드 하다보면 META INF 파일에 쓸대 없는 내용들이 들어가서 문제가 생기는

경우가 있다.

Gradle script 에서 해당 내용을 exclude 해서 제거가 가능 함

Android task 내부에 아래와 같이 제거할 내용을 전부 작성 하면된다.
	packagingOptions {
    	exclude("META-INF/maven/com.squareup.okhttp/okhttp/pom.properties")
    }


'Android' 카테고리의 다른 글

Android HTTPS SHA128 인증서 오류  (0) 2017.02.08
Sharedpreferences 에 관하여  (0) 2015.04.04
Android QR code scan 부분  (0) 2014.09.21
Android QR code  (0) 2014.08.12
Android AsyncTask 함정 카드  (1) 2014.08.03

정확한 기간은 모르지만 HTTPS 에서 사용하는 SHA128 알고리즘 인증서를 더이상 갱신이 불가능한 이슈가 있는데,
WebView 에서 Https URL을 Load 하다보면 어떤 기기는 정상 동작 하지만 어떤 기기는 SSL exception이 나오는 경우가 있다.

단말과 상관없이 Google System webview 문제라고 생각 되어 관련 히스토리를 뒤적 뒤적 해보니 요런 재미난 이슈가 있었던거 같다.

WebView 53, 54 버전 일부에서 Symantec 인증서 관련된 페이지가 load 되지 않는 이슈 (https://www.chromium.org/developers/androidwebview/webview-ct-bug)

건내 받은 정보에 의하면 아래와 같은 버전에서 문제가 발생 한다고 한다.
  • 54.0.2840.85       November   2, 2016     문제 발생

  • 54.0.2840.68       October      20, 2016    문제 발생

  • 54.0.2840.61       October      13, 2016    문제 발생

  • 53.0.2785.124     September 17, 2016    문제 발생

  • 53.0.2785.121     September 16, 2016    문제 발생

  • 53.0.2785.113     September 14, 2016    문제 발생

  • 53.0.2785.97       September   8, 2016    문제 발생

그리고 추가로 Google system webview 가 없거나 사용 하지 않음 상태로 되어 있음에도 비슷한 문제가 나온다면,
Google Chrome 을 확인할 필요가 있다.


'Android' 카테고리의 다른 글

Gradle jar package exclude  (0) 2017.02.08
Sharedpreferences 에 관하여  (0) 2015.04.04
Android QR code scan 부분  (0) 2014.09.21
Android QR code  (0) 2014.08.12
Android AsyncTask 함정 카드  (1) 2014.08.03

Sharedpreferences  에 데이터를 쓸때는 쓸려는 원본 데이터가 byte type 인지 꼭 확인 해야함.

저장 형태가 xml 포멧이라 byte type 은 base64 encoding 해서 작성 해야 함,

특히 new String 으로 해서 데이터를 쓰는 경우가 종종 있는데 상당히 무식한 방법임.


특이점.

API Level 11 부터는 메모리에도 동시에 쓰고 있어서 put 이후 get을 하면 입력했던 값 그대로 나옴, 하지만 그 아래 버전들은 null을 벹어 줌.

'Android' 카테고리의 다른 글

Gradle jar package exclude  (0) 2017.02.08
Android HTTPS SHA128 인증서 오류  (0) 2017.02.08
Android QR code scan 부분  (0) 2014.09.21
Android QR code  (0) 2014.08.12
Android AsyncTask 함정 카드  (1) 2014.08.03
 QR code 생성 하기.
 2014/08/12 - [Android Study] - Android QR code

 이번에는 Scanner code 에 대해서 설명 해보도록 하겠음.
Camera preview 를 이용한 기법이므로 camera preview 정도는 가볍게 해결 해주셔야함.

 일단은 Camera preview callback 함수 부터.
     private Camera.PreviewCallback mPreviewCallback = new Camera.PreviewCallback() {
        // Frame 제한 시간
        private static final long FRAME_RATE_TIME = 200; // 200:5, 124:8, 100:10
        // Frame 체크용 시간 변수
        private long mCheckTime = 0;

        @Override
        public void onPreviewFrame(byte[] data, Camera camera) {
            boolean checkImage = false;
            // Frame 제한 시간을 넘는 경우에만 decode 작업을 수행
            if (mCheckTime == 0) {
                mCheckTime = System.currentTimeMillis();
                checkImage = true;
            } else {
                long current = System.currentTimeMillis();
                if (current - mCheckTime > FRAME_RATE_TIME) {
                    mCheckTime = current;
                    checkImage = true;
                }
            }

            if (checkImage == true) {
                mThread.insert(data, camera.getParameters().getPreviewSize());
            }
        }
    };


 코드 자체는 별 내용이 없고 Thread에 YUV 데이터를 전달 하는게 전부 인데, 시간 interval을 준 까닭은 Preview size가 너무 클 경우 YUV data 가 무지막지하게 커지는 경향이 있음.
 이럴 경우 decode에 과부하가 걸려서 Camera preview가 제대로 동작 안하고 버벅이는 현상이 발생함.

그다음 Thread 부분은.
    private class QRDecorderThread extends Thread {
        // Queue의 최대 값
        private static final int QUEUE_MAX = 3;
        // YUV data blocking queue
        private BlockingQueue<byte[]> mQueue;
        // UI 쪽에 data를 전달 할 Handler
        private Handler mHandler;
        // Preview size 변수
        private Camera.Size mSize;

        public QRDecorderThread(Handler handler) {
            mHandler = handler;
            mQueue = new ArrayBlockingQueue<byte[]>(QUEUE_MAX);
        }

        @Override
        public void run() {
            while (true) {
                try {
                    byte[] data = mQueue.take();

                    PlanarYUVLuminanceSource source = new PlanarYUVLuminanceSource(
                            data, mSize.width, mSize.height, 0, 0, mSize.width,
                            mSize.height, false);

                    BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(
                            source));

                    QRCodeReader reader = new QRCodeReader();

                    try {
                        Result result = reader.decode(bitmap);
                        String resultData = result.getText();
                        // 결과물이 있을 경우 preview 정지 및 UI 쪽에 data 전달
                        if (resultData != null) {
                            mCamera.stopPreview();
                            mHandler.sendMessage(mHandler.obtainMessage(0,
                                    resultData));
                        }
                    } catch (Exception e) {
                    }
                } catch (InterruptedException e) {
                    break;
                }
            }
        }

        public void insert(byte[] data, Camera.Size size) {
            try {
                mSize = size;
                mQueue.put(data);
            } catch (InterruptedException e) {
            }
        }
    }

사실은 저기 Thread 내부에서 새로 생성하는 class 들도 어떻게 잘 조절하면 new를 안하고 재활용 할 수 있을 듯한데...
음 거기까진 잘 모르겠음.
그리고 하나더 Camera parameter를 setting 할때 분명 preview에 대한 FrameRate를 설정 할 수 있는 걸로 알고 있는데 이것 또한
시도 해보지 않음...
여하튼 이런식으로 하면 동작하긴 함. 

'Android' 카테고리의 다른 글

Android HTTPS SHA128 인증서 오류  (0) 2017.02.08
Sharedpreferences 에 관하여  (0) 2015.04.04
Android QR code  (0) 2014.08.12
Android AsyncTask 함정 카드  (1) 2014.08.03
Android Custom Widget 만들기 7편  (0) 2012.04.12
 이번 주제는 QR 코드.
요즘은 기본적으로 QR code를 인식하는 다양한 방법 혹은 어플들이 있으니까, 나도 해봐야지.

우리에게 필요한 준비물은 Android SDK, Eclipse, QR code library 정도.

그리 잘 만든 코드는 아니지만 일단 스타드~

우선 QR code library 수집을 위해서 위대하신 우리 Google 느님에게 검색, 검색~
그리고 zxing 이란 녀석을 사용하기로 결정!!
URL : https://github.com/zxing

근데 이거 까보니 너무 많음 바코드도 있고... 기타 등등.. 그래서 귀찮으므로 QR 코드만 따로 빼서 새로 만듬
그리고 생각해보니 code 위주로 작성하는데 복사를 못하게 하면 난감해서 복사방지 풀음...


QR 코드 생성해서 ImageView에 보이도록 하는 부분.

    private class CreateQRCodeAsyncTask extends AsyncTask<String, Void, Bitmap> {
        // QR code 색상
        private static final int WHITE = 0xFFFFFFFF;
        private static final int BLACK = 0xFF000000;

        // QR code bitmap 크기 비율
        private static final float REDUCE_RATIO = 0.8f;

        // 타겟 image view
        private ImageView mTagetView;

        // 화면 크기
        private Point mDisplaySize;

        public CreateQRCodeAsyncTask (Imageview taget, Point displaySize) {
            mTagetView = taget;
            mDisplaySize = displaySize;
        }

        @Override
        protected Bitmap doInBackground(String... params) {
            // zxing library class (QR code writer)
            QRCodeWriter qrCodeWriter = new QRCodeWriter();

            try {
                // 화면 비율 대비 QR 코드 이미지 크기 조정
                int temp = mDisplaySize.x;

                if (temp > mDisplaySize.y) {
                    temp = mDisplaySize.y;
                }

                int dWidth = (int) ((float) temp * REDUCE_RATIO);
                int dHeight = (int) ((float) temp * REDUCE_RATIO);

                // QR code로 인코딩해서 비트맵 array 정보를 얻어옴 zxing 자체 class임
                BitMatrix result = qrCodeWriter.encode(params[0],
                        BarcodeFormat.QR_CODE, dWidth, dHeight);
                int width = result.getWidth();
                int height = result.getHeight();

                // Bitmap pixel array
                int[] pixels = new int[width * height];

                // BitMatrix 정보를 바탕으로 bitmap 픽셀 array 에 color 입력
                // All are 0, or black, by default
                for (int y = 0; y < height; y++) {
                    int offset = y * width;
                    for (int x = 0; x < width; x++) {
                        pixels[offset + x] = result.get(x, y) ? BLACK : WHITE;
                    }
                }

                // pixel array 크기의 bitmap 생성
                Bitmap bitmap = Bitmap.createBitmap(width, height,
                        Bitmap.Config.ARGB_8888);

                // bitmap에 pixel 정보 입력
                bitmap.setPixels(pixels, 0, width, 0, 0, width, height);

                return bitmap;
            } catch (Exception e) {
                return null;
            }
        }

        @Override
        protected void onPostExecute(Bitmap result) {
            if (result != null && mTagetView != null) {
                // image view 에 QR code 업데이트
                mTagetView.setImageBitmap(result );
                mTagetView.invalidate();
            }
        }
    }   

다음편에 스캔하는 code 설명을 이어가 겠음...





'Android' 카테고리의 다른 글

Sharedpreferences 에 관하여  (0) 2015.04.04
Android QR code scan 부분  (0) 2014.09.21
Android AsyncTask 함정 카드  (1) 2014.08.03
Android Custom Widget 만들기 7편  (0) 2012.04.12
Android Custom Widget 만들기 6편  (0) 2012.04.12
 우리가 Android 상에서 Thread 작업을 쉽게 할 수 있도록 class 되어 있는 아주 유용한 녀석이 있음.
AsyncTask 란 녀석인데 상속받아서 class를 작성하면 손쉽게 뼈대들을 만들어주고 내가 크게 관리할 필요 없이,
UI thread 쪽으로 메세지를 날려주는 아주 좋은 녀석이다.

그리고 class를 실행 시키는 방법이 2가지가 있는데 excute(...) 하고  executeOnExecutor(Executor, ...)  이다.
허니콤 이상 버전 부터는 excute로 동작하는 모든 AsyscTask 는 single thread로 동작한다.
즉 AsyncTask라고 여러개 선언하고 동작 시켜봤자 하나 끝나야 다른게 수행되는 그런 구조다.

반면 executeOnExecutor 는 원래 우리가 예상하고 기대했던 방식대로 동작한다.

여기까진 뭐 그냥 그렇거니 했는데 한 4달전에 개발 했던 application 에서 독특한 문제를 발견 했다.
AsyncTask 원본 class에 가면 이녀석을 생성 할 수 있는 max 값이 정해져 있다.

나는 6개를 생성했었는데 7번째 부터는 동작 자체를 안하는 버그가 있는 것이었다.
그래서 뒤져보니 저게 떡~ 하니 리미트가... 후...
그래서 나는 추천한다 정말 다양한 멀티 쓰레드가 필요하면 그냥 Thread class를 쓰고 UI 동작은 Handler로 처리하라고,
어차피 내부적으로 AsyncTask도 동일하게 동작한다.
Thread 동작을 수행하고 내부적으로 Handler 객체에 post 하는 방식을 취하고 있는 거니까....
 

'Android' 카테고리의 다른 글

Android QR code scan 부분  (0) 2014.09.21
Android QR code  (0) 2014.08.12
Android Custom Widget 만들기 7편  (0) 2012.04.12
Android Custom Widget 만들기 6편  (0) 2012.04.12
Android Custom Widget 만들기 5편  (0) 2012.04.12
전편은 여기
2012/04/12 - [Android Study] - Android Custom Widget 만들기 6편 

실전 사용 code
    // OnOffButtonActivity.java 내용
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        OnOffButton btn = (OnOffButton) findViewById(R.id.OnOffButton);
        btn.setOnButtonClickListener(new OnButtonClickListener() {
            @Override
            public void onResult(boolean onResult) {
                Toast.makeText(OnOffButtonActivity.this, "OnResult : " + onResult,
                       Toast.LENGTH_SHORT).show();
            }
        });
       // 초기 버튼을 off 상태로 설정
        btn.setOnOff(false);
    } 

    // main.xml 내용 
    // Widget class의 정확한 위치를 지정 해야 함
    <com.android.customwidget.OnOffButton
        android:id="@+id/OnOffButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/> 

이렇게 하고 나면 on off 상태 변경 혹은 animation 종료 시 toast 팝업이 발생 함.
후~ 이로써 custom widget은 끝은 아니고 일부 종료~ 

'Android' 카테고리의 다른 글

Android QR code  (0) 2014.08.12
Android AsyncTask 함정 카드  (1) 2014.08.03
Android Custom Widget 만들기 6편  (0) 2012.04.12
Android Custom Widget 만들기 5편  (0) 2012.04.12
Android Custom Widget 만들기 4편  (0) 2012.04.12
전편 필요한분 여기~
2012/04/12 - [Android Study] - Android Custom Widget 만들기 5편 

후 곧 마무리 지어 지을 수 있을듯.
 
    // 결과물 Listener에 전달 하는 함수
    private void onResult() {
       // Listener 객체가 null 이 아닐 경우만 호출
        if (mListener != null) mListener.onResult(mIsOn);
    }
    // Listener 등록 함수
    public void setOnButtonClickListener(OnButtonClickListener listener) {
        mListener = listener;
    }
    // on off toggle 함수
    public void toggleOnOff() {
        mHandler.sendEmptyMessage(ANIMATION_MESSAGE_START);
    }
    // on off setting 함수
    public void setOnOff(boolean isOn) {
        mIsOn = isOn;
       // 기본 값은 on 상태를 가정하고 설정
        int left = 0;
        int right = mMovementLimite;
       // off 상태 일때
        if (mIsOn == false) {
            left = mBtnWidth - mMovementLimite;
            right = mBtnWidth;
        }
       // button rect left, right 위치 지정
        mSource.left = left;
        mSource.right = right;
       // 움직일 delta 값 초기화 
        mMoveDelta = 0;
       // 화면 갱신
        invalidate();
    }
    // 현재 상태 얻어 오기 (on 이면 true)
    public boolean getIsOn() {
        return mIsOn;
    } 
    // Listener 등록을 위한 interface 함수
    public interface OnButtonClickListener {
       // On - Off 상태 변경되면 호출됨
        public abstract void onResult(boolean onResult);
    }
    // 저장된 instance restore 함수
    @Override
    protected void onRestoreInstanceState(Parcelable state) {
       // EXTRA_ON_OFF_SAVE_KEY 값으로 on off 저장된 instance 값 읽어 옴
       // EXTRA_ON_OFF_SAVE_KEY 는 string으로 아무 것이든 상관 없음 
        mIsOn = ((Bundle)state).getBoolean(EXTRA_ON_OFF_SAVE_KEY);
       // 움직일 delta 값 초기화 
        mMoveDelta = 0;
       // 기본 값은 on 상태를 가정하고 설정
        int left = 0;
        int right = mMovementLimite;
       // off 상태 일때
        if (mIsOn == false) {
            left = mBtnWidth - mMovementLimite;
            right = mBtnWidth;
        }
       // button rect가 null 일경우 새로 생성
        if (mSource == null) {
            mSource = new Rect(left, 0, right, mBtnHeight);
       // button rect가 null 이 아니면 left, right 위치 설정 
        } else {
            mSource.left = left;
            mSource.right = right;
        }
       // 기존에 저장되어 있는 state 부모 클래스에 에 전달
       // 기존 instance 정보는 EXTRA_SAVE_INSTANCE_KEY 사용
        super.onRestoreInstanceState(((Bundle)state).getParcelable(
         EXTRA_SAVE_INSTANCE_KEY));
    }
   // instance 저장 함수
    @Override
    protected Parcelable onSaveInstanceState() {
       // instance 저장 할 bundle 생성
        Bundle bundle = new Bundle();
       // EXTRA_SAVE_INSTANCE_KEY 사용 하여 기존 instance 저장
        bundle.putParcelable(EXTRA_SAVE_INSTANCE_KEY, super.onSaveInstanceState());
       // EXTRA_ON_OFF_SAVE_KEY 사용 하여 기존 on off 상태 저장  
        bundle.putBoolean(EXTRA_ON_OFF_SAVE_KEY, mIsOn);
       // bundle 전달
        return bundle;
    } 

실 사용 법은 담편에... 후~ 

'Android' 카테고리의 다른 글

Android AsyncTask 함정 카드  (1) 2014.08.03
Android Custom Widget 만들기 7편  (0) 2012.04.12
Android Custom Widget 만들기 5편  (0) 2012.04.12
Android Custom Widget 만들기 4편  (0) 2012.04.12
Android Custom Widget 만들기 3편  (0) 2012.04.12
전편은 여기에.
2012/04/12 - [Android Study] - Android Custom Widget 만들기 4편 

음 이제 Handler 하고 몇가지 함수? 하고 Listener만 설명 하면 될듯.
이번엔 덩치큰 Handler 부터... 
    // Button animation을 담당하는 handler
    private class ButtonMoveHandler extends Handler {
       // handler 에 message가 전달 되면 호출 되는 함수
        @Override
        public void handleMessage(Message msg) {
          // message 종류 구분
            switch (msg.what) {
          // message 가 animation 시작 일 때
            case ANIMATION_MESSAGE_START :
             // animation 구분 값은 ture
                mIsAnimation = true;
              // 현재 left 값을 얻어옴
                int left = mSource.left;
              // on 상태에서 시작 했다면
                if (mIsOn == true) {
                 // 움직일 delta 값이 양수 라면
                    if (mMoveDelta > 0) {
                    // MOVE_TO_RIGHT_LEFT 값 보다 크게 움직였을 경우
                    // MOVE_TO_RIGHT_LEFT 값은 80 
                        if (left < MOVE_TO_RIGHT_LEFT) {
                       // 오른쪽으로 animation 시작
                            this.sendEmptyMessage(ANIMATION_MESSAGE_MOVE_RIGHT);
                    // MOVE_TO_RIGHT_LEFT 값 보다 작게 움직였을 경우 
                        } else {
                       // 왼쪽으로 animation 시작
                            this.sendEmptyMessage(ANIMATION_MESSAGE_MOVE_LEFT);
                        }
                 // 움직일 delta 값이 음수 라면  
                    } else {
                    // 왼쪽으로 animation 시작  
                        this.sendEmptyMessage(ANIMATION_MESSAGE_MOVE_LEFT);
                    }
              // off 상태에서 시작 했다면  
                } else {
                 // animation 방향을 구분 하기 위한 최대 값 계산
                    int max = mBtnWidth - mMovementLimite - MOVE_TO_RIGHT_LEFT;
                 // 움직일 delta 값이 음수 라면  
                    if (mMoveDelta < 0) {
                     // left 값이 계산된 값 보다 크게 움직였을 경우
                        if (left > max) {
                        // 왼쪽으로 animation 시작  
                            this.sendEmptyMessage(ANIMATION_MESSAGE_MOVE_LEFT);
                     // left 값이 계산된 값 보다 작게 움직였을 경우  
                        } else {
                        // 오른쪽으로 animation 시작  
                            this.sendEmptyMessage(ANIMATION_MESSAGE_MOVE_RIGHT);
                        }
                 // 움직일 delta 값이 양수 라면  
                    } else {
                    // 오른쪽으로 animation 시작    
                        this.sendEmptyMessage(ANIMATION_MESSAGE_MOVE_RIGHT);
                    }
                }
                break;
          // message 가 animation left 이동 일 때  
            case ANIMATION_MESSAGE_MOVE_LEFT :
              // 이동 delta 값은 DURATION_VALUE와 같음 (한 스텝에 이동 할 거리)
              // DURATION_VALUE 는 13
                mMoveDelta = DULATION_VALUE;
              // onDraw 호출
                invalidate();
              // 다시 자기 자신 호출 (종료 될 때까지 반복 호출)
                this.sendEmptyMessage(ANIMATION_MESSAGE_MOVE_LEFT);
                break;
          // message 가 animation right 이동 일 때
            case ANIMATION_MESSAGE_MOVE_RIGHT :
              // 이동 delta 값은 - DURATION_VALUE와 같음 (한 스텝에 이동 할 거리)  
              // DURATION_VALUE 는 13  
                mMoveDelta = DULATION_VALUE * -1;
              // onDraw 호출  
                invalidate();
              // 다시 자기 자신 호출 (종료 될 때까지 반복 호출)  
                this.sendEmptyMessage(ANIMATION_MESSAGE_MOVE_RIGHT);
                break;
          // message 가 animation stop 일 때 
            case ANIMATION_MESSAGE_STOP :
              // animation flag false로 설정
                mIsAnimation = false;
              // 움직일 delta 값 0으로 설정 
                mMoveDelta = 0;
              // 화면 갱신을 위한 onDraw 호출 
                invalidate();
              // left, right 이동 animation handler message 삭제 
                this.removeMessages(ANIMATION_MESSAGE_MOVE_RIGHT);
                this.removeMessages(ANIMATION_MESSAGE_MOVE_LEFT);
              // Listener 를 호출 최종 결과 통보 
                onResult();
                break;
            }
        }
    } 

이로써 덩치 큰놈들은 죄다 설명 끝났음 후~ 아구 힘들다.
담편에는 가벼운 메소드 몇 개만 하면 끝날듯?

'Android' 카테고리의 다른 글

Android Custom Widget 만들기 7편  (0) 2012.04.12
Android Custom Widget 만들기 6편  (0) 2012.04.12
Android Custom Widget 만들기 4편  (0) 2012.04.12
Android Custom Widget 만들기 3편  (0) 2012.04.12
Android Custom Widget 만들기 2편  (0) 2012.04.12
이전글.. 필요한분 여기.
2012/04/12 - [Android Study] - Android Custom Widget 만들기 3편


남은 코드 이어서...
    // Touch 이벤트 처리 함수
   @Override
    public boolean onTouchEvent(MotionEvent event) {
       // touch 행동 (action) 얻기
        int action = event.getAction();
        switch (action) {
       // touch down 했을 때
        case MotionEvent.ACTION_DOWN :
          // mIsAnimation 은 boolean 객체 (animation 진행 상황 구분)
            if (mIsAnimation) mHandler.sendEmptyMessage(ANIMATION_MESSAGE_STOP);
          // int 형 X 좌표 저장 객체
            mOldPosition = (int) event.getX();
            break;
       // touch move 했을 때 
        case MotionEvent.ACTION_MOVE :
          // animation 중이라면 아무것도 안함
            if (mIsAnimation) return super.onTouchEvent(event);
          // animation 상태가 아니면 현재 좌표 읽어옴
            int current = (int) event.getX();
          // 현재 좌표와 예전 좌표의 차이가 TOUCH_POINT_GAP 보다 클때만 반응
          // TOUCH_POINT_GAP 값은 10
            if (Math.abs(mOldPosition - current) > TOUCH_POINT_GAP) { 
              // int형 변수 움직일 거리 저장
                mMoveDelta = mOldPosition - current;
              // 현재 좌표를 old 좌표에 복사
                mOldPosition = current;
              // onDraw() 호출 
                invalidate();
            }
            break;
       // touch cancel 되거나 up 했을때 
        case MotionEvent.ACTION_CANCEL :
        case MotionEvent.ACTION_UP :
          // animation이 동작 중이지 않다면 수행
            if (mIsAnimation == false) {
              // button 그림이 on 상태가 됬을때
                if (mSource.left == 0 && mMoveDelta < 0) {
                    mMoveDelta = 0;
                 // Listener 에다가 해당 event 전달
                    onResult();
              // button 그림이 off 상태가 됬을때
                } else if (mSource.right == mBtnWidth && mMoveDelta > 0) {
                    mMoveDelta = 0;
                 // Listener 에다가 해당 event 전달 
                    onResult();
              // 움직이던 도중 일때 
                } else {
                 // animation 동작하게 handler 호출 
                    mHandler.sendEmptyMessage(ANIMATION_MESSAGE_START);
                }
            }
            break;
        }
       // 나머지 다른 경우는 기존 code 유지
        return super.onTouchEvent(event);
    }
    // 그림 그리는 함수
    @Override
    protected void onDraw(Canvas canvas) {
       // animation 을 종료 해야 할지 구분 하는 변수
        boolean animetionStop = false;
       // left 위치 계산
        int left = mSource.left + mMoveDelta;
       // right 위치 계산  
        int right = mSource.right + mMoveDelta;
       // right 값이 오른쪽 끝일 경우
        if (right >= mBtnWidth) {
          // 더이상 이동 하지 못하게 left 값 고정
            left = mBtnWidth - mMovementLimite;
          // 더이상 이동 하지 못하게 right 값 고정 
            right = mBtnWidth;
          // off 상태로 변경
            mIsOn = false;
          // animation 동작 중이었으면 animation 종료
            if (mIsAnimation) animetionStop = true;
       // left 값이 왼쪽 끝일 경우 
        } else if (left <= 0) {
          // 더이상 이동 하지 못하게 left 값 고정  
            left = 0;
          // 더이상 이동 하지 못하게 right 값 고정  
            right = mMovementLimite;
          // on 상태로 변경
            mIsOn = true;
          // animation 동작 중이었으면 animation 종료  
            if (mIsAnimation) animetionStop = true;
        }
       // 이미지 rect의 left 값 설정
        mSource.left = left;
       // 이미지 rect의 right 값 설정
        mSource.right = right;
       // canvas에 bitmap 그림
        canvas.drawBitmap(mOnOffBitMap, mSource, mContent, new Paint()); 
        super.onDraw(canvas);
       // animation 종료 해야하면 handler 호출 
        if (animetionStop)  mHandler.sendEmptyMessage(ANIMATION_MESSAGE_STOP);
    } 

남은 코드는 다음 편에~ To be continue. 

'Android' 카테고리의 다른 글

Android Custom Widget 만들기 6편  (0) 2012.04.12
Android Custom Widget 만들기 5편  (0) 2012.04.12
Android Custom Widget 만들기 3편  (0) 2012.04.12
Android Custom Widget 만들기 2편  (0) 2012.04.12
Android Custom Widget 만들기 1편  (1) 2012.04.12

+ Recent posts