命名規則(キャメルケース, パスカルケース, スネークケース, ケバブケース)とKotlin

命名規則(キャメルケース, パスカルケース, スネークケース, ケバブケース) - わくわくBank

ケバブケースというのがあるんだ...

命名規則

current user item を要素語とした複合語の記法を確認します。

キャメルケース( camelCase )

currentUserItem のように書きます。 先頭の要素語( current )は小文字で書き始めます。 先頭以外の要素語( user item )の最初を大文字で書き始めます。 ローワーキャメルケースともいいます。

パスカルケース( PascalCase )

CurrentUserItem のように書きます。 要素語( current user item )の最初を大文字で書き始めます。 アッパーキャメルケースともいいます。

スネークケース( snake_case )

current_user_item のように書きます。 アンダースコア で要素語( current user item )を連結します。

ケバブケース( kebab-case )

current-user-item のように書きます。 ハイフン で要素語( current user item )を連結します。

Kotlin

developer.android.com

  • 変数は概ねキャメルケース

ASCII 文字と数字のみを使用します。以下に述べる少数の例では、アンダースコアも使用されます。したがって、有効なそれぞれの識別子名は、正規表現 \w+ で照合されます。 name_、mName、s_name、kName の例に見られるような特殊な接頭辞または接尾辞は、バッキング プロパティの場合以外では使用されません。

  • クラス名はパスカルケース

  • 定数名は大文字のスネークケース

Android Study Jamに参加して先着50名のグッズを頂いた。

2022年7、8月にGoogle Japanが主催していたAndroid Study Jamに参加した。

Androidアプリの新しいUI開発ツールであるJetpack Composeを普及する施策である。

こういうのが主催されるってことは、まだ従来のAndroid Viewを使う人が多数派で、先ずJetpack Composeを使おうという人が少数派なんだろう。

内容はオンライン教材で以下リンクのpathwayをやって、一通り完了したらバッジが貰えるから、それを報告する。

developer.android.com

developer.android.com

獲得したバッジ

先着50名に入れたので、ステンレスボトル、トートバッグ、シールを頂いた。ステンレスボトルはいい感じだ。

これからJetpack Composeを使うという人は、とりあえずこのpathwayを一通りやると良い。

これをやると、Jetpack Composeを使う上での要点、思想、パフォーマンスなどが学べる。

まだAndroidアプリ開発したことないという人には早いと思う。そういう人には以下がおすすめ

Android Basics in Kotlin course  |  Android Developers

Android Basics with Compose course  |  Android Developers

AndroidでParcelable、Serializable、Enumのクラスを使う時は@Keepも共に使おう

AndroidアプリではProGuardへの対応はまあ必須である。

圧縮プロセスの過程で、Parcelable、Serializable、Enum のクラス名が難読化されないようにする必要がある。その対応方法

@Keep class ParcelableArg : Parcelable { ... }

@Keep class SerializableArg : Serializable { ... }

@Keep enum class EnumArg { ... }
  • もしくはproguard-rules.proに追記する
-keepnames class com.path.to.your.ParcelableArg
-keepnames class com.path.to.your.SerializableArg
-keepnames class com.path.to.your.EnumArg

どちらかをやっておけばよい。

説明がnavigationのところにあるのがモヤモヤ感

developer.android.com

Jetpack DataStoreを消去する

公式に良いのが見つからなかったのでメモ

  • Preferences DataStore
// 消去
context.dataStore.edit { it.clear() }

// 定義
val Context.dataStore by preferencesDataStore(name = "settings")
  • Proto DataStore
// 消去
context.datastore.updateData { it.toBuilder().clear().build() }

// 定義
object SettingsSerializer : Serializer<Settings> {
  override val defaultValue: Settings = Settings.getDefaultInstance()

  override suspend fun readFrom(input: InputStream): Settings {
    try {
      return Settings.parseFrom(input)
    } catch (exception: InvalidProtocolBufferException) {
      throw CorruptionException("Cannot read proto.", exception)
    }
  }

  override suspend fun writeTo(
    t: Settings,
    output: OutputStream) = t.writeTo(output)
}

val Context.settingsDataStore: DataStore<Settings> by dataStore(
  fileName = "settings.pb",
  serializer = SettingsSerializer
)

android - How to clear jetpack datastore data on specific condition - Stack Overflow

  • Proto DataStore

https://developer.android.com/topic/libraries/architecture/datastore#proto-create

  • codelab

Proto DataStore を使用する  |  Android Developers

KotlinのCharをIntにする

KotlinのCharを10進数のIntにするにはdigitToInt()

digitToInt - Kotlin Programming Language Kotlinバージョンは1.5以上

println('5'.digitToInt()) // 5
println('3'.digitToInt(radix = 8)) // 3
println('A'.digitToInt(radix = 16)) // 10
println('k'.digitToInt(radix = 36)) // 20

また、radixは2から36まで

ComposeViewでのテキストのautoLink対応

Text()にTextViewのandroid:autoLinkに相当するものがなかったので、実装

@Composable
fun DefaultLinkifyText(
    modifier: Modifier = Modifier,
    text: String?,
    textAppearance: Int = android.R.style.TextAppearance_Material_Body2
) {
    val context = LocalContext.current
    val customLinkifyTextView = remember {
        TextView(context)
    }
    AndroidView(modifier = modifier, factory = { customLinkifyTextView }) { textView ->
        textView.setTextAppearance(textAppearance)
        textView.text = text ?: ""
        LinkifyCompat.addLinks(textView, Linkify.ALL)
        Linkify.addLinks(
            textView, Patterns.PHONE, "tel:",
            Linkify.sPhoneNumberMatchFilter, Linkify.sPhoneNumberTransformFilter
        )
        textView.movementMethod = LinkMovementMethod.getInstance()
    }
}

stackoverflow.com

ListAdapterのサンプル実装

abstract class ListAdapter : RecyclerView.Adapter developer.android.com

サンプル実装

data class Tweet(
    val text: String,
    val id: Long,
)


class TweetAdapter(
    private val onClick: (Tweet) -> Unit
) : ListAdapter<Tweet, TweetAdapter.ItemViewHolder>(DIFF_UTIL_ITEM_CALLBACK) {

    class ItemViewHolder(val view: View) : RecyclerView.ViewHolder(view) {
        ---
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder {
        val adapterLayout =
            LayoutInflater.from(parent.context).inflate(R.layout.list_tweet, parent, false)

        return ItemViewHolder(adapterLayout)
    }

    override fun onBindViewHolder(holder: ItemViewHolder, position: Int) {
        val tweet = getItem(position)
        holder.view.setOnClickListener { onClick(tweet) }
    }

    companion object {
        val DIFF_UTIL_ITEM_CALLBACK = object : DiffUtil.ItemCallback<Tweet>() {
            override fun areItemsTheSame(oldItem: Tweet, newItem: Tweet) =
                oldItem.id == newItem.id

            override fun areContentsTheSame(oldItem: Tweet, newItem: Tweet) =
                oldItem == newItem
        }
    }
}