implementation("androidx.viewpager2:viewpager2:1.0.0")탭레이아웃을 하단에 두고, 나머지 부분은 뷰페이저로 꽉 채웠다.
<?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">
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/main_view_pager"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@id/main_tab"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
</androidx.viewpager2.widget.ViewPager2>
<com.google.android.material.tabs.TabLayout
android:id="@+id/main_tab"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="@color/white"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
뷰페이저에 연결할 프래그먼트를 framents 변수 안에서 배열로 관리한다.
import androidx.fragment.app.Fragment
import androidx.viewpager2.adapter.FragmentStateAdapter
class ViewPager2Adapter(fragmentActivity: MainActivity) : FragmentStateAdapter(fragmentActivity) {
private var fragments: ArrayList<Fragment> = ArrayList()
override fun getItemCount(): Int {
return fragments.size
}
override fun createFragment(position: Int): Fragment {
return fragments[position]
}
fun addFragment(fragment: Fragment) {
fragments.add(fragment)
notifyItemInserted(fragments.size - 1)
}
fun removeFragement() {
fragments.removeLast()
notifyItemRemoved(fragments.size)
}
}
initViewPager() 함수를 만들어서, 그 안에서 탭레이아웃과 뷰페이저를 연결해준다.
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.viewpager2.widget.ViewPager2
import com.example.myimgsearch.databinding.ActivityMainBinding
import com.google.android.material.tabs.TabLayoutMediator
class MainActivity : AppCompatActivity() {
private val binding by lazy { ActivityMainBinding.inflate(layoutInflater) }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(binding.root)
initViewPager()
}
private fun initViewPager() {
val tabTextList = listOf("이미지 검색", "내 보관함")
var viewPager2Adapter = ViewPager2Adapter(this)
viewPager2Adapter.addFragment(SearchFragment())
viewPager2Adapter.addFragment(StorageFragment())
binding.mainViewPager.apply {
adapter = viewPager2Adapter
registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback(){})
}
TabLayoutMediator(binding.mainTab, binding.mainViewPager) { tab, position ->
tab.text = tabTextList[position]
}.attach()
}
}
애플리케이션 추가하기를 누르면 사용자 정보를 입력하게 된다. 여기서 앱아이콘은 등록하지 않아도 괜찮지만, 나머지 필수 값들을 입력하면 애플리케이션이 등록되는데, 눌러서 들어가보면 사용할 수 있는 네이티브 앱키, REST API 키, JavaScript 키, Admin 키를 가질 수 있다.REST API 키를 활용할 것이다..gitignore파일에 들어가는 /build 와 local.properties를 활용하여 git에 API키 값이 올라가는 불상사를 막을 것이다.BASE_URL에 대해서도 이 방법을 활용할 수 있다.local.properties에 api_key 변수 설정하기Gradle Scripts 안에 존재하는 local.properties에 사용하고싶은변수명="제공된키값"을 작성한다.
나는 변수명을 api_key라고 간단하게 적었다. 카카오 REST API 값만 사용할 것이기 때문에..
제공되는 키 값은 꼭 "" 더블쿼터안에 작성하도록 하자.
## This file is automatically generated by Android Studio.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file should *NOT* be checked into Version Control Systems,
# as it contains information specific to your local configuration.
#
# Location of the SDK. This is only used by Gradle.
# For customization when using a Version Control System, please read the
# header note.\
...
api_key="제공해주는 키 값"
build.gradle 에 properties 설정하기android { } 바깥에 properties를 선언해주고, android { } 안에 있는 defaultConfig {} 안에는 buildConfigField(type,name,value)를 선언해준다.
[트러블슈팅] android { } 안에 있는 buildFeatures {}안에 buildConfig = true를 추가해준다. 해주지 않으면, Cause: defaultConfig contains custom BuildConfig fields, but the feature is disabled.오류를 만나게 된다..
[트러블슈팅] Properties()를 임포트 받을 때에는 수많은 Properties( )들이 있지만, 꼭 java.util.Properties을 임포트해줘야 load 함수를 사용할 수 있다.
[트러블슈팅] buildConfigField()함수를 작성해줄 때에는 value값에 "설정한변수명"이 프로퍼티임을 알 수 있도록 꼭 properties.getProperty("설정한변수명")를 사용해준다.
import java.io.FileInputStream
import java.util.Properties
...
val properties = Properties().apply { load(FileInputStream(rootProject.file("local.properties"))) }
android {
...
defaultConfig {
...
buildConfigField("String", "KAKAOAPI", properties.getProperty("api_key"))
}
...
buildFeatures {
...
buildConfig = true
...
}
}
...
BuildConfig로 받아서 사용하기.BuildConfig.buildConfigField의name형태로 원하는 곳에서 사용할 수 있다.BuildConfig가 사용이 안된다면, Build메뉴 > Rebuild Project를 통해 빌드를 다시 해주면 사용가능하다.val apikey : String = BuildConfig.KAKAOAPI