月: 2022年11月

deprecatedになったsetHasOptionsMenuの対応

AndroidGradlePluginをアップデートするとsetHasOptionsMenuonOptionsItemSelectedが非推奨になりました。今後はメニュー関連を実装する場合はMenuHostMenuProviderを使う必要があります。

今までのActivityの実装

class MainActivity : AppCompatActivity(R.layout.activity_main) {
  override fun onCreateOptionsMenu(menu: Menu): Boolean {
    menuInflater.inflate(R.menu.menu_main, menu)
    return true
  }
  
  override fun onOptionsItemSelected(item: MenuItem): Boolean {
    return when (item.itemId) {
      R.id.setting -> {
        // settingが押されたときの処理
        true
      }
      else -> super.onOptionsItemSelected(item)
    }
  }
}

ActivityをMenuHostとMenuProviderを使って実装

class MainActivity : AppCompatActivity(R.layout.activity_main) {
  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    
    addMenuProvider(object : MenuProvider {
      override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {
        menuInflater.inflate(R.menu.menu_activity, menu)
      }

      override fun onMenuItemSelected(item: MenuItem): Boolean {
        when (item.itemId) {
          R.id.setting -> {
            // settingが押されたときの処理
          }
        }
        return true
      }
    })
  }
}

今までのFragmentの実装

class MainFragment : Fragment(R.layout.fragment_main) {
  override fun onCreate(savedInstanceState: Bundle?) {
    setHasOptionsMenu(true)
  }
  
  override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
    super.onCreateOptionsMenu(menu, inflater)
    inflater.inflate(R.menu.menu_fragment, menu)
  }

  override fun onOptionsItemSelected(item: MenuItem): Boolean {
    return when (item.itemId) {
      R.id.setting -> {
        // settingが押されたときの処理
        true
      }
      else -> super.onOptionsItemSelected(item)
    }
  }
}

FragmentをMenuHostとMenuProviderを使って実装

class MainFragment : Fragment(R.layout.fragment_main) {
  override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    
    (requireActivity() as MenuHost).addMenuProvider(object : MenuProvider {
      override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {
        menuInflater.inflate(R.menu.menu_fragment, menu)
      }
      
      override fun onMenuItemSelected(menuItem: MenuItem): Boolean {
        when (item.itemId) {
          R.id.setting -> {
            // settingが押されたときの処理
            true
        }
        return true
      }
    }, viewLifecycleOwner, Lifecycle.State.RESUMED)
  }
}

[Kotlin]interfaceをインスタンス化する

このサイトのアクセス解析を見ると意外と簡単な内容というかシンプルな内容のアクセスが多いので今回もサラッと終わる内容になります。

Kotlinではinterfaceを継承したインスタンスを簡単に作ることが可能です。下記のようなinterfaceがあるとします。

interface HasName {
    val name: String
}

class Human : HasNameというクラスを作成しても良いですが、クリックリスナーとか「継承したクラスを作成するほどではないな」という時は下記のように書くことでinterfaceを継承したインスタンスを作成できます。

fun main() {
    val human = object : HasName { override val name = "suzuki" }
    println(human.name)
}

https://pl.kotl.in/4T0rVkYhM