Skip to main content

Posts

Generate Kotlin Docs using Dokka

Have you ever generated Kotlin docs (Kdocs) for your library/project? I have. There is a tool for this called Dokka and you can find it here. It's not too hard to set up.I personally used Dokka for a small API i wrote for SharedPreferences. Anyways, the steps are pretty basic. One thing you must be careful though, is to know the syntax of the Kdocs pretty well (usually, if you know how to generate Javadoc, Kotlin docs don't have much difference).Let's take a simple example:/** Reads a String from SharedPreferences * @param [key] the key provided to find the stored value * @return [String] the data of type String if found if not returns an empty String * @throws [java.lang.ClassCastException] if the key is found but is not a String */ @Throws(java.lang.ClassCastException::class) fun readString(key: String, defaultStringValue: String = ""): String = sharedPreferences.getString(key, defaultStringValue) ?: throw java.lang.ClassCastException("The key exists, but …

What I learned from Kotlin Flow API

I used to check the docs and just read a lot about flows but didn't implement anything until yesterday. However, the API tasted really cool (even though some operations are still in Experimental state).Prerequisites: If you don't know RxJava it's fine. But a RxJava recognizer would read this faster.Cold vs Hot streamsWell, I really struggled with this concept because it is a little bit tricky. The main difference between cold and hot happened to be pretty simple: Hot streams produce when you don't care while in cold streams, if you don't collect() (or RxJava-s equivalent subscribe()) the stream won't be activated at all. So, Flows are what we call cold streams. Removing the subscriber will not produce data at all, making the Flows one of the most sophisticated asynchronous stream API ever (in the JVM world). I tried to make a illustration of hot and cold streams: Since I mentioned the word asynchronous this implies that they do support coroutines also. Flows vs…

Searchable Fragments with the Paging Library

This post is inspired by @EpicPandaForce answer in StackOverflow. I faced the same problem which I didn't know how to solve: How to perform search when you are using a Paging Library (or how the hell to refresh after I reperform Rooms query)?Let's suppose we have this scenario: I have a list of data, which are shown in the Fragment by LiveData observation, which are retrieved by the ViewModel through LiveDataPagedListBuilder(). I'm hoping you know the basics of the Paging Library already.The data source:I'm retrieving the data using a local database and Paging Library's Datasource.Factory<Key, Value>:@Dao interface MyDao{ @RawQuery(observedEntities = [MyEntityRepresentation::class]) fun selectAllMeetingCondition(query: SupportSQLiteQuery): DataSource.Factory<Int , MyEntityRepresentation>: }Room queries at Runtime.My use case requires to generate a dynamic query each time the user performs a search. In other words, the query depends on the users …

Prepopulate Room with data.

There are times, when we just need the data when the app starts, and all the functionality is just a matter of work. Or we just need the app to be independent from the network and we have the data. A simple dog-race database or cat-race database doesn't actually need online interaction at all (if there are not too many data of course). So, Room comes with a nice solution about this. The docs are pretty clear and short when it comes to this topic.
We just write:

Room.databaseBuilder(appContext, AppDatabase.class, "Sample.db") .createFromAsset("database/myapp.db") .build() And our data are ready to be instantiated when the app starts. One more thing to note is that its extremely fast to do it this way. However, here are some problems that the docs don't even bother to mention (which I think are important for some).
1 - A .db file, is not a .sql file. The file we are supposed to hold in assets folder which contains a query like: CREATE TABLE IF NOT …

Fragments ❤ ViewPager2

The ViewPager2 is a pretty nice rework of the ViewPager API. Some new features you may find with the ViewPager2 are:

1- Vertical scrolling. You can simply enable it by adding: android:orientation="vertical" in the <ViewPager2> tag in your xml file.
2- Right to left support: you can set the android:layoutDirection="rtl" to enable this.
3- Support for DiffUtil, because it is based on RecyclerView.
4 - Fragments improved support, which we will talk about below.

So, let's suppose that we have 2 Fragments: HomeFragment and SchoolFragment. In the Activity/Fragment xml file, which is going to hold these two sliding by switching with each-other, place the ViewPager2 tag:

<androidx.viewpager2.widget.ViewPager2 xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/my_view_pager" android:layout_width="match_parent" android:layout_height="match_parent" >" Now, let's set up co…

Setting up Gradle with Kotlin DSL, a simple guide

Kotlin is a very a pretty nice adoptive language and user friendly. It really replaced Java from my everyday programming. However, it was not enough. We all know that groovy runs on JVM. So, why do I even need a new language just for my builds? Can't it be Java? So Java is the basic language for the JVM, Kotlin runs on JVM, Groovy runs on JVM and my build system has a separated language from my business logic system. Why?

I was introduced to Gradle with Kotlin accidentally. I never heard of Kotlin DSL in terms of Gradle. I just created a new Spring project and the built file looked kind of strange. After a little Google-ing, everything was clear. Long story short, I removed groovy from my Gradle build tool in my Android project, and replaced it with Kotlin. It shouldn't take more than 15 minutes to do this, but you can struggle with some things in particular.

Note: Kotlin DSL means Kotlin Domain Specific Language. It's just a notation, the name is self descriptive.

 Here a…

Conditional navigation and single event LiveData

Conditional navigation is a little tricky when it comes to Navigation Architecture. There are plenty of nice articles and solutions about it, but I'm sharing the way I solve this important problem. So let's consider this use case:


If you don't put HomeFragment as a start destination, you will have some serious trouble with the fragment back stack and you would need to write the onBackPressDispatcher in every fragment. Therefore, don't do it.

There is also an easier step to do this directly in the OnlyActivity you have, and it's pretty nice too, but I've noticed that Google suggest the activities to be kept just for holding <fragment>s and nothing more. Otherwise it would violate the responsibility that the new Architecture Activity behaviour has (like checking from its' ViewModel user authentication etc).

So it's just fragments. A common problem you might face is when you use LiveData<T> the usual way for this case. I'm not handling the…