<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Spacer</title>
	<atom:link href="https://bps-e.com/dev/tag/spacer/feed/" rel="self" type="application/rss+xml" />
	<link>https://bps-e.com/dev</link>
	<description>android アプリ開発 kotlin + jetpack compose + material 3</description>
	<lastBuildDate>Thu, 06 Jul 2023 03:01:42 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.8.3</generator>

<image>
	<url>https://bps-e.com/dev/wp-content/uploads/2022/10/cropped-logo3-32x32.png</url>
	<title>Spacer</title>
	<link>https://bps-e.com/dev</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>[Android] 007. Layout / Material3 Control</title>
		<link>https://bps-e.com/dev/android-007/</link>
		
		<dc:creator><![CDATA[bps-e]]></dc:creator>
		<pubDate>Thu, 27 Oct 2022 21:00:07 +0000</pubDate>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Jetpack Compose]]></category>
		<category><![CDATA[Kotlin]]></category>
		<category><![CDATA[Material 3]]></category>
		<category><![CDATA[Bitmap]]></category>
		<category><![CDATA[Box]]></category>
		<category><![CDATA[BoxWithConstraints]]></category>
		<category><![CDATA[Canvas]]></category>
		<category><![CDATA[Column]]></category>
		<category><![CDATA[LazyColumn]]></category>
		<category><![CDATA[LazyHorizontalGrid]]></category>
		<category><![CDATA[LazyRow]]></category>
		<category><![CDATA[LazyVerticalGrid]]></category>
		<category><![CDATA[Row]]></category>
		<category><![CDATA[Scaffold]]></category>
		<category><![CDATA[Spacer]]></category>
		<category><![CDATA[Surface]]></category>
		<category><![CDATA[キーボード隠す]]></category>
		<category><![CDATA[画面に線]]></category>
		<category><![CDATA[背景グラデーション]]></category>
		<category><![CDATA[背景画像]]></category>
		<guid isPermaLink="false">https://bps-e.com/dev/?p=171</guid>

					<description><![CDATA[詳しくは以下とチュートリアルを参照https://developer.android.com/jetpack/compose/layouts/basics?hl=ja Layout Surface / Scaffold  [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>詳しくは以下とチュートリアルを参照<br><a rel="noopener" href="https://developer.android.com/jetpack/compose/layouts/basics?hl=ja" target="_blank">https://developer.android.com/jetpack/compose/layouts/basics?hl=ja</a></p>



<h2 class="wp-block-heading"><span id="toc1">Layout</span></h2>



<h3 class="wp-block-heading"><span id="toc2">Surface / Scaffold</span></h3>



<p>TopAppBarやFABなどを規定の場所に配置したい場合はScaffoldをでない場合はSurfaceをベースのレイアウトに使用<br>Navigationなどで画面遷移する場合で前の画面に戻るUIや処理が無い場合はScaffoldでTopbarの設定をしBackボタンを配置してください<br>Scaffoldを使用する場合は使用するメソッドなどで@OptIn(ExperimentalMaterial3Api::class)などを付ける</p>



<p>Scaffoldでtopbarを指定した場合contentがtopbarの後ろにめり込みます<br>LazyColumn(上下スクロールリスト)だけの画面などの場合は問題無いかもしれませんが困るので以下のようにする</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-kt" data-lang="Kotlin"><code>Scaffold { innerPadding -&gt;
    Box(modifier = Modifier.padding(innerPadding)) {
        ...          
    }
}</code></pre></div>



<h3 class="wp-block-heading"><span id="toc3">Box / BoxWithConstraints</span></h3>



<p>コントロールを重ねて表示したい場合などに使う<br>親の制約(例えば画面サイズ)を把握して配置したい場合はBoxWithConstraintsを使う</p>



<h3 class="wp-block-heading"><span id="toc4">Column / Row</span></h3>



<p>基本の縦横レイアウト</p>



<p>サイズはModifierで指定しなかった場合はcontentのサイズに依存する<br>画面サイズの割合でサイズを指定したい場合はModifier.weightを使う<br>weightは2箇所以上指定して、指定した数値の合計の割合のサイズになる</p>



<p>左右中央寄せをしたい場合は以下のような実装</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-plain"><code>Row(modifier = Modifier.fillMaxWidth().padding(8.dp, 0.dp, 8.dp, 0.dp),
    verticalAlignment = Alignment.CenterVertically,
    horizontalArrangement = Arrangement.SpaceBetween
) {
    Text(&quot;左&quot;)
    Text(&quot;中央&quot;)
    Text(&quot;右&quot;)
}</code></pre></div>



<h3 class="wp-block-heading"><span id="toc5">リスト / グリット</span></h3>



<p>LazyColumn / LazyRow / LazyVerticalGrid / LazyHorizontalGrid<br>詳しくは以下参照<br><a rel="noopener" href="https://developer.android.com/jetpack/compose/lists?hl=ja" target="_blank">https://developer.android.com/jetpack/compose/lists?hl=ja</a></p>



<h3 class="wp-block-heading"><span id="toc6">余白</span></h3>



<p>余白を追加したい場合はSpacerを使う</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-plain"><code>Spacer(modifier = Modifier.height(10.dp))</code></pre></div>



<h2 class="wp-block-heading"><span id="toc7">Material3 Contorl</span></h2>



<p>Material 3で使用できるコントロール一覧は以下にあります<br><a rel="noopener" href="https://developer.android.com/reference/kotlin/androidx/compose/material3/package-summary" target="_blank">https://developer.android.com/reference/kotlin/androidx/compose/material3/package-summary</a></p>



<p>FABが円から角丸四角になってたり、BottomAppBarにFABがドッキングできなくなっていたり、おそらくまだ未実装のコントロールなど、以前のMaterialと実装上の違いもあるようです</p>



<p>ここではよく使いそうで用意されているものに少し手をいれたものの覚書きを残します<br>↑<br>この記事を書いている時点でDividerの存在に気がついてなかったです&#8230;<br>単純な線ならDividerを使用してください</p>



<h3 class="wp-block-heading"><span id="toc8">画面に線を引く</span></h3>



<div class="hcb_wrap"><pre class="prism line-numbers lang-kt" data-lang="Kotlin"><code>/**
 * シンプルな横線描画
 *
 * @param color 線の色
 * @param border 線の太さ
 * @param margin 線の描画開始/終了のマージン
 */
@Composable fun Line(
    modifier: Modifier = Modifier,
    color: Color = if (isSystemInDarkTheme()) Color.White else Color.Black,
    border: Dp = 1.dp,
    margin: Dp = 0.dp
) {
    Canvas(modifier.fillMaxWidth().height(border)) {
        drawLine(
            color = color,
            start = Offset(margin.toPx(), border.toPx() / 2),
            end = Offset(size.width - margin.toPx() * 2, border.toPx() / 2),
            strokeWidth = border.toPx(),
            //pathEffect = PathEffect.dashPathEffect(listOf(24f, 24f).toFloatArray(), 0f),
        )
    }
}</code></pre></div>



<h3 class="wp-block-heading"><span id="toc9">背景に画像を表示</span></h3>



<div class="hcb_wrap"><pre class="prism line-numbers lang-kt" data-lang="Kotlin"><code>/**
 * 画面背景(イメージ)
 *
 * @param fileName Assetsに配置した画像ファイル名
 */
@Composable fun ImageBackground(
    fileName: String,
    modifier: Modifier = Modifier,
    content: @Composable () -&gt; Unit
) {
    val context = LocalContext.current
    val bitmap: Bitmap? by rememberSaveable { mutableStateOf(context.assetsToBitmap(fileName)) }

    BoxWithConstraints(modifier = modifier.fillMaxSize()) {
        bitmap?.let {
            Image(
                bitmap = it.asImageBitmap(),
                contentDescription = null,
                modifier = Modifier.fillMaxSize(),
                contentScale = ContentScale.Crop
            )
        }
        content()
    }
}

/**
 * Assetsにあるイメージファイルを読込みBitmapを返す
 */
fun Context.assetsToBitmap(fileName: String): Bitmap? {
    return try {
        with(assets.open(fileName)) {
            BitmapFactory.decodeStream(this)
        }
    } catch (e: IOException) { null }
}</code></pre></div>



<h3 class="wp-block-heading"><span id="toc10">背景をグラデーション</span></h3>



<div class="hcb_wrap"><pre class="prism line-numbers lang-kt" data-lang="Kotlin"><code>/**
 * 画面背景(グラデーション)
 *
 * 参考: Now in Android / Android Open Source Project
 * https://github.com/android/nowinandroid
 *
 * @param topColor 上から下に向かうグラデーション色
 * @param bottomColor 下から上に向かうグラデーション色
 */
@Composable fun GradientBackground(
    modifier: Modifier = Modifier,
    topColor: Color = Color.Unspecified,
    bottomColor: Color = Color.Unspecified,
    content: @Composable () -&gt; Unit
) {
    val currentTopColor by rememberUpdatedState(topColor)
    val currentBottomColor by rememberUpdatedState(bottomColor)

    BoxWithConstraints(modifier = modifier.fillMaxSize().drawWithCache {
        // Compute the start and end coordinates such that the gradients are angled 11.06
        // degrees off the vertical axis
        val offset = size.height * tan(Math.toRadians(11.06).toFloat())

        val start = Offset(size.width / 2 + offset / 2, 0f)
        val end = Offset(size.width / 2 - offset / 2, size.height)

        // Create the top gradient that fades out after the halfway point vertically
        val topGradient = Brush.linearGradient(
            0f to if (currentTopColor == Color.Unspecified) {
                Color.Transparent
            }
            else {
                currentTopColor
            },
            0.724f to Color.Transparent,
            start = start,
            end = end,
        )
        // Create the bottom gradient that fades in before the halfway point vertically
        val bottomGradient = Brush.linearGradient(
            0.2552f to Color.Transparent,
            1f to if (currentBottomColor == Color.Unspecified) {
                Color.Transparent
            }
            else {
                currentBottomColor
            },
            start = start,
            end = end,
        )

        onDrawBehind {
            // There is overlap here, so order is important
            drawRect(topGradient)
            drawRect(bottomGradient)
        }
    }) {
        content()
    }
}</code></pre></div>



<h3 class="wp-block-heading"><span id="toc11">ソフトキーボードを画面タップで隠す</span></h3>



<p>ControlではないですがTextField使用時にほしい機能なので&#8230;</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-kt" data-lang="Kotlin"><code>// フォーカスリセットまたはkeyboardControllerで隠す
val focusRequester = remember { FocusRequester() }
val interactionSource = remember { MutableInteractionSource() }
val keyboardController = LocalSoftwareKeyboardController.current

Surface (modifier = Modifier
    .clickable(
        interactionSource = interactionSource,
        enabled = true,
        indication = null,
        onClick = {
            focusRequester.requestFocus()
        }
    )
    .focusRequester(focusRequester)
    .focusTarget()
    .onFocusChanged {              
        if (it.isFocused) {
            //keyboardController?.hide()
        }
    },
) {}</code></pre></div>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>Android Studio Dolphin 2021.3.1 Patch 1 built on September 30, 2022</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
