2020年11月10日火曜日

ConstraintSet を使って Activity を再生成せずにレイアウトを切り替える

自分で縦横レイアウトを切り替えるので Manifest に設定を追加 <activity android:name=".MainActivity" android:configChanges="orientation|screenSize|screenLayout|keyboardHidden"> ... </activity> 縦画面用のレイアウトと、横画面用のレイアウトを用意する。
例としてここでは縦画面では上部に 16:9 で配置し、横画面では全画面に配置している。

縦画面用
res/layout/activity_main_port.xml <?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/constraintLayout" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <include android:id="@+id/container" layout="@layout/activity_main" android:layout_width="0dp" android:layout_height="0dp" app:layout_constraintDimensionRatio="16:9" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout> 横画面用
res/layout/activity_main_land.xml <?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/constraintLayout" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <include android:id="@+id/container" layout="@layout/activity_main" android:layout_width="0dp" android:layout_height="0dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout> activity_main_port.xml と activity_main_land.xml からそれぞれ ConstraintSet を構成する。
onConfigurationChanged() で画面の向きに応じて対応する ConstraintSet を ConstraintLayout に applyTo() する。 class MainActivity : AppCompatActivity() { private val constraintSetPort = ConstraintSet() private val constraintSetLand = ConstraintSet() private lateinit var constraintLayout: ConstraintLayout override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val layoutId = when (resources.configuration.orientation) { Configuration.ORIENTATION_LANDSCAPE -> R.layout.activity_main_land else -> R.layout.activity_main_port } setContentView(layoutId) constraintLayout = findViewById(R.id.constraintLayout) constraintSetPort.clone(this, R.layout.activity_main_port) constraintSetLand.clone(this, R.layout.activity_main_land) } override fun onConfigurationChanged(newConfig: Configuration) { super.onConfigurationChanged(newConfig) val constraintSet = when (newConfig.orientation) { Configuration.ORIENTATION_LANDSCAPE -> constraintSetLand else -> constraintSetPort } constraintSet.applyTo(constraintLayout) } }





2020年11月5日木曜日

Android 11 では ACTION_CREATE_DOCUMENT と ACTION_OPEN_DOCUMENT には <queries> 指定が必要

Intent.ACTION_CREATE_DOCUMENT および Intent.ACTION_OPEN_DOCUMENT を startActivityForResult() で呼び出す以下のコードは、targetSdkVersion が 29 (Android 10)までは問題なく動きます。 private fun createDocument() { val intent = Intent(Intent.ACTION_CREATE_DOCUMENT) .addCategory(Intent.CATEGORY_OPENABLE) .setType("*/*") .putExtra(Intent.EXTRA_TITLE, "log.txt") if (intent.resolveActivity(packageManager) != null) { startActivityForResult(intent, REQUEST_CODE_CREATE_DOCUMENT) } else { Toast.makeText( this, "Unable to resolve Intent.ACTION_CREATE_DOCUMENT", Toast.LENGTH_SHORT ) .show() } } private fun openDocument() { val intent = Intent(Intent.ACTION_OPEN_DOCUMENT) .addCategory(Intent.CATEGORY_OPENABLE) .setType("*/*") if (intent.resolveActivity(packageManager) != null) { startActivityForResult(intent, REQUEST_CODE_OPEN_DOCUMENT) } else { Toast.makeText( this, "Unable to resolve Intent.ACTION_OPEN_DOCUMENT", Toast.LENGTH_SHORT ) .show() } } しかし、targetSdkVersion を 30 (Android 11)にすると、intent.resolveActivity(packageManager) が null を返すようになってしまいます。

Android 11 では AndroidManifest.xml に以下の <queries> を指定すると動くようになります。 <manifest ...> ... <queries> <intent> <action android:name="android.intent.action.CREATE_DOCUMENT" /> <data android:mimeType="*/*" /> </intent> <intent> <action android:name="android.intent.action.OPEN_DOCUMENT" /> <data android:mimeType="*/*" /> </intent> </queries> ... </manifest>



2020年10月21日水曜日

DevFest 2020 で Material Design Components のカスタマイズについて話してきました。



資料はこちらです。



Android Studio 4.1 についてと、まとめの後のおまけにいくつかページを追加しています。
MDC をカスタマイズするときは便利だと思うので、是非参考にしてください。