Android – 수평 측정기 레퍼런스 with. 코틀린

TiltSensor에 들어간 클래스/위젯

class, component on the TIltSensor

  • Custom View
  • Paint,Canvas
  • ACCELEROMETER Censor (가속도 센서)
수평일 때 (horiwontally)
왼쪽으로 기울일 때 (tilt to the left)
오른쪽으로 기울일 때 (tilt to the right)
아래로 기울일 때 (tilt to the bottom)
위로 기울일 때 (tilt to the top)

TiltView.kt

package com.example.tiltsensor

import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.hardware.SensorEvent
import android.view.View

// TiltView 커스텀뷰
// xml을 사용하지 않고 직접 제작해서 만드는 뷰(화면)

// View를 상속받는데 생성자를 오버라이드함 <context를 받을 수 있게>
// context는 어플리케이션 시스템 관리 객체이다
// 코틀린,자바로 뷰를 제작하려면 context를 받는게 약속이다

class TiltView(context: Context?) : View(context) {
    // 그릴 때 붓의 역할하는 객체 만들기
    private val greenPaint: Paint =Paint()
    private val blackPaint:Paint=Paint()

    // 중점 변수 선언
    private var cX:Float=0f
    private var cY:Float=0f

    // 센서 x,y값 변수
    private var xCoord:Float=0f
    private var yCoord:Float=0f

    init{
        // 색깔을 초록색으로 설정
        greenPaint.color= Color.GREEN
        // 외곽선만 그리게 설정
        blackPaint.style=Paint.Style.STROKE
    }

    // 뷰의 크기가 변경될 때 호출되는 메소드
    // 그런데 처음에 뷰의 크기가 정해지면 어차피 호출됨
    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        // w: 변경된 뷰 가로 길이, h: 세로 길이
        // oldw: 변경 전 뷰 가로 길이, oldh: 세로 길이

        // 중점 변수 초기화
        cX=w/2f
        cY=h/2f
    }

    // 그림 그리기 메소드
    override fun onDraw(canvas: Canvas?){
        //바깥 검정색 외곽만 그려진 원
        canvas?.drawCircle(cX,cY,100f,blackPaint)
        // 안쪽 녹색으로 채워진 원
        // [센서의 x값과 y값이 변함에 따라 그려지는 원의 위치도 다름]
        canvas?.drawCircle(xCoord+cX,yCoord+cY,100f,greenPaint)
        // 가운데 십자가
        canvas?.drawLine(cX-20,cY,cX+20,cY,blackPaint)
        canvas?.drawLine(cX,cY-20,cX,cY+20,blackPaint)
    }
    
    // 센서가 변하고 onSensorChanged에서 호출시킴 
    fun onSensorEvent(event:SensorEvent){
        // 화면을 가로로 돌렸으므로 x축과 y축을 서로 바꿈
        // 값이 너무 작으므로 20을 곱함
        yCoord=event.values[0]*20
        xCoord=event.values[1]*20

        // 다시 그리기 메소드
        invalidate()
    }
}

MainActivity.kt

package com.example.tiltsensor

import android.content.Context
import android.content.pm.ActivityInfo
import android.hardware.Sensor
import android.hardware.SensorEvent
import android.hardware.SensorEventListener
import android.hardware.SensorManager
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.WindowManager

class MainActivity : AppCompatActivity(), SensorEventListener {

    // sensorManager를 처음 사용할 때 초기화 <객체를 가리키게 됨>
    private val sensorManager by lazy{
        // 센서를 사용하기 위해 센서 매니저 객체를 만들기
        // SystemService에서 센서 매니저 객체를 가져오고, 참조변수의 자료형을 SensorManager로 변환
        getSystemService(Context.SENSOR_SERVICE) as SensorManager
    }

    // 화면을 담당할 TiltView 객체를 가리킬 수 있는 참조변수 선언 (늦은 초기화)
    private lateinit var tiltView:TiltView

    // 센서 정밀도가 변경되면 호출되는 메소드
    override fun onAccuracyChanged(p0: Sensor?, p1: Int) {
    }

    // 센서 값이 변경되면 호출되는 메소드 <센서는 sensorEvent객체에 정보를 넘기고, 해당 객체의 멤버가 바뀌면 이 메소드가 호출됨>
    override fun onSensorChanged(event: SensorEvent?) {
        // value[0]: x축 값: 위로 기울이면 -10~0, 아래로 기울이면 0~10
        // value[1]: y축 값: 왼쪽으로 기울이면 -10~0, 오른쪽으로 기울이면 0~10
        // value[2]: z축 값: 미사용

        // 기능은 let메소드 안에 정의한다
        event?.let{
            // 이벤트 객체를 넘겨서 센서 값을 알 수 있게 함
            tiltView.onSensorEvent(event)
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        // 화면이 꺼지지 않게 하기
        window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
        // 화면이 가로 모드로 고정되게 하기
        requestedOrientation= ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE

        super.onCreate(savedInstanceState)

        // TiltView객체 선언 및 화면을 TiltView로 지정
        tiltView=TiltView(this)
        setContentView(tiltView)

    }

    // onCreate->onStart다음에 호출되는 메소드
    override fun onResume(){
        super.onResume()
        // 리스너(이벤트 처리 객체) 등록 <센서도 함께 등록한다>
        // 인수에는 [처리 객체,센서 종류,센서값을 얼마나 받는지] 나타냄
        sensorManager.registerListener(this,
            sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), // 가속도 센서 이용
        SensorManager.SENSOR_DELAY_NORMAL) // 중간 정도 속도로 센서 값을 받음
    }

    // 프로그램이 화면에서 가려지면 호출됨
    override fun onPause(){
        super.onPause()
        // 센서 등록 해제 <화면이 가려지면 센서를 해제>
        sensorManager.unregisterListener(this)
    }

}

Leave a Reply

Your email address will not be published. Required fields are marked *