I am using MVVM android architecture for my application.
I want to implement click event, so, do we need to use data binding architecture components or we can just use activity for handling the click event and validating the user inputs?
What's the best way to implement this?
Well the question would be using the Databinding or not. Here are some pros and cons of Databinding:
Pros:
Makes the code super clean.
Makes the code shorter.
Easy to test.
Cons:
Sometimes it's hard to debug.
It's a little heavy and increases the compile time.
But... since Google has already anounced it as part of the Android Architecture components I believe you should use it.
What's the best way to implement this?
I don't know how familiar you are with the Databinding but you should know something about Binding Adapters, anw in the onClick you won't be needing it. Just add the android:onClick attribute in the XML file. Also you can find this Codelab to properly implement it:
https://codelabs.developers.google.com/codelabs/android-databinding/#0
Example:
First of all make sure you have the Databinding enabled in your build.gradle
android {
...
dataBinding {
enabled true
}
}
After that go to the layout you will use the databinding (and for that make sure it will be an Activity/Fragment), and just type ALT+ TAB in your IDE and than....
After that, define types, for example a ViewModel and it's name. And in the view that will use the click function add what I said above. (android:onClick="#{() -> viewmodel.onLike()}")
You are not finished. You will somehow need to connect your logic to that databinding, so go to your Java/Kotlin code for your Activity/Fragment and:
Replace the setContentView(R.layout.some_activity) with val binding : SomeActivityBinding =
DataBindingUtil.setContentView(this, R.layout.some_activity)
Notice the SomeActivityBinding will be provided by the IDE itself because is handled on the Databinding library according to the xml naming.
That's the most basic. Good luck.
Related
I'm new to android studio and I'm leaning it from this video
At 50:45 he says that we can directly use the id without findViewById (), for him it shows just import that Id, but when I tried the same I'm not getting what he is getting. Can anyone tell me what's wrong, is that feature removed in the latest update??
"kotlinx.android.synthetic is no longer a recommended practice. Removing in favour of explicit findViewById"
So, this feature`s been deprecated almost a year ago.
The new recommended way of working with view tree is View Binding.
Or you could write some lazy extension function that uses findViewById under the hood.
You can use the Kotlin Android Extensions check here or with the help of data binding or view binding you can just use the id directly in to your java activity class
The way you're talking about is Kotline Extensions for view, for which you apply it in the build.gradle file using apply plugin: 'kotlin-android-extensions', sync the project as prompted by the Android studio and it starts working.
But, Kotlin extensions has also been deprecated for view binding which is null-safe, also easy to implement and better.
To read about view binding, read the Android documentation on ViewBinding here and about migrating here. You can also go with this article to help with setting up Android view binding.
In kotlin to access an element in the layout you do not need to do:
val k = findViewById(R......)
The element should be automatically imported into the kotlin file that connected to the view F.E if you have a text element in your main activity, in kotlin you access it by using it's id directly in the file that inflates that view and the import should be added automatically like this.
import kotlinx.android.synthetic.main.activity_main.view.*
However in few recent projects I noticed that this does not happen automatically.
You are correct, the Kotlin synthetics have quite a lot of similarities to the View Binding feature. The main advantage view binding has is that it's a bit harder to use the wrong binding class (with synthetics, you could quite easily import the wrong synthetics class if you have views in multiple layouts with the same ID).
I believe it's deprecated for a number of reasons, namely the type safety issue and the fact that it doesn't work with Java.
I've wrote a short tutorial on view binding here.
After some digging I found that Kotlin Android Extensions is now deprecated. Here is the guide to use the new method.
https://developer.android.com/topic/libraries/view-binding
Another option is to add the plugin in the app.gradle file.
plugins {
...
id 'kotlin-android-extensions'
}
After doing this two questions comes to mind:
Why did they remove the imports?
isn't the method that they demonstrated just doing the exact same thing as in it's importing the whole view?
I'm writing an Android application in Kotlin.
I also use the Anko view library to replace xml with programmatic view creations.
I'd like to write specs for my views (which are AnkoComponents).
Is there an accepted methodology for doing this?
I can't seem to find any information on specs + anko by googling or looking at the Anko docs.
Specifically, I'd like to test the createView(ui : AnkoContext<T>) method.
More specifically (and what I'm hoping will be answered by asking this question), is how do I mock out an AnkoContext<T> which I can pass to createView in my test?
Where to see a list of all attributes of all view types in Android?
I got an impression, that ImageButton does not have enabled and pressed attributes. At least, they didn't work when I set them in XML. Also I found a lot of "guides" on how to make these button either disabled and/or pressed.
Simultaneously, when I bound them with data binding
<ImageButton
android:id="#+id/locate_button"
android:layout_width="64dp"
android:layout_height="64dp"
android:layout_toRightOf="#id/bookmark_button"
android:enabled="#{activity.locateEnabled}"
android:pressed="#{activity.locatePressed}"
android:onClick="#{activity.onLocateClick}"
android:src="#drawable/locate_selector"
android:background="#null"
/>
they just worked. Both pressed and enabled. At the same moment pressed is even reported as unknown property by Android Studion spell checked!
So, what is it?
1) by-design behaviour and I just don't understand something (what?)
2) sugar from data binding library
3) hacking
4) ????
How to know, how poratble is this feature?
The answer is both 1 and 2. Data binding will allow you use an attribute to call any setter on a View. You can look at the data binding guide's section on attribute setters.
When you set the android:enabled attribute, you are using Android data binding's the automatic setters to calls setEnabled(). Android data binding sees the attribute name (enabled) and looks for a setter with that name and finds setEnabled(). The same is true for android:pressed -- there is a setPressed() method. Yay for convention!
android:onClick is a real attribute, but data binding doesn't use it. There is no setOnClick() method, either. Instead, there is a Binding Adapter that sets an OnClickListener to call your onLocateClick() method. There is a bit of magic involved in this that relies on the Annotation Processor that data binding uses to examine your code, but suffice it to say that it does this at compile time instead of using runtime reflection.
All event listeners should have Binding Adapters written for them with the same name as the event (as opposed to the listener name). So, you can also set android:onLongClick, for example. You may also be interested in the lambda syntax for events.
I'm not sure what you mean by "portable." Data Binding is usable at least back to Gingerbread (we claim Froyo, but really, who targets Froyo?), but you won't be able to transfer it to iOS or anything like that. All of Android data binding is done with a small runtime library and generated code. You don't have to worry about specific versions of Android.
I use eclipse for android development, and I find it very annoying that every time I create an activity or add new views to my activity, I need to create the references to views in my layout. I am looking for some kind of eclipse plugin that can generate the calls to findViewById() from the layout. I couldn't really find anything because I didn't know what it would be named. It would be very useful and time saving if that kind of plugin existed.
EDIT: The answers you gave are great. Can these tools also add more references to an existing activity so I don't have to manually do that when I add a view to the layout?
You can use https://github.com/JakeWharton/butterknife library for View Injections.
You can also get eclipse plugin https://marketplace.eclipse.org/content/lazy-android for the same.
But the ButterKnife library is frequently being contributed by android devs than the mentioned eclipse plugin. With this library, you can also avoid instantiating listeners yourself by just using like,
#OnClick(R.id.submit) void submit() {
// TODO call server...
}
For View injections, simply,
#InjectView(R.id.user) EditText username;
#InjectView(R.id.pass) EditText password;
So, it will compile as,
username = (EditText) findViewById(R.id.user);
password = (EditText) findViewById(R.id.pass);
Try the morcinek code generator. Its really simple to use.
This are the steps to install the plugin:
http://tmorcinek.wordpress.com/2011/11/30/eclipse-plugin-for-automatic-generation-of-activity-code-from-xml-layout-file/
After install process you may want to configurate a package to get the classes built by the generator, on the IDE -> Window -> Preferences on Bookmark Android Code Generator you can change that parameter.
The plugin does need a better interface for custom activities, still you could get the code, its really simple to make the changes you need, at least the inline listeners.
This solution doesnt work to modify classes you already have, that would be a really good improvement... i'll give it a try in a couple days with more time.