300x250
반응형

전체화면의 사이즈를 상황에 따라서 동적으로 사이즈를 조절 하기 위한 예제.

 

레이아웃 설정 

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:text="Hello World!"
        android:background="#ff0022"
        android:gravity="center"
        android:textColor="@color/cardview_light_background"
        app:layout_constraintBottom_toTopOf="@id/guidelineHorizontal"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="@id/guidelineVertical"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/test"
        android:text="클릭"
        app:layout_constraintEnd_toEndOf="parent"
        />

    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/guidelineVertical"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintGuide_percent="0.2" />

    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/guidelineHorizontal"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintGuide_percent="0.7" />



</androidx.constraintlayout.widget.ConstraintLayout>

 

이렇게 레이아웃만 설정 하면 TextView의 전체 사이즈가 가이드라인을 통해서 조절이 된다.

이런식으로 수평/수직의 퍼센트를 설정함으로 해당 가이드라인을 기준으로 TextView을 그리고 있다.

 

그럼 상황에 따라서 TextView의 사이즈가 조절되야 하는 경우가 있다.

실제 실무에서도 필요한 기능이므로 그럴 때는 코드단에서 처리를 해줘야 한다.

 

아래와 같이 해보자.

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        var btn: Button = findViewById(R.id.test)
        btn.setOnClickListener {
            changeGuideline(0.5, 0.8)
        }
    }

    private fun changeGuideline(ver:Double, hor:Double) {
        val gd1: Guideline = findViewById(R.id.guidelineHorizontal)
        val gd2: Guideline = findViewById(R.id.guidelineVertical)

        gd1.layoutParams = (gd1.layoutParams as ConstraintLayout.LayoutParams).apply {
            guidePercent = ver.toFloat()
        }

        gd2.layoutParams = (gd2.layoutParams as ConstraintLayout.LayoutParams).apply {
            guidePercent = hor.toFloat()
        }
    }
}

 

동적인 상황을 고려하여 클릭 했을 경우 변경 되도록 처리.

위와 같이 사이즈가 조절 되었음.

 

참조 해서 잘 사용해보자..기록기록.

728x90
300x250
반응형
728x90

프로젝트시 특정모듈에 따라서 기능을 on/off해야 하는데 메타데이터에서 컨트롤 하는게 더 효율적으로 생각되어 메타데이터에서 설정후 실제 코드에서 읽어오는 방법을 정리 하였다.

 

매니페스트 설정

<manifest>
......
	<meta-data
        android:name="testEnable"
        android:value="true"
    />
</manifest>

메니패스트에 사용할 메타데이터를 등록한다.

나의 목표는 testEnable이 true이면 특정 기능을 사용하고 없으면 사용하지 않는 것이다.

 

private fun getTestEnable(): Boolean {
	return packageManager.getApplicationInfo(
            packageName,
            PackageManager.GET_META_DATA)
            .metaData
            .getBoolean("testEnable")
}

 

만약에 testEnable 메타데이터가 없는 경우는 무조건 false로 리턴한다.

728x90
300x250
반응형

현재 설정 관련 레이아웃을 만들다가 표시해주는 상자를 곡선으로 그리고 싶었다.

아무래도 더 이쁘기도 하고 벤치마킹하는 유튜브나 다른 플레이어들도 코너를 많이 적용 했기 때문이다.

 

먼저. 나는 constraintLayout을 사용하는데 이 contraintLayout에 corner를 적용하고 싶다.

먼저 일반적으로 사용 할때.. 이렇게 사용 하였음.

<androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="@dimen/_180sdp"
        android:layout_height="wrap_content"
        android:background="#212121"
        android:visibility="visible"
        android:layout_marginBottom="@dimen/_10sdp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintBottom_toBottomOf="parent">
        
        <TextView
           ......
        />
</androidx.constraintlayout.widget.ConstraintLayout>

자 이런식으로 한 후에 실행을 시키면 단순히 네모난 모양으로 출력이 된다.

나는 네모난 모양을 곡선으로 변경하고 싶을때 다음과 같이 사용 하였다.

 

view_card.xml

<?xml version="1.0" encoding="utf-8"?><!-- 다이얼로그 배경 -->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <corners android:radius="10dp" />
    <solid android:color="#383838" />
</shape>

위에 내용은 corner를 그려주는 레이아웃이다. 이 레이아웃을 contraintLayout에 background에 적용하면된다.

여기서 참고 할 것은. view_card.xml은. drawable아래에 생성을 해주어야한다!!!

 

아래와 같이 적용하면 이제 네모가 아닌 코너가 만들어진 상태로 화면에 보여준다.

<androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="@dimen/_180sdp"
        android:layout_height="wrap_content"
        android:background="@drawable/view_card"
        android:visibility="visible"
        android:layout_marginBottom="@dimen/_10sdp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintBottom_toBottomOf="parent">
        
        <TextView
           ......
        />
</androidx.constraintlayout.widget.ConstraintLayout>

constraintLayout에 background="#212121" -> @drawable/view_card 로 변경하면 끝!

728x90
300x250
반응형

코틀린을 사용하다 보면 random함수가 필요한 경우가 종종 있다.

그래서 랜덤함수의 사용방법을 기록해보기로 한다.

 

1. random()

fun main() {
	val range = (0..45)
    
    println(range.random())
    println(range.random())
}

결과 .

0 부터 45까지의 랜덤한 함수가 출력되었다.

총 6개의 랜덤함수를 만들어 보자.

fun main() {
	val range = (0..45) 
    var cnt = 0
    
    while(cnt < 6) {
        print(range.random()  )    
        print(" ")
        cnt++
    }   
}

 

0 부터 45번까지 총 6개의 데이터를 생성 하여 나열하였다.

 

위 내용은 정해진 패턴으로 랜덤 숫자를 생성한다. 그래서 매번 처음 동작 시킬때마다 같은 숫자대역이 나올확률이 있다.

이러한 정해진 패턴을 무시하는 랜덤함수를 사용하자.

 

2. SecureRandom

fun main() {
	val range = SecureRandom()
    println(range.nextInt(45))  
 
}

nextInt(45)는 0부터 45까지의 랜덤숫자를 출력 하도록 설정 한다.

 

똑같이 1번내용 처럼 살짝 응용을 하면 원하는 개수를 지정 할수 있고, 중복되지 않다던지, 특정 숫자를 제외 한다던지의 내용을 추가하여 구현 할수있다.

 

상황에 따라 다르지만 되도록이면 secureRange를 사용하는게 좋을 것 같ㄷ.

728x90
300x250
반응형

추가 기능을 만들려고 하는데, Youtube나 네이버 동영상 등 여러가지 동영상 플랫폼에서 지원하는 기능이다.

맨처음에 기능의 이름을 몰라서 여러가지로 검색을 해보았는데 해당 기능의 이름은 PIP라고 부른다.

 

간단한 예제를 먼저 소개를 하고 추후에 기능을 추가할 예정이다.

 

구현 순서.

1. 설정 : 매니페스트 수정. ( AndroidManifest.xml )

<activity
  ......
  android:resizeableActivity="true"
  android:supportsPictureInPicture="true"
  ......
/activity>

매니페스트에 위 두개를 추가 한다.

 

2. xml 수정

기본생성된 내용을 수정한다.

<VideoView
        android:id="@+id/main_video_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        />

    <ScrollView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <Button
            android:id="@+id/main_pip_btn"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Start PIP mode"
            android:backgroundTint="@android:color/holo_orange_light"
            />
    </ScrollView>

 

3. 코드 수정.

class MainActivity : AppCompatActivity() {
    private val mPipBuilder = PictureInPictureParams.Builder()
    private lateinit var binding : ActivityMainBinding
    private val TAG = "PIP"

    override fun onCreate(savedInstanceState: Bundle?) {
        Log.d(TAG, "[power cycle] onCreate")
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        binding.mainVideoView.run {
            //영상이 끝나면 영상을 재시작해서 무한반복 시킴.
            setOnCompletionListener {
                it.start()
            }

            //res폴더에 있는 비디오를 비디오뷰에 set시켜준다.
            setVideoURI(Uri.parse("android.resource://$packageName/${R.raw.sample}"))
            start()
        }

        binding.mainPipBtn.setOnClickListener {
            mPipBuilder.setAspectRatio(Rational(binding.mainVideoView.width, binding.mainVideoView.height))
            enterPictureInPictureMode(mPipBuilder.build())
        }
    }
}

 

4. 결과 화면

START PIP MODE를 클릭하면 오른쪽 사진처럼 화면이 작아짐을 볼수있다.

 

추후에 화면이 작아졌을 경우 재생버튼등의 layout등을 표시하고 그에 따른 기능을 구현하는 예제를 추가로 만들어 볼 예정이다. 

728x90
300x250
반응형

안녕하세요.

이번에 안드로이드 개발을 시작하면서 미들웨어의 함수를 호출해야 하는 일이 생겼습니다.

백그라운드는 전부 C++코드이기 때문에 직접 호출이 필요한 경우가 있습니다.

간단하게 호출하는 방법을 소개 하려고 합니다.

 

1. 코드 이름 및 종류

- exam.kt, mw.cpp

 

2. 간단한 소스 

exam.kt

extern fun testNativeCode()

fun call() {
	testNativeCode
}

여기서 위 내용처럼 하면 Android studio에서 native code를 생성 할 것인지 묻는다.
그때 만들어질 위치를 선택해주면 자동으로 생성 한다.

 

mw.cpp

#include "exam.h"

extern "C"
JNIEXPORT void JNICALL
Java_com_mobipintech_zui_MobileMainDialog_testNativeCode(JNIEnv *env, jobject thiz) {
    // TODO: implement at3NativeTestFunc()
    at3NativeTestFunc();
}

위 내용은 Java_com_mobipintech_zui_MobileMainDialog까지는 경로.
TestNativeCode는 함수 이름이다.

 

exam.cpp

void atNativeTestFunc()
{
	printf("TEST 코드 입니다.\n")
}

 

exam.h

void atNativeTestFunc();

 

이렇게 사용할 내용을 c++에 정의 해놓고 코틀린 내부에서 호출해서 직접 사용 하면 됩니다.

 

728x90
300x250
반응형

이번에 안드로이드 앱 개발이 필요하여 공부를 진행 하면서 개발을 동시에 진행해야 한다.

그래서 공부한 내용을 블로그에 추가로 정리를 한다.

 

1. 화면 크기 : 화면의 물리적인 크기, 화면의 대각선 크기로 지정.
예) 보통화면 : 최소 470dp X 320dp

 

2. 화면 밀도 : 물리적 화면 공간 안에 있는 픽셀의 개수, 일반적으로 dpi ( dot per inch )

예) hdpi ( 고밀도 ) ~ 240dpi

3. 해상도 : 화면에 있는 물리적 픽셀의 총개수, 예로 2천만 화소로 부른다.

 in : 인치, 기반의 물리적 스크린 크기.

 mm : 밀리미터, 기반의 물리적 스크린 크기

 px : 스크린상의 실제 픽셀에 대응 하는 단위

 dp : 밀도 독립적 픽셀

 px : dp * ( dpi / 160 )

 sp : 텍스트 크기를 정의

 pt : 화면 밀도와 상관 없이 1pt는 물리적 화면 크기의 1/72인치이다.

 

 ps) 안드로이드 기기는 많은 업체에서 제작되고 화면의 크기 및 해상도 천차만별이다. 이런 서로 다른 크기와 화면밀도, 해상도를 가진 기기들에서 같은 모양의 UI를 제공하기 위해서는 dp를 사용한다.

728x90

+ Recent posts