命名規則(キャメルケース, パスカルケース, スネークケース, ケバブケース)と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
- 変数は概ねキャメルケース
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をやって、一通り完了したらバッジが貰えるから、それを報告する。
先着50名に入れたので、ステンレスボトル、トートバッグ、シールを頂いた。ステンレスボトルはいい感じだ。
上げるの遅くなったけど、Android Study Jam のグッズを頂いた。しかも先着50名に入ったらしい。ありがとうございます。 pic.twitter.com/aVOoRpNhxR
— ochi (@ochi_tw) 2022年9月5日
これからJetpack Composeを使うという人は、とりあえずこのpathwayを一通りやると良い。
これをやると、Jetpack Composeを使う上での要点、思想、パフォーマンスなどが学べる。
まだAndroidアプリ開発したことないという人には早いと思う。そういう人には以下がおすすめ
AndroidでParcelable、Serializable、Enumのクラスを使う時は@Keepも共に使おう
AndroidアプリではProGuardへの対応はまあ必須である。
圧縮プロセスの過程で、Parcelable、Serializable、Enum のクラス名が難読化されないようにする必要がある。その対応方法
- @Keepアノテーションを使用する
@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のところにあるのがモヤモヤ感
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
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()
}
}
ListAdapterのサンプル実装
abstract class ListAdapter
サンプル実装
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
}
}
}