Kotlin with Android: Base classes and Kotlin Android Extensions - android

So i have used Kotlin Android Extensions and i find it very easy to use and well worth it. No more findViewById or Butterknife.Bind(...). I have found no issue with it all all except for one situation.
In a base class, for example, BaseActivity, there's normally a bunch of views that will be present in all the layouts, for example, a toolbar. And common operations like changeToolbarColor(), or setToolbarTitle().
In this simple cases, i canno't use Kotlin Android Extensions because, as it is a base class, the view itself will be present on multiple layouts and tho can't be property imported. In this cases i just simply use by lazy {find<>(...).
Is there any way this can be accomplished with the build-in android extension plugin?

Kotlin Android Extensions generates an extension function for each element on a given layout. Since extension methods exist outside the inheritance model, there is no way to define a common protocol like abstract val toolbar:Toolbar on the parent.
However, under the hood the extension methods only execute findById, if the given ID exists on a layout it will fetch the element. This means that if you maintain the same ids for your common elements inside your layouts (i.e.: all toolbars with #id/toolbar), you can create a dummy layout with your common elements and their respective IDs. This layout will work as a sort of interface, allowing you to do import kotlinx.android.synthetic.main.base_activity_dummy.* and thus generating the extension methods you want.
By doing the above, the this.toolbar on your BaseActivity will fetch the actual item on your concrete activity instead of the element on the dummy layout.
Of course, this technique, while convenient, is error prone and could make your program very confusing for an outsider. But again, it won't be more error prone than calling findById everywhere.

Related

How to add functionality to existing classes?

Currently, I am developing an android library. Basically the idea is to add some functionality to any android widget that there is. The library is used to create compound views, and the user should be able to convert every existing android widget/view into a compound view with some additional functionality I want to add dynamically.
Every one of these views should still be useable inside XML files, which means I cannot change the constructor too much.
Another requirement is that I need an option for the user to provide some classes for the views. By that, I mean that the created compound view is going to have a public variable named viewStore. Thy type of viewStore would either be the user's implementation of the ViewStore interface (preferred way but I am pretty sure this would require code generation as discussed later) or would be provided via generics.
In the end, a compound view would have this folder structure like this:
MyView Folder
MyView extends CoolViewWithViewStore extends AndroidWidgetChoosenByUser
MyViewStore implements ViewStore <- used in CoolViewWithViewStore
One option is to extend every single widget. I don't think I need to explain why this is a bad idea. Furthermore the user couldn't provide the additional classes that are needed.
Another one I thought of was Annotation with code generation. The problem I came across here was that the user needs access to variables of CoolViewWithViewStore inside MyView which wouldn't be possible because CoolViewWithViewStore would be generated at compile-time and furthermore the user could accidentally use his class inside XML instead of our generated one.
I would like to hear if anybody has a better idea of how to handle this or if there even is a clean solution to this to achieve this kind of architecture. If anybody has a better idea of how to structure my library I would like to hear this as well.
Using Kotlin extension function you could extend a class with new functionality without having to inherit from the class.

Best approach for handling same layouts for different activities

I have been working on application which has 3 types of accounts related to it. We create a single layout and view/hide items on it depending on, from which account you are currently logged in.
With this approach, we have activities/fragments doing a lot of different things, they handle all cases wrapped in if/else checks etc. With growing project, it is becoming hard to maintain these classes.
Say, if I have to hide a view in certain scenario, I have to look around many if/else checks just to hide a single button because if I hide it on one place other check will make it visible again, really hard to maintain.
I am looking forward for best advises on this issue from the experts.
If you are struggling with a lot of if/else scattered in the code, maybe you should use polymorphism in your code.
Create an abstract class for the Activity, then specialize it for each particular type.
Use the Factory method pattern for creating objects of this hierarchy. This method will use the parameters for deciding which concrete class to instantiate, and then it will initialize the instance being returned.
Use the Template Method pattern if there is an algorithm common to all sub-classes but that contains some open steps that should be implemented by each class.
Use the State/Strategy pattern if you need polymorphic code that may be modified at runtime.
If your separate apps require minor customization and theme changes, but are really the same base app, multiple flavors is definitely the way to go. However, if both apps require a lot of custom code differences, you might want to rethink using multiple flavors strategy.
Also, take notice of the difference between flavors and build types. Use flavors for situations where you might need different versions of the same app in the Play Store, for example, free and pro, or for situations where you are customizing the same app for multiple clients.
for details http://www.androidauthority.com/building-multiple-flavors-android-app-706436
you have create new xml files in which has common view's for your activity and fragment then need to use include tag in xml for adding those common view's into your activities & fragments xml.
Create different xml for same layout and use <include layout="#"/>
Tag to create the layout, it will reduce if/else and also provide you the code re-usability
I think you should create separate layout for all 3 types of account and you can create PickLayout static class/method to pick the layout by type
int getLayout(int type){
return layoutMap.get(type);
}
if you have re-usable layout then you should use include, merge or you can use ViewStub also.
if you have chain of if/else then you should use Map link that will be scale-able, error-prone free.
And try to follow android suggested design-pattern that will be helpful for writing test case also.

When you use Android Studio are you working with MVC?

I know in Xcode when you write an app, you have controller, model, views.
android studio doesn't have a Controller specific. Do you think in android studio are working with MVC?
No but you can build it quite easily:
On Android, you always have these XML which represent the views (actually you can do all programatically but a better practice will invite you to use these XML because they're more flexible) and they're in the ressources. The problem comes when you do custom views because you need to put a bit of logic in that and then it is part of your java code.
Then the controller is, basically, the activity but the fragments contain also, theoretically a bit of logic so they're like hybrid between controller and view (I, personally, consider them as controller but my pair developer as a view).
Then the models are very easy to separate... At the end you can get something like this: (but I do not if you would call it MVC)
-java
|_model
|_user.java
|_view
|_customView.java (extends View for example)
|_controller
|_MainActivity.java
|_fragment_contained_in_main_activity_inflating_Custom_View.java
-res
|_layout
|_customView_layout.xml
Android the activity or fragment is the "controller". You write the controlling code in java and the views in XML. You can make model classes as .java files and when populating data from a server wrap those model classes in an Array or List to be used and placed onto your view via the activity code.

Benefits and limitations of different implementation approaches

I just started learning Android development and I read there was basically 3 main approaches to 'build a view' which are :
Java-based: Use Java to define Strings, lay out window, create GUI controls, and assign event handlers. Like Swing programming.
XML-based: Use XML files to define Strings, lay out window, create GUI controls, and assign event handlers. The Java method will read the
layout from XML file and pass it to setContentView
Hybrid: Use an XML file to define Strings, lay out window and create GUI controls. Use Java to assign event handlers
What are the benefits and limitations of these 3 different approaches ?
Which one should be rather used by a beginner or a confirmed programmer ?
I'm not asking for subjective answer here ( before being flagged :) ).
There must be some facts that make these approaches different from one another (speed, maintainability, readability...)
XML-based is like using CSS for a webpage. Using XML separates concerns neatly into the MVC (Model-View-Controller) pattern. If everything is specified in XML, then your activity can utilize different layout files for different screens, and the presentation of these elements can easily be updated by just changing to new XML files. This is good software development practice and greatly helps when it comes time to redesign or reuse components. In some cases you may still need to dynamically set some things in Java, but you should try to put all presentation-related stuff in the XML files.
The event handlers should still be set and defined in Java, in my opinion. That is not related to presentation and thus does not belong in the XML files. I do not use the onclick XML attributes. Also, if you set it in the onclick attribute, you can break the connection if you refactor the method name in Java but forget to update the XML file.
The advantage of using XML as much as possible is that all the Android tools provide support for this style of programming (UI editors, etc.). If you do everything in code, you're on your own. (Want to see the effect of a change to your code-based layout? Build your app and run it in the emulator. With an XML-based layout, you can preview it right in the XML editor where you are making the changes.)
Regarding event handlers, the main advantage of declaring them in XML (e.g., with an android:onClick property) is that you don't have to declare the event handler classes. The advantage here, though is not particularly strong, and I often use what you describe as a hybrid approach.
I'd advise beginning Android programmers (whether experienced with other programming or not) to gain a strong foundation in the XML style that Android pushes.

intercepting declarative XML UI values in android

I would prefer to do most UI layout and set view properties in XML but have run into times when I need to override these values in code before rendering the view.
I can continue to do this after the layout/viewgroup has been constructed from the processed XML files but am wondering if there is a better way.
I know which property values need to be overwritten before the UI is constructed. Is there an event / pipeline I can extent that would allow me to inject a new value for a property while it is being constructed by the system?
Not sure if this more efficient - just thinking about alternative solutions.
Thanks.
If such a pipeline exists (I don't think it does) it will probably not gain you more in terms of efficiency.
When you compile your application, each XML layout file is compiled into a View resource, which are loaded from your application code (mostly in the onCreate() method of Activity).
This basically means after compiling, there's no XML to be edited/injected.

Categories

Resources