Search code examples
androidkotlinextension-methodsandroid-ktx

Can we create custom Synthetic Kotlin Extensions in Android?


I'm interested in the Kotlin Synthetic Extensions for Android, and thought if we can do the same for custom files, like raw XML files that we keep in the project. For example, let's consider the synthetic views in Kotlin.

import kotlinx.android.synthetic.main.fragment_profile_management.*

textview_shop_name.text = merchant.establishmentName

The code that gets generated is this:

TextView textView = (TextView) _$_findCachedViewById(com.goharsha.testapp.R.id.textview_shop_name);
Intrinsics.checkExpressionValueIsNotNull(textView, "textview_shop_name");
Merchant merchant3 = this.merchant;

if (merchant3 == null) {
    Intrinsics.throwUninitializedPropertyAccessException("merchant");
}

textView.setText(merchant3.getEstablishmentName());

And the _$_findCachedViewById method is also being generated into the same class as follows:

private HashMap _$_findViewCache;

public View _$_findCachedViewById(int i) {
    if (this._$_findViewCache == null) {
        this._$_findViewCache = new HashMap();
    }

    View view = (View) this._$_findViewCache.get(Integer.valueOf(i));

    if (view != null) {
        return view;
    }

    View view2 = getView();

    if (view2 == null) {
        return null;
    }

    View findViewById = view2.findViewById(i);
    this._$_findViewCache.put(Integer.valueOf(i), findViewById);

    return findViewById;
}

Since this is specific to Android, I guessed this could be done in Kotlin and maybe I can extend this for custom raw XML files, like config files for example and have them parsed into an object might be interesting.

However, I couldn't find how can this be done. I knew of extension functions in Kotlin, but here, a whole file is synthetically generated based on the imports. There is also this magic that this Kotlin import was not found when I decompiled the app.

I also tried looking at the core-ktx and view-ktx libraries, but no luck so far. Any idea how this can be done?


Solution

  • Yes, it is possible to do this and you need to do three things in order to get this done.

    1. Write a Gradle plugin
    2. Write a Kotlin compiler plugin (the API is undocumented, so get ready for a real challenge)
    3. Write an IntelliJ plugin (for features like go-to on a synthetic field to navigate to the XML file)

    These synthetic view generations are done in this route. Here are some resources if you want to try making something like this.