Kotlin たまに使うことまとめメモ

思い出したら随時追記していきます。

## 非同期でAPIを複数呼びたいとき

```kotlin

lifecycleScope.launch(Dispatchers.IO) {
    val getApiResult = getApi(requestBody)
    val getApiSecondResult = getApiSecond(requestBody)

    withContext(Dispatchers.Main) {
        //APIのレスポンスを使った処理
        binding.view = getApiResult.return_data
        
    }
}


//１つ目のapiを呼ぶ関数
private fun getApi(requestBody: GetApiRequest):  GetApiResponse? {
        val http = RequestApi().getApiRequestObjectPlane().create(GetApi::class.java)
        val response = http.getApiRequest(requestBody).execute()
        return if (response.isSuccessful) response.body() else null
}

//２つ目のapiを呼ぶ関数
private fun getApiSecond(requestBody: GetApiSecondRequest):  GetApiSecondResponse? {
        val http = RequestApi().getApiRequestObjectPlane().create(GetApiSecond::class.java)
        val response = http.postApiSecondRequest(requestBody).execute()
        return if (response.isSuccessful) response.body() else null
}

```

## クリップボードにテキストをコピーする
ボタンを押したとき、クリップボードに文字列をコピーさせます。トーストも表示させてコピーされたことが分かりやすくしてます。
```kotlin
fun copyToClipboard(context: Context, label: String?, text: String?) {
    val clipboardManager =  
    context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager?: return
        clipboardManager.setPrimaryClip(ClipData.newPlainText(label, text))
    }

   
binding.iconCopy.setOnClickListener {
    copyToClipboard(context, "walletAddress", "コピーさせたいテキスト")
    Toast.makeText(getActivity(), "テキストをコピーしました", Toast.LENGTH_SHORT).show()
}
```

## 端末の通知設定を確認する
アプリからユーザー端末の通知設定がONになっているかOFFになっているか確認できます。
```kotlin:SampleActivity
val areNotificationsEnabled = NotificationManagerCompat.from(context).areNotificationsEnabled()

if (areNotificationsEnabled) {
    Log.d("結果","通知設定はONです")
} else {
    Log.d("結果","通知設定はOFFです")
}
```

設定アプリを開いて通知設定を変更するよう促す場合は以下のようにします。

※ちなみにアプリ側で通知設定を直接制御することはできないです。
```kotlin
//通知設定がOFFのときに設定画面に遷移させ、ONにするよう促す
val intent = Intent() 
intent.action = "android.settings.APP_NOTIFICATION_SETTINGS" 
intent.putExtra("app_package", packageName) 
intent.putExtra("app_uid", applicationInfo.uid) startActivity(intent)
```
## 画面を縦で固定化する
横回転させたくないとき、Manifestファイルに以下追加すれば大丈夫です。
```kotlin: AndroidManifest.xml
        android:screenOrientation="portrait"
```

## ステータスバーの色を変更する


```kotlin:SampleActivity
val window: Window = window
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
window.setStatusBarColor(resources.getColor(R.color.white))
```



## リサイクラービューなどで一番下に余白をつける
スクロール可能なビューを使用するとき、大体一番下に余白をつけます。最初の頃は空のビューを設置したりなどしてましたが、以下のようにすると簡単にできます。

```kotlin

<androidx.recyclerview.widget.RecyclerView
    android:id="@+id/RecyclerView"
    android:layout_width="match_parent"
    android:layout_height="800dp"
    android:paddingBottom="200dp"  // この部分
    android:clipToPadding="false"  // この部分
/>
```



## 画像の色を変える
画像の色をフラグメント側で変換する方法です。
```kotlin
//Drawableのリソースを取得する
val originalDrawable = ContextCompat.getDrawable(requireContext(), R.drawable.icon_arrow)

//Drawableをの色を変換する
originalDrawable?.setColorFilter(Color.WHITE, PorterDuff.Mode.SRC_IN)

//ImageViewに変更後のDrawableを設定する
binding.toggleArrow.setImageDrawable(originalDrawable)
```

## はみ出させるレイアウト

```kotlin
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:clipChildren="false"  // この部分
    >
    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/whiteBox"
        android:layout_width="351dp"
        android:layout_height="wrap_content"
        android:clipToPadding="false"     // この部分
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" >

     
        <ImageView
            android:id="@+id/icon_close_button"
            android:layout_width="24dp"
            android:layout_height="24dp"
            android:layout_marginTop="-8dp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

    </androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
```

## 文字の一部の色、サイズをかえる

```kotlin
 val dateViewHolder = holder as DateViewHolder

            val termsAndConditions = SpannableString(dateViewHolder.termsAndConditions.text)

            // テキストの色を変更
            val termsAndConditionsSpan = ForegroundColorSpan(Color.parseColor("#2887EB"))
            termsAndConditions.setSpan(termsAndConditionsSpan, 0, 16, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)

            dateViewHolder.termsAndConditions.text = termsAndConditions


            val applyToMultiple = SpannableString(dateViewHolder.applyToMultiple.text)

            val alertColor = ForegroundColorSpan(Color.parseColor("#FD5B6F"))
            applyToMultiple.setSpan(alertColor, 15, 21, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)

            // サイズ変更
            val alertSize = AbsoluteSizeSpan(18, true)
            applyToMultiple.setSpan(alertSize, 15, 21, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)

            dateViewHolder.applyToMultiple.text = applyToMultiple


            val sixApply = SpannableString(dateViewHolder.sixApply.text)

            sixApply.setSpan(alertColor, 8, 12, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
            sixApply.setSpan(alertSize, 8, 12, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)

            dateViewHolder.sixApply.text = sixApply


```


## webviewの表示

```kotlin
<WebView
            android:id="@+id/web_layout"
            android:layout_width="match_parent" android:layout_height="match_parent"
            android:elevation="200dp"
            android:overScrollMode="always" android:visibility="visible"
            app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent"
            />

```

・webview上でJavaScriptを有効にしたいとき
```kotlin
webView.settings.javaScriptEnabled = true
```

## Adapterにセットされているデータを更新したいとき
```kotlin
itemViewHolder.deleteButton.setOnClickListener {
                notifyDataSetChanged()
            }
```

## 端末の位置情報を取得する

```kotlin
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        binding.selectCurrentLocation.setOnClickListener {
            if (ContextCompat.checkSelfPermission(requireContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                // パーミッションがまだ付与されていない場合、ユーザーにパーミッションを要求する
                requestPermissions(arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), LOCATION_PERMISSION_REQUEST_CODE)
            } else {
                // パーミッションがすでに付与されている場合、位置情報を取得する
                val location = getLocation(requireContext())
                if (location != null) {
                    // 位置情報が取得できた場合
                    val latitude = location.latitude.toString()
                    val longitude = location.longitude.toString()
                    getCurrentLocation(lat=latitude, lon=longitude)
                } else {
                    // 位置情報が取得できなかった場合
                    Toast.makeText(requireContext(), "現在地が取得できません", Toast.LENGTH_SHORT).show()
                }
            }
        }
    }

    private fun getLocation(context: Context): Location? {
        val locationManager = context.getSystemService(Context.LOCATION_SERVICE) as LocationManager
        return if (ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
            locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER)
        } else {
            null
        }
    }

```

## その他参考になった記事

### Adapterの中でActivityやFragmentの関数を使いたいとき

[結局のところRecyclerViewのコールバックはどう書くのがベストなのよ？
](https://qiita.com/aaa_aki_develop/items/e662cb0833aa8f039ae5 "結局のところRecyclerViewのコールバックはどう書くのがベストなのよ？
")


### 画面のスクロールに合わせてヘッダーを可変させたいとき
[いろいろなCoordinatorLayoutパターン
](https://qiita.com/ymshun/items/190527ffff55356ffb9e "いろいろなCoordinatorLayoutパターン
")