philipy355 / inflearn-compose

0 stars 0 forks source link

docs : 수평계앱 (canvas와 센서를 활용) #18

Open philipy355 opened 11 months ago

philipy355 commented 11 months ago
class MainActivity : ComponentActivity() {
    private val viewModel by viewModels<MainViewModel>()

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

        //Activity에는 lifecycle 객체가 존재한다.
        lifecycle.addObserver(viewModel)

        setContent {
            TiltScreen(
                x = viewModel.x.value,
                y = viewModel.y.value
            )
        }
    }
}

@SuppressLint("ServiceCast")
class MainViewModel(application: Application) : AndroidViewModel(application), SensorEventListener,
    LifecycleObserver {

    private val _x = mutableStateOf(0f)
    val x : State<Float> = _x

    private val _y = mutableStateOf(0f)
    val y : State<Float> = _y

    private val sensorManager by lazy {
        application.getSystemService(Context.SENSOR_SERVICE) as SensorManager
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    fun registerSensor(){
        sensorManager.registerListener(
            this,
            sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
            SensorManager.SENSOR_DELAY_NORMAL
        )
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    fun unregisterSensor(){
        sensorManager.unregisterListener(this)
    }
    override fun onSensorChanged(event: SensorEvent?) {
        event?.let{
            _x.value = event.values[0]
            _y.value = event.values[1]
        }
    }

    override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) {}
}

@Composable
fun TiltScreen(x: Float, y: Float){

    val yCoord = x * 20
    val xCoord = y * 20

    Canvas(modifier = Modifier.fillMaxSize()){
        val centerX = size.width / 2
        val centerY = size.height / 2

        drawCircle(
            color = Color.Black,
            radius = 100f,
            center = Offset(centerX, centerY),
            style = Stroke()
        )
        //녹색원
        drawCircle(
            color = Color.Green,
            radius = 100f,
            center = Offset(centerX + xCoord, centerY + yCoord),
        )
        //가운데 십자가
        drawLine(
            color = Color.Black,
            start = Offset(centerX - 20, centerY),
            end = Offset(centerX + 20, centerY)
        )
        drawLine(
            color = Color.Black,
            start = Offset(centerX, centerY - 20),
            end = Offset(centerX, centerY + 20)
        )
    }
}
@Preview(showBackground = true)
@Composable
fun Preview(){
    TiltScreen(x = 30f, y = 20f)
}
philipy355 commented 11 months ago
    //화면 꺼지지 않도록 하기
    window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
    //화면 가로 모드로 고정되게 하기
    requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE