It seems that simply using android:layout_height="wrap_content" on your RecyclerView won’t make its height automatically expand when new items are added in it.
Category: Dev Diary
-
Make a RecyclerView expand its height when new item is added //Android Dev Diary
-
How to start using view binding //Android Kotlin Dev Diary
First, open your
app/build.gradlefileInside the
android{}block ofapp/build.gradle, add the following:buildFeatures { viewBinding = true }Sync project with gradle files.
In your activity or fragment, define the following class-wide property:
private lateinit var binding: FragmentorActivityNameBinding
Replace the
FragmentorActivityNameBindingabove with the appropriate binding class name. Tip: The binding class name is based on the XML file’s name. For example, if your XML file name isactivity_main.xml, the binding class name should beActivityMainBinding. Or, if your file name isfragment_main.xml, the binding class name should beFragmentMainBinding.In your activity, the
onCreatefunction should look like this:override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivityMainBinding.inflate(layoutInflater) val view = binding.root setContentView(view) }Otherwise, if using view binding in a fragment, your
onCreateViewshould look like this:override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { binding = FragmentMainBinding.inflate(inflater, container, false) binding.lifecycleOwner = viewLifecycleOwner binding.viewModel = mainViewModel return binding.root } -
Disable animations programmatically during instrumented tests // Android Dev Diary
When running an instrumented Android test, or “androidTest”, and you encounter the following error:
androidx.test.espresso.PerformException: Error performing 'scroll to' on view 'Animations or transitions are enabled on the target device.It means that you need to disable animations for it to successfully run the test.
But, it can take a lot of clicks on the emulator/device screen to get to the developer settings to turn off animations!
So, for a quicker way to disable animations in the Android device during development, just enter the following commands in your Android Studio terminal:
adb shell settings put global window_animation_scale 0.0 adb shell settings put global transition_animation_scale 0.0 adb shell settings put global animator_duration_scale 0.0 -
Exception: No signature of method android() is applicable for argument types, Build Gradle // Dev Diary
Today I wanted to make a
data classa Parcelable so that I could pass it as an argument in Navigation component.Parcelables, though better in performance than Serializables, take more time to implement! To help us out, there’s a “kotlin-parcelize” plugin that can generate the boilerplate code for us.
There were issues though.
After applying the kotlin-parcelize plugin, I was getting the error:
'kotlin-parcelize' can't be applied together with 'kotlin-android-extensions'So kotlin-parcelize is like a “successor” to the now deprecated
'kotlin-android-extensions'that I’m still using. So I replaced'kotlin-android-extensions'with ‘kotlin-parcelize’.I got another error after attempting to sync with my Gradle files:
org.gradle.api.GradleScriptException: A problem occurred evaluating project ':app'[...]Caused by: groovy.lang.MissingMethodException: No signature of method: build_54gmhuqjm83le8li4fspjsxlu.android() is applicable for argument types: (build_54gmhuqjm83le8li4fspjsxlu$_run_closure1) values: [build_54gmhuqjm83le8li4fspjsxlu$_run_closure1@3c374eea] at build_54gmhuqjm83le8li4fspjsxlu.run([...]\app\build.gradle:11)The solution was to remove the following code from my
android{}block:androidExtensions { experimental = true }After removing that, Gradle synced successfull!
References:
Parcelable implementation generator
How to use @Parcelize now that kotlin-android-extensions is being deprecated? -
Two-way data binding with StateFlow & BindingAdapters //Dev Diary
I created BindingAdapters for an EditText like so:
@BindingAdapter("android:text") fun setText(editText: EditText, inputAmount: MutableStateFlow<Double>) { if (editText.text.toString() != inputAmount.value.toString()) { editText.setText(inputAmount.value.toString()) editText.setSelection(editText.text.length) } } @InverseBindingAdapter(attribute = "android:text") fun getText(editText: EditText): Double { if (editText.text.isEmpty()) return 0.0 return editText.text.toString().toDouble() }My XML layout element looks like this:
<com.google.android.material.textfield.TextInputEditText android:id="@+id/tiet_input_amount" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="@string/input_hint_amount" android:inputType="numberDecimal" android:text="@={viewModel._inputAmount}" />And in my ViewModel, the
inputAmountis set up this way:val _inputAmount: MutableStateFlow<Double> = MutableStateFlow(0.0) val inputAmount: StateFlow<Double> = _inputAmount -
Fix coroutine error: Cannot access database on the main thread // Android Dev Diary
As I was running a test for a ViewModel function, I encountered the following error:
[...] Main Thread @coroutine java.lang.IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time.I think it may be caused by the
viewModelScopefromviewModelScope.launch {}being used by the running test, which may not be accessible during unit tests.What I did to fix this error on my unit test was to enable main thread operations in my in-memory Room database test instance. I simply added
.allowMainThreadQueries()while building the database instance like so:db = Room.inMemoryDatabaseBuilder( context, MyRoomDatabase::class.java) .allowMainThreadQueries() .build()Is that the best way to do it? If you got a better suggestion, please comment! I’d love to hear about it.
-
Grant, revoke permissions via Android Studio Terminal (ADB Shell) // Android Dev Diary
To grant and revoke permissions via Terminal (ADB Shell), run your app on an emulator (I haven’t personally tried on a device but it should work there too).
Open your Terminal, and then enter the following command:
adb shellOnce you’re in, you may use the following syntax for granting or revoking your Android device’s permissions:
pm grant <package-name> <permission>For example, to grant a permission:
pm grant net.catzie.myapp android.permission.READ_EXTERNAL_STORAGEpm grant net.catzie.myapp android.permission.WRITE_EXTERNAL_STORAGEAnd to revoke a permission:
pm revoke net.catzie.myapp android.permission.READ_EXTERNAL_STORAGEpm revoke net.catzie.myapp android.permission.WRITE_EXTERNAL_STORAGENow there’s no need to open the settings screen on your device to play with your Android permissions!