ViewBindingを使用してMainActivityの中でレイアウトの設定を行う
kotlin初学者なため、間違い等があれば教えていただけますと幸いです。
環境
Android Studio Ladybug Feature Drop | 2024.2.2
compileSdk 35
kotlin 1.9.24
前回の記事のソースをもとに進めていきます。
KotlinでAPI通信を行う
XMLレイアウトへアクセスする
findViewByIdやViewBindindとは?
findViewByIdやViewBindingを使用すると、XMLレイアウトに定義された各UIコンポーネントに、ActivityやFragmentから簡単にアクセスでき、その属性や動作を変更することが可能になります。
今回はfindViewById を使わず、ViewBindingを使ってレイアウトファイル内のビュー(idで指定されたUIコンポーネント)を取得しています。
ViewBindingを有効にする
build.gradleに以下を追加します。
これで、ViewBindingを使うことができるようになります。
android {
...
buildFeatures {
viewBinding = true
}
}
MainActivityと結びつける
private lateinit var binding: ActivityMainBinding
ActivityMainBinding・・・activity_main.xml から自動生成されたバインディングクラス。XMLレイアウト内の各UIコンポーネントにアクセスできるようにします。
binding = ActivityMainBinding.inflate(layoutInflater)
layoutInflater・・・XMLに記述されたUIレイアウトを、プログラムから操作可能な実際のViewオブジェクトに変換します。
inflate()・・・メソッドの引数としてlayoutInflaterを渡すと、生成したViewをどの親コンテナにアタッチするかを指定できます。今回の場合は親コンテナを指定せず、後でsetContentView(binding.root) で明示的にアタッチしています。
最後に、生成されたActivityMainBindingインスタンスをbindingに代入します。
binding.pokeRecyclerView.layoutManager = LinearLayoutManager(this)
LinearLayoutManager(this)・・・RecyclerViewのアイテムを縦方向(デフォルト)に並べます。thisはこの場合、実行中のMainActivityを指します。
binding.pokeRecyclerView.layoutManager・・・ activity_main.xmlに定義されたRecyclerViewのレイアウト。.layoutManagerプロパティに代入することで、RecyclerViewの表示方法やスクロール動作を管理することができます。
private lateinit var binding: ActivityMainBinding
private lateinit var adapter: PokeAdapter
private val pokemonList = mutableListOf<PokemonResponse>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
WindowCompat.setDecorFitsSystemWindows(window,true)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.pokeRecyclerView.layoutManager = LinearLayoutManager(this)
adapter = PokeAdapter(pokemonList)
binding.pokeRecyclerView.adapter = adapter
.....
}
PokeAdapterの書き換え
class ViewHolder(val binding: PokeRowBinding) : RecyclerView.ViewHolder(binding.root)
PokeRowBinding・・・poke_row.xmlから『自動生成』されたバインディングクラスです。
binding.root・・・ViewBindingによって生成されたバインディングクラス。今回の場合は、『recyclerview』の『constraintlayout』を指します。
val binding = PokeRowBinding.inflate
inflate(LayoutInflater.from(parent.context),parent,false)・・・XMLファイルに書かれた画面を実際の画面に表示されるViewオブジェクトに変換します。
(inflateの定義)
class PokeAdapter(private val pokemonList: MutableList<PokemonResponse>): RecyclerView.Adapter<PokeAdapter.ViewHolder>(){
class ViewHolder(val binding: PokeRowBinding) : RecyclerView.ViewHolder(binding.root)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val binding = PokeRowBinding.inflate(
LayoutInflater.from(parent.context),parent,false
)
return ViewHolder(binding)
}
override fun getItemCount(): Int = pokemonList.size
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val pokemon = pokemonList[position]
holder.binding.pokeTextView.text = pokemon.name
Glide.with(holder.itemView.context)
.load(pokemon.sprites.frontDefault)
.into(holder.binding.pokeImageView)
}
}
全体
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
private lateinit var adapter: PokeAdapter
private val pokemonList = mutableListOf<PokemonResponse>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
WindowCompat.setDecorFitsSystemWindows(window,true)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.pokeRecyclerView.layoutManager = LinearLayoutManager(this)
adapter = PokeAdapter(pokemonList)
binding.pokeRecyclerView.adapter = adapter
lifecycleScope.launch {
for (id in 1..10) {
try {
val pokemon = RetrofitInstance.api.getPokemon(id)
pokemonList.add(pokemon)
adapter.notifyItemInserted(pokemonList.size - 1)
} catch (e: Exception) {
e.printStackTrace()
}
}
}
}
}
Discussion