命名規則(キャメルケース, パスカルケース, スネークケース, ケバブケース)と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 } } }