ラベル 備忘録 の投稿を表示しています。 すべての投稿を表示
ラベル 備忘録 の投稿を表示しています。 すべての投稿を表示

2025年3月22日土曜日

Android/Jetpack Compose Imageに関するパラメータを紹介

どうも。どっことです。今回はJetpack ComposeのImageコンポーサブルについてチートシートを紹介したいと思います。

Imageコンポーサブルとは

Imageコンポーサブルは、名前の通り画像やイメージを表示するコンポーサブルです。まずはAndroidViewのImageViewで実装していたことが、Jetpack Composeでも同様に実現できるのかが気になるところですが、結局ImageViewで重要な設定であったscaleType、つまりイメージの見せ方についての設定がそれに相当するcontentScaleで実現でき、それ以外はModifierを使えば済んでしまうようです。(つまりImageに関する紹介がほとんどない...)

このページではscaleTypeに相当するcontentScaleについて軽く触れ、その設定がどのような見え方をするのかは公式サイトの方にお任せしようと思います。

Imageコンポーサブルを使うときのパラメータチートシート

まずは、必要最小限で設定できるImageのパラメータです。

Image(
  painter = painterResource(id = R.drawable.dog), // リソースから画像表示
  contentDescription = stringResource(id = R.string.dog_content_description) // 説明文
)

contentScale

contentScaleにはいくつかの設定項目があるので、一覧で紹介します。

  • ContentScale.Fit
    • アスペクト比を維持しながら拡大・縮小
    • scaleTypeのfitCenter相当
  • ContentScale.Crop
    • 空きスペースがなくなるように画像を拡大表示(くり抜き)
  • ContentScale.FillHeight
    • アスペクト比を維持しながら、高さに合わせて拡大・縮小
  • ContentScale.FillWidth
    • アスペクト比を維持しながら、幅に合わせて拡大・縮小
  • ContentScale.FillBounds
    • Viewの大きさに合わせて拡大・縮小(画像が歪む)
    • scaleTypeのfitXY相当
  • ContentScale.Inside
    • アスペクト比を維持しながら、縮小(拡大はしない)
  • ContentScale.None
    • 画像に対して何もしない
    • scaleTypeのcenter相当

まとめ

今回はImageコンポーサブルについて紹介しました。正直Image自体には目新しいパラメータがなかったので、contentScaleに関する紹介程度となりましたが、アプリ開発においてイメージの表示は必須機能なので、contentScaleのパラメータについては理解を進ませておきたいところです。

参考


2025年2月22日土曜日

Android/Jetpack Compose Modifierに関するパラメータを紹介

どうも。どっことです。今回はJetpack ComposeのModifierについてチートシートを紹介したいと思います。

前回はTextコンポーサブルを紹介しましたが、「そもそも共通で設定するパラメータってどこで管理するねん」となりまして、調べたらModifierというオブジェクトがあることがわかりました。 今回はこのModifierについて、チートシートとして紹介したいと思います。

Modifierオブジェクトとは

Modifierは、コンポーサブルに対して設定可能な共通のパラメータを管理しているオブジェクトです。 AndroidViewがわかる人なら、Viewに対して設定できる項目くらいの理解で問題ないと思います。

Modifierを使うときのパラメータチートシート

Modifierで設定できるパラメータは(よく使うものは)以下です。

    // ****** 横幅指定関連 ****** // 
Modifier.width(20.dp)                    // 幅指定(layout_width)
    .fillMaxWidth()                      // 幅いっぱい(layout_width="match_parent")
    .widthIn(20.dp, 20.dp)               // 最小・最大幅指定(minWidth,maxWidth)

    //****** 高さ指定関連 ******//
    .height(20.dp)                       // 高さ指定(layout_height)
    .fillMaxHeight()                     // 高さいっぱい(layout_height="match_parent")
    .heightIn(20.dp, 20.dp)              // 最小・最大高さ指定(minHeight, maxHeight)
    
    //****** 縦横まとめて指定 ******//
    .size(20.dp)                         // 縦横指定(layout_width,layout_height) 
    .size(20.dp, 20.dp)                  // 縦横指定(layout_width,layout_height) 
    .fillMaxSize()                       // 縦横幅いっぱい (layout_width="match_parent"/layout_height="match_parent")
    .sizeIn(20.dp, 20.dp, 50.dp, 50.dp)  // 最小・最大縦横指定(minWidth, minHeight, maxWidth, maxHeight) 
    
    //****** background関連 ******//
    .background(Color.Red)               // 背景色指定(background)
    
    //****** padding関連 ******//
    .padding(top = 10.dp)                // 上部余白 (paddingTop)
    .padding(start = 10.dp)              // 左余白 (paddingStart)
    .padding(end = 10.dp)                // 右余白 (paddingEnd)
    .padding(bottom = 10.dp)             // 下部余白 (paddingBottom)
    .padding(horizontal = 10.dp)         // 左右余白 (paddingHorizontal)
    .padding(vertical = 10.dp)           // 上下余白 (paddingVertical)
    .padding(10.dp)                      // 上下左右余白 (padding)
    
    //****** 位置調整関連 ******//
    .align(Alignment.CenterHorizontally) // layout_gravity(左右位置, Columnコンポーネント内などで)
    .align(Alignment.CenterVertically)   // layout_gravity(上下位置, Rowコンポーネント内などで)
    
    //****** タップ処理関連 ******//
    .clickable { /** */ }                // タップ処理(setOnClickListener)
    
    //****** 枠線関連 ******//
    .border(BorderStroke(3.dp, Color.Blue)) // 枠線をつける(witdh, color)

    //****** 角丸関連 ******//
    .background(Color.Red, RoundedCornerShape(10.dp))                  // 角丸背景にする
    .border(BorderStroke(3.dp, Color.Blue), RoundedCornerShape(10.dp)) // 角丸枠線をつけるそ

その他

dimens.xmlに定義した値をpadding/marginの値として使いたい

dimensionResourceを使えばリソース定義を参照できます。以下、参考ページから転記。

// In the res/values/dimens.xml file
// <dimen name="padding_small">8dp</dimen>
// In your Compose code
val smallPadding = dimensionResource(R.dimen.padding_small)
Text(
    text = "...",
    modifier = Modifier.padding(smallPadding)
)

まとめ

今回はModifierオブジェクトで設定できるパラメータについてチートシートとして紹介しました。目を通してみると、角丸の実装がサポートされるようになったのは非常に嬉しいポイントだと思いました。この記事も参考になりそうな項目を見つけたら随時更新していく予定ですので、参考にしていただけますと幸いです。

次回やるとしたら、Imageコンポーネントについて同様に紹介しようと思います。

参考

2025年2月15日土曜日

Android/Jetpack Compose Textに関するパラメータを紹介

どうも。どっことです。今回はJetpack ComposeのTextコンポーサブルについてチートシートを紹介したいと思います。

これまでのAndroidViewから、Jetpack Composeに移行が完了できた人も少なくないのではないでしょうか。私はそんな移行できていない人間の一人なのですが、今回はそんなJetpack Composeで画面を実装する時に「これってどうやって実装するんだっけ!?」となってもすぐに解決できるよう、チートシートとしてこのページに整理したいと思います。

Textコンポーサブルとは

Textコンポーサブルは、AndroidViewでいうところのTextView、つまりキホンのキですね。テキストを表示せずにアプリを作ることはできないので、まずはここから入るのが王道だと思います。

Textコンポーサブルをつかうときのパラメータチートシート

Textコンポーサブルに設定できるパラメータは(よく使うものは)以下です。

Text(
  "Hello World", 
  fontSize = 24.sp,    // テキストサイズ
  lineHeight = 30.sp,  // 行の高さ
  maxLine = 3,         // 最大行数
  minLine = 1,         // 最小行数
  color = Color.Red,   // テキスト色
  fontStyle = FontStyle.Italic, // テキストスタイル(斜体)
  fontWeight = FontWeight.Bold, // テキストスタイル(太字)
  textAlign = TextAlign.Center, // テキストの位置(gravity)
  overflow = TextOverflow.Ellpsis // テキストが収まらない場合の省略表示(ellipsize)
)

その他の使い方

リソースを参照してテキストを表示する

stringResourceを利用すると、リソースのテキストを参照できます。

Text(stringResource(R.string.app_name))

表示テキストを装飾する

buildAnnotatedStringを利用すると、装飾されたテキストを表示することができるらしいです。

今回は割愛。

まとめ

今回はTextコンポーサブルでよく使うであろうパラメータについて紹介しました。AndroidViewがDeprecatedになる前にJetpackComposeを身につけておきたいですね。

2023年12月12日火曜日

Android テキスト周りの超細かい余白を取得する方法を解説

余白をテキストのピクセル単位でデザイン要求してくるデザイナー、絶対に許さない。

解説

テキストのベースラインから、上の余白(top, ascent)や下の余白(descentやbottom)をピクセル単位で取得することができます。この値を使って、数ピクセル単位の余白のズレも調整することができます。

val textPaint = Paint(Paint.ANTI_ALIAS_FLAG)
textPaint.setTextSize(12)
// FontMetricsの取得
val fontMetrics : FontMetrics = textPaint.getFontMetrics()
val topY = fontMetrics.top
val ascentY = fontMetrics.ascent
val descentY = fontMetrics.descent
val bottomY = fontMetrics.bottom

正直に言います。もう二度とやりたくありません。

参考

2023年10月18日水曜日

2023年10月16日月曜日

iOS 可変長引数を持つメソッドの定義

Javaと似てて、末尾に ... を追加するだけ。参照する際は、配列と同じように扱える。

func print(texts: String...) {
    // 配列のように要素数を参照できる
    if texts.count == 0 {
       return
    }
    // 配列のように要素を参照できる
    print("first: \(texts[0])")
    for text in texts {
      print("element: \(text)")
    }
}

参考

2023年10月13日金曜日

HTML/CSS CSSを設定するときに頻出する設定項目

このブログの表示感を調整するためにCSSをカスタマイズしていたが、毎回調べなおしていたので備忘録。

  • width
    • タグ要素の幅。divで頻出。
  • height
    • タグ要素の幅。divで頻出。
  • background-color
    • タグ要素内の背景色。RGB指定。
  • font-size
    • タグ要素内のテキストのテキストサイズ。 指定方法が色々ある。
    • px,emとか。
    • larger/smaller (親要素のフォントサイズとの相対)とか。
  • color
    • タグ要素内のテキストの色。RGB指定。
  • font-style
    • タグ要素内のテキストのスタイル。
    • normalitalicobliqueとか。
  • padding
    • タグ要素内に設定する余白。px,em指定。
    • 1つ指定は全方向に同一の値を設定。
    • 4つ指定はの順に設定される。
  • margin
    • タグ要素外に設定する余白。px,em指定。
    • 1つ指定は全方向に同一の値を設定。
    • 4つ指定はの順に設定される。
  • list-style
    • リストタグ(ul)限定。左につくボッチの指定。
    • noneを指定すると消える。
  • border-style
    • 枠線を表示する際のスタイルを指定できる。
    • solid(実線),dashed(破線)など。
  • border-width
    • 枠線を表示する際の枠線の太さ設定。
    • px, em指定。
  • border-color
    • 枠線を表示する際の枠線の色指定。
    • RGB指定。
  • border
    • border-style, border-width, border-colorを一括で指定できるプロパティ。

2023年10月12日木曜日

iOS ボタンタップ中の色を変えたい

ViewのプロパティであるisHighlightedの更新を受けて、背景色を設定するだけ。

カスタムViewを実装する際に、isHighlightedをオーバーライドし、didSetbackgroundColorを設定すればいいだけ。こんなん。

override open var isHighlighted: Bool {
    didSet {
        backgroundColor = isHighlighted ? .lightGray : .blue
    }
}

ちなみにisHighlightedとは、Androidでいうところのstate_pressedUIButtonなどのUIControlクラスを継承したViewは状態に対して背景を変えるメソッドがあるため、それを使えばタップ中の色を変えることができる。

参考

2023年10月11日水曜日

iOS UIViewを角丸にしたり、枠線を付ける実装方法を解説

どうも。どっことです。今回は、iOSのUIViewについて角丸や枠線をつけ方について実装を解説していきたいと思います。

iOSで角丸や枠線を付ける実装方法

私自身がAndroidエンジニアとしてやってきた時間が長いので、どうしてもAndroid開発者目線となってしまうのですが、Viewを角丸にしたり、枠線をつけたりする実装が本当に面倒くさいです。簡単に見せるだけでも、新規に背景用ファイルを用意してあげる必要があります。

しかし、iOSは角丸や枠線を超簡単に実装できます。本当に羨ましいです。別に悔しくねーし。

実装方法

それでは、実装方法について解説していきたいと思います。

角丸にする

UIViewが共通に持っているlayerという変数に対応するパラメータがあるので、コード上であれば以下に値を設定することで角丸にすることができます。

layer.cornerRadius

枠線を付ける

枠線の実装も同様で、以下に値を設定することで枠線を付けることができます。

layer.borderWidth
layer.borderUIColor

ちなみに、borderUIColorCGColorクラスを設定する必要があることに注意してください。

まとめ

今回は、UIViewを角丸にしたり枠線をつけたりする実装方法を解説しました。特に見せ方を柔らかくする角丸の実装が簡単なのは、iOSはとても良いなと思いました。

参考

2023年9月21日木曜日

Android つぶやきながらJetpackComposeのサンプルを覗いてみる その1

巷ではJetpackComposeが流行っているらしい。これまでAndroid開発では xml により画面のレイアウトを実装していたけど、今後は 宣言型UIフレームワーク が主流になってくる様子。xml が慣れている人にとってはまだすこし取っ掛かりにくいけど、画面の構成がより明示的に表現されるのであれば、それはそれで嬉しいと思う。

サンプルを見てみる。

Android Studio>File>New>Import Sample...で、入力フォームにcomposeを入力すると、それっぽいものがフィルタリングされるので、適当に選択する。Androidarchitecture>Architectureを選択してみる。(どうやらTODOアプリのサンプルが見れる様子。SunFlowerも画像表示のサンプルとしては重要だけど、今回はシンプルそうな方を眺めてみる)

とりあえずDLが終わったけどどこを見ればいいのかわからないので、AndroidManifest.xmlを見てみる。TodoActivity というActivityが登録してあるみたい。

TodoActivityを覗いてみる

override fun onCreate(savedInstanceState: Bundle?) {
  super.onCreate(savedInstanceState)
  setContent {
    AppCompatTheme {
      TodoNavGraph()
    }
  }
}

setContentしか実装されていない... AppCompatThemeは名前からなんとなくテーマが設定されているコンポーネントかと予想できるので、その内側に設定されているTodoNavGraph を見てみる。(deprecatedなっていたが、趣旨から外れるのでここでは気にしないことにする。)

TodoNavGraphを覗いてみる

で、初っ端にでてきた実装がこれ。

@Composable
fun TodoNavGraph(
  modifier: Modifier = Modifier,
  navController: NavHostController = rememberNavController(),
  coroutineScope: CoroutineScope = rememberCoroutineScope(),
  drawerState: DrawerState = rememberDrawerState(initialValue = DrawerValue.Closed),
  startDestination: String = TodoDestinations.TASKS_ROUTE,
  navActions: TodoNavigationActions = remember(navController) {
    TodoNavigationActions(navController)
  }
) {
...

fun... メソッドやんけ...しかも戻り値もない...ほんとうにこれでいいんか...?もう少し眺めてみよう。

@Composableアノテーションが付与されたメソッド内の実装を眺めてみる。

どうやらNavHostというコンポーネント内で、必要なものを構成するぽい。

NavHost(
  navController = navController,
  startDestination = startDestination,
  modifier = modifier
) {

んで、その NavHost での実装は composable というコンポーネントで構成されている。

composable(
  TodoDestinations.TASKS_ROUTE,
  arguments = listOf( navArgument(USER_MESSAGE_ARG) { type = NavType.IntType; defaultValue = 0 }
  )
) { ... }
composable(TodoDestinations.STATISTICS_ROUTE) { ... }
composable(
  TodoDestinations.ADD_EDIT_TASK_ROUTE,
  arguments = listOf(
      navArgument(TITLE_ARG) { type = NavType.IntType },
      navArgument(TASK_ID_ARG) { type = NavType.StringType; nullable = true },
  )
) { ... }

で、そのコンポーネントが各画面やサイドメニュー(ドロワー)の要素に対応していそう。

まとめ(所感)

ここまでの所感など

  • TodoDestinations で定義された定数が、このアプリを構成する画面やドロワーに対応していそうに見える。であれば実際に運用する場合この定義は列挙型にしておいて、引数としてはordinalなどを渡してあげたほうが良さそうな。
  • TodoDestinations.ADD_EDIT_TASK_ROUTEcomposable を見ると、どうやら画面に渡すパラメータもここで定義しておく様子。ここでの定義と実際の画面とで乖離が起きないよう、画面側のどこかで管理しておいたほうが良さそう。
  • アプリを構成する画面定義は見えたけど、各画面間での画面遷移や処理結果の戻しなどをどのように実装するかは見えていないので、次にサンプルを眺めるときはこの辺りをフォーカスして確認できれば嬉しい。

とりあえずここまで。

参考

2023年8月11日金曜日

Android 裏にいるActivityもすべて終了するfinishAffinityメソッドを紹介

どうも。どっことです。今回はスタックに積まれているActivityをすべて終了させるメソッドを紹介します。

裏のActivityもすべて終了するfinishAffinity

Activity AからActivity BstartActivity()でスタックを積んだとき、Activity Aが明示的に自身をfinish()させなければ、Activity Bの裏にActivity Aはスタックとして存在します。

そしてこのときActivity Bfinish()を呼び、自身を終了させても、スタックに残っているActivity Aが表示され、アプリを終了することができません。

今回は、Activity BからスタックにいるすべてのActivityを終了させるメソッドを紹介したいと思います。

Activity#finishAffinity()

すべてのActivityを終了させるにはfinishAffinity() というメソッドを使います。単純なケースであれば、このメソッドを呼び出すことで裏にいるActivityをすべて終了することができます。

単純なケースと書いたのは、Activityには親和性(affinity)という概念があるためです。これが厳格に管理されているActivityですと、今回のケースは期待した動作をしない可能性があります。

ただし基本的に同一のAndroidアプリという領域のActivityであるためaffinityが厳格に管理されているケースは非常に稀で、まずはやりたいことが実現できるかをこのメソッドを呼んで試してみるのが解決への一番の近道になるかと思います。

参考

2023年8月9日水曜日

Android AndroidPでhttp通信に失敗する問題

targetSDKVersionをAndroidP以上に設定すると、セキュリティの問題でアプリでのhttp通信が失敗する。AndroidManifest.xml のapplicationタグに以下の属性を追加する。

<application
    ....
    android:usesCleartextTraffic="true">
</application>

開発段階ではローカル環境にサーバ立ててそこにスタブデータを置いて動作確認することが多いが、本番環境では回避すべき設定なので、debug/releaseでAndroidManifest.xmlを分けるなど、きちんと切り分けること。

2023年8月8日火曜日

HTML/CSS マウスオーバーしたときの表示をカスタマイズする

マウスオーバーしたときに表示を切り替えたいときは、CSSに疑似クラスを指定する。

a:hover {
  マウスオーバー中に表示したい内容
}

この指定を複数の要素に指定することで、例えばテキストやイメージの表示切替などもできる。

a:hover {
  マウスオーバー中に表示したい内容
}
.a-covered:hover {
  マウスオーバー中に表示したい内容
}

マウスオーバー以外にも疑似クラスの指定により表示を変えられるものは以下。

  • link:御訪問リンク
  • visited:訪問済みリンク
  • hover : マウスオーバー
  • active : リンククリック中

参考

2023年7月30日日曜日

正規表現 文字列の一部だけを加工したい

Logcatとかコンソールでログとか漁ってるときに、「必要なところを探して、必要な所だけくり抜くのマジだるい…」ってなる。

正規表現を使えば簡単なんだけど、「必要な所だけくり抜く」表現がわからなかったので放置してた。でもいい加減(ちゃんと書ければ秒で済む話を何時間もかけて作業してるの、マジ無能…と思い)なんとかしたかったので、調べて備忘録として残す。

知ってしまえば本当に簡単なんだわ。

検索での表現

(検索したいけど置換したくない文字)なにかしら置換したい文字(検索したいけど置換したくない文字)

置換の表現

$1置換後の文字$2

ポイントは

  • 「くり抜くところ」を括弧書き()にすると、置換するときに$*(数字)て書けば検索したときに括弧書きに該当するところがそのまま残る。ちなみに、カッコはグループ化する表現らしい。
  • そのまま残したいところが複数ある場合でも、$に付ける数字を増やしていけばOK。

<div>タグを<p>タグに変えたい。"/"も気にせず置換したい。

検索での表現

<(/*)div>
  • 検索対象のdivを指定する。
  • /があるかないかは、置換後のテキストにも影響するので、()で書く。
  • *は0文字以上の意味。

置換での表現

<$1p>

  • 置換したい文字としてpタグを指定する。
  • ()で書いた箇所が$1として置換後のテキストに反映される。
  • 今回は、/があった場合に限り置換後に/が入るようにする。

参考

2023年7月26日水曜日

Android Activityのスタックをクリアする

Intent.FLAG_ACTIVITY_CLEAR_TOPIntent#setFlag(int)でセットするだけ。

fun showTop(View view) {
  let intent = Intent(getApplication(), MainActivity::class.java)
  intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
  startActivity(intent);
}

参考

2023年7月24日月曜日

iOS Xcode ドキュメンテーションコメントを追加するショートカットキーを紹介

メソッドの上部で option + command + / を入力すると、自動でドキュメンテーションコメントが追加されます。

あとで見返すときのために、「何をするメソッドか」「引数にはどんな値が必要か、どういう値が想定されているか」「戻り値は何か」などを記入しておきましょう。

参考

2023年7月23日日曜日

Android 共有ボタンのデータを受け取る、送信する

どうも。どっことです。今回は共有ボタンの実装について解説します。

X(旧:Twitter)でのポストやブログの記事など、Webにはいたる所に共有ボタンがあります。今回は共有ボタンによりデータが送信された時にアプリ側でそれを受け取るための実装と、アプリで共有ボタンを用意する実装をそれぞれ解説していきます。

受け取る側の実装

よくあるBroadcastReceiverの実装パターンです。2つやることがあります。

1つは、AndroidManifest.xmlに共有ボタンによるデータ送信のintentを受け取る宣言を明記します。

<activity android:name=".MainActivity" >
  <intent-filter> 
    <action android:name="android.intent.action.SEND" />
    <category android:name="android.intent.category.DEFAULT" />
    <data android:mimeType="text/plain" />
  </intent-filter>
</activity>

そしてもう一つは、実際に受け取った時の処理です。受け取るActivityBroadcastReceiverに対してインテントフィルターを設定します。Activityでは、メンバ変数として持っているintentを、BroadcastReceiverではBroadcastReceiver#onReceivedの引数として渡されるintentを参照することで、詰められているデータにアクセスすることができます。

override fun onCreate(savedInstanceState: Bundle?) {
  if (intent?.action == Intent.ACTION_SEND) {
    val text = intent.getStringExtra(Intent.EXTRA_TEXT)
    // 良しなにする
  }
}

送る側の実装

こちらもよくあるstartActivity(Intent)の実装です。

ただintentの作り方だけちょっと独特で、共有したいデータを詰めたintentIntent#createChooserに渡します。そうして返されたintentstartActivityで投げます。

val temp: Intent = Intent().apply {
  action = Intent.ACTION_SEND
  putExtra(Intent.EXTRA_TEXT, "テストのテキストです")
  type = "text/plain"
}
startActivity(Intent.createChooser(temp, null))

まとめ

今回は共有ボタンに関するAndroidの実装を解説しました。特に共有ボタンからデータを受け取る処理はアプリを利用してもらう契機として重要なので、参考にしていただけると幸いです。

参考

2023年7月21日金曜日

iOS 数値を0埋めしてテキストとして表示する

Androidでは、String.format(text, value)としてテキストを出力させるが、iOSの場合もほぼ同じでStringのコンストラクタに入れるだけ。

let number = 3
let numberString = String(format: "%03d", number) // 003

参考

2023年7月15日土曜日

CI/CD 最近考えていること リリース手順が面倒くさい

毎回毎回、

署名キー探して、
設定値を入力してビルドして
aabファイル生成して
プレイストアにアップロードして

ってフローが面倒になった。どうにかならないものか。

少なくても、署名キー探す~aabファイル生成するまでを自動化できることは知っているけど、例えばGitHubActionでやるなら生成したaabファイルや署名キーを秘匿にしないといけない都合でリポジトリも秘匿にしないといけないし、でもそれを秘匿にするのは正直あまりうれしくない(できるだけパブリックにしておきたい)。どうにかならないものか。

って考えたときに、「ソースを管理する領域(GitHub)とaabファイル生成をする領域を別にすればいいんじゃん。そうすればソースはパブリックのままでいいし、署名キーやら生成したaabファイルやらも秘匿の状態を保てる。とても幸せやん。」と気づいた。

上記を整理すると以下のフローとなる。

  1. ローカル環境で開発
  2. GitHubに変更をプッシュ
  3. GitHubはGitHubActionのジョブを回す
    • テストを回したり
    • Readme更新したり
    • CI/CDサービスに登録してあるジョブのトリガーを引いたり ★1
  4. 前項のトリガーを受けて、CI/CDサービスはaabファイルを生成する。
    1. GitHubからソースコードをクローンしてくる。
    2. aabファイルを生成し、成果物として管理。
  5. CI/CDサービスはプレイストアにaabファイルをアップロードする。 ★2
    1. どこまでできるか次第だが、リリースノートなども合わせてアップロードできればなお嬉しい。
  6. CI/CDサービスはすべての処理が完了したことを通知する。
  7. 私はそれを確認して、特に問題なければリリース。何かあれば適宜修正。

素敵だ。上記フローを実現するために必要な調査は★1,2の内容。

  • ★1:登録したジョブを実行するトリガーを外部から引くことはできる?(CI/CDのサービス次第?)
  • ★2:aabファイルをプレイストアにアップロードするクチ(=IF)は用意されている?どこまでの情報をアップロードできる?

まあ、「そんなのありません」ってことはないんだろうけどね。特に★1については「サービスとしてはあるけど、有料会員様限定のサービスなんすよ」かもしれないし。

というわけで、考えていることでした。調査した結果とか、更新があればまた改めて投稿します。

2023年7月12日水曜日

Android OnClickListener はXMLレイアウトファイルからでも設定できる

どうも。どっことです。今回はXML上でクリックリスナーを設定する実装方法について解説します。

XMLでクリックリスナーを設定する

dataBindingでは、XMLでクリックリスナーを設定する処理はよくある実装ですが、実はdataBindingを使わない通常のケースでも似たような実装をすることができます。

解説

XMLでクリックリスナーを設定するには、任意のViewに対して android:onClickを設定してあげます。たとえば、TextViewに設定するときは以下のような形です。

<TextView
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:text="テスト"
   android:onClick="testClicked" />

あとはこのXMLを読み込むクラスに、testClicked(View v)関数を実装します。

override fun testClicked(v: View) {
  Log.d("TAG", "TextView テスト is clicked")
}

今回設定したonClickの値はtestClickedなのでそれに合わせていますが、実際に利用する際はTextViewがどんな表示をしているかなどを表現した関数名にしてあげると後々にコードを追いやすくなるかと思います。

まとめ

今回はXMLでクリックリスナーを設定する実装方法について解説しました。dataBindingでも似たような実装方法があると思いますが、そうでなくてもシンプルに利用することができるので、参考にしていただけると幸いです。

参考

移行予定

どうも。どっことです。 タイトルの通りですが、諸事情により GitHubPage に移行予定です。 https://mkt120.github.io/ この備忘録に記載の内容を転記しつつ、今後はこちらのページを更新していく予定です。