15 Dec 2018
The Data Binding Library allows you to bind UI components in your layouts to data sources in your app using a declarative format rather than programmatically. In this codelab you’ll learn how to set it all up, use layout expressions, work with observable objects and create custom Binding Adapters to reduce boilerplate to a minimum.
Get Started
First thing we need to do is to enable the Data Binding library in yout project. So
modify your build.gradle
(app module context) and add the following code:
android {
...
dataBinding {
enabled true
}
}
Sync your project and now you are able to convert or create a layout to a Data Binding layout. You must wrap your layout with a <layout>
tag and optionally use the tags data
, variables
and expressions
. You can also automatically convert a regular layout to Data Binding using the Android Studio by right-clicking the parent layout tag and selecting “Convert data binding layout”.
Example of usage 1
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="viewmodel"
type="com.android.databinding.viewmodels.MyExampleViewModel"/>
<variable name="funds" type="Integer"/>
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
.....
</androidx.constraintlayout.widget.ConstraintLayout
</layout>
Layout variables are used to write layout expressions which are placed in the value of element attributes and they use the @{expression}
format. See the following example:
Example of usage 2
<ImageView
android:id="@+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="@{funds < 0 ? View.GONE : View.VISIBLE}"/>
Observing data
Instead of explicitly updating the UI when values changes, you can use [observables] to automatically updates the UI. In this way, another Architecture component of Android Jetpack library is recommended: LiveData.
Let’s discuss about only the observables and data binding works since this article is only explanning about Data Binding. When an observable value changes, the UI elements it’s bound to are updated automatically.
Use can freely interact with your data using DataBindingUtil
. See the following example and notice DataBinding will auto-generate a class for you. In the Example, the class generated was MainActivityBinding
because our original layout did not specify a name for the class so DataBinding simply used the name of the layout file and add word ‘Binding’ in the end:
main_activity.xml
-> MainActivity + Binding -> MainActivityBinding
Example of usage 3
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding : MainActivityBinding =
DataBindingUtil.setContentView(this, R.layout.main_activity)
binding.viewmodel = viewModel
}
More details
I recommend you to watch this amazing tutorial presented by Dan Galpin: Level up with Data Binding and simplify your Android coding
20 Nov 2018
According to Blockchain experts, Non-Fungible Tokens can revolutionize the future of blockchain. Do you really understand this concept and how can it be used? Let’s start talking about the basics and discussing what makes NFTs special and with a promising future.
Fungible Tokens and Non Fungible Tokens
Fungibility is important in the world of blockchain and cryptocurrency. It is desired for any currency, traditional or digital, since most currencies aim to be an interchangeable asset. A token can be exchanged for any other token of the same value. For example, One US dollar currency can be changed for another US dollar currency without any difference to the user.
On the other hand, Non-Fungible Token can’t be exchanged for any other NFT, because it has a unique and non-interchangeable behavior. These characteristics make them different from each other and digitally scarce. It is possible to create an analogy of NFTs with opera show tickets. Although the tickets are for the same show and everyone will listen to the same songs, each ticket has an identifier, buyer’s name and seat number. They are not easily transferable because each ticket has its value in a unique way.
In the Ethereum network, there are popular patterns that have been specified by the community itself. Each standard is known as ERC which stands for Ethereum Request for Comments. It defines methods, technology, behaviors for a particular functionality in Ethereum and it is submitted either for peer review.
ERC-1155
ERC-1155 is a standard for contracts that manage any combination of fungible tokens and non-fungible tokens.
Let’s talk about how the management works in every mentioned pattern in this article. Each ERC-20 token is required to be deployed in separate contracts. In case of ERC-721, this requires a single contract for managing a group of non-fungible tokens. However ERC-1155 works differently, it can handle any fungible and non-Fungible tokens in a single contract. This allows control of multiple tokens with different types in the same deployed contract.
As a result, the pattern avoids tons of repetitive code circulating the several contracts in the Ethereum ecosystem and saving significant storage space and gas costs.
What is special about ERC1155?
The new standard is a powerful tool that joins fungible tokens that have been widely accepted (list of ERC-20 tokens) to the non-fungible tokens that are popularizing themselves (list of NFT tokens).
In addition, the interface ERC-1155 provides ways to make transactions more efficient. The interface defines the function “safeBatchTransferFrom” to group multiple tokens and enable atomic swaps. In other words, the interface allows multiple complex operations in a single transaction. This procedure is quite simple and does not involve complex implementation.
Backwards Compatibility is another feature of the standard. It is compatible with ERC-721 and ERC-20 which can be inherited without any issue.
ERC-1155 allows smart contracts to reference other contracts’ storage whenever it necessary. In this way, it avoids duplicating of code or misuse of storage by smart contracts. As a result, it improves the efficiency of the Ethereum ecosystem.
26 Jul 2018
Continuous Integration
Continuous Integration aka CI is a development practice that requires developers to integrate code into a shared repository several times a day. Each check-in is then verified by an automated build, allowing teams to detect problems early. By integrating regularly, you can detect errors quickly, and locate them more easily and not integrating continuously you will have longer periods between integrations. This makes it exponentially more difficult to find and fix problems. Such integration problems can easily knock a project off-schedule, or cause it to fail altogether.
Travis CI
Using Travis CI, the users can easily sync Github projects and test the code test the code in minutes. Travis CI can be configured to run the tests on a range of different machines, with different software installed (such as older versions of a programming language implementation, to test for compatibility), and supports building software in numerous languages, including C, C++, C#, Clojure, D, Erlang, F#, Go, Apache Groovy, Haskell, Java, JavaScript, Julia, Perl, PHP, Python, R, Ruby, Rust, Scala and Visual Basic. Several high-profile open source projects are using it to run builds and tests on every commit, such as Plone, Ruby on Rails, and Ruby.[8][9
Truffle with Travis CI
Firstly, as prerequisite you should follow the Travis CI docs in order to integrate your Github project with Travis.
Then add the following chunk of code into your .travis.yml
:
In this script, we are selecting nodeJs version 8.11.3 with latest version of Node package manager (npm). Ganache (old testRPC) and truffle are also installed. The trigger mechanisms starts with ganache initialization and the truffle command truffle test
. In other words, the code will be compiled and the tests will ran too.
07 Jul 2018
As the official Firestore docs says, Firestore is a NoSQL document database built for automatic scaling, high performance, and ease of application development. While the Cloud Firestore interface has many of the same features as traditional databases, as a NoSQL database it differs from them in the way it describes relationships between data objects.
This Realtime Database (RTDB) is highly integrated with Firebase platform, including Google’s Cloud Functions serverless platforms. Besides Firestore was designed for making it easier for developers to build offline apps with the help of a local database for web, iOS and Android and to easily sync data between different apps and users in real time.
Features
Designed for scaling – Cloud Firestore delivers the best of the Google Cloud platform;
Offline Support – Write, read, examine, and query data, even if the file is offline;
Flexibility – Store your data in documents, organized into collections architectured in a flexible hierarchical data structures;
Expressive Queries – Use queries to retrieve documents and choose the documents in a collection corresponding to the query parameters;
Real-time updates – Data is synchronizated to update data on any connected party;
20 Jun 2018
Setup
buildscript {
// …
ext.kotlin_version = ‘'
dependencies {
classpath "org.jetbrains.kotlin" +
"kotlin-gradle-plugin:$kotlin_version"
} }
apply plugin: ‘kotlin’
dependencies {
compile “org.jetbrains.kotlin:kotlin-stdlib-jre8”
}
Utility Functions
Favor Kotlin top-level extension functions over the typical Java utility classes. And for easier consumption within Java code, use @file:JvmName to specify the name of the Java class which would get generated by the Kotlin compiler.
// Use this annotation so you can call it from Java code
@file:JvmName(“StringUtil”)
fun String.lengthIsEven(): Boolean = length % 2 == 0
val lengthIsEven = “someString”.lengthIsEven()
Data classes
They are classes that have the specific purpose of holding data:
data class Dog(val name: String, val age: Int)
The data class will have the following function out of the box:
toString of the form “Dog(name=Mark, age=12)” equals() and hashCode() copy()
It will also become a subject for destructuring declarations:
val markTurtle = Dog(“Joe”, 50)
val (name, age) = markTurtle
println(name)
Inline functions
A lambda expression in Kotlin is translated to Java anonymous classes in Java 6 or 7, that is an overhead. Lambda calls are affecting the call stack which has a performance impact.
inline functions can be used to flat out calls instead of invoking another method call and adding that to the call stack. So it makes sense to use inline functions when we pass in the lambdas.
inline fun callBlock(block: () -> Unit) {
println(“Before calling block”)
block()
println(“After calling block”)
}
When we call callBlock it gets translated to something like the following:
callBlock { println(“The block operation”) }
String var1 = “Before calling block”;
System.out.println(var1)
String var2 = “The block operation”;
System.out.println(var2);
var1 = “After calling block”;
System.out.println(var1);
vs. the following if the function was not marked as inline
callBlock { println(“The block operation”) }
callBlock((Functinos0)null.INSTANCE);
You have to be careful with inline functions though because it literary copies the method content where it is called and if the body of the functions is too large you really do not want to do this.
Knowing that, the following obviously will not make any sense because it has zero effect.
inline fun foo(noinline block: () -> Unit) {// Single lambda marked as noinline
inline fun foo() { // No lambdas
Checking for null in conditions
First, you can explicitly check if b is null, and handle the two options separately:
val l = if (b != null) b.length else -1
The compiler tracks the information about the check you performed, and allows the call to length inside the if. More complex conditions are supported as well:
if (b != null && b.length > 0)
print(“String of length ${b.length}”)
else
print(“Empty string”)
Note that this only works where b is immutable (i.e. a local variable which is not modified between the check and the usage or a member val which has a backing field and is not overridable), because otherwise it might happen that b changes to null after the check.
Safe Calls
Your second option is the safe call operator, written ?.:
b?.length
This returns b.length if b is not null, and null otherwise. The type of this expression is Int?.
Safe calls are useful in chains. For example, if Bob, an Employee, may be assigned to a Department (or not), that in turn may have another Employee as a department head, then to obtain the name of Bob’s department head, if any), we write the following:
bob?.department?.head?.name
Such a chain returns null if any of the properties in it is null.
Elvis Operator
When we have a nullable reference r, we can say “if r is not null, use it, otherwise use some non-null value x”:
val l: Int = if (b != null) b.length else -1
Along with the complete if-expression, this can be expressed with the Elvis operator, written ?::
val l = b?.length ?: -1
If the expression to the left of ?: is not null, the elvis operator returns it, otherwise it returns the expression to the right. Note that the right-hand side expression is evaluated only if the left-hand side is null.
Note that, since throw and return are expressions in Kotlin, they can also be used on the right hand side of the elvis operator. This can be very handy, for example, for checking function arguments:
fun foo(node: Node): String? {
val parent = node.getParent() ?: return null
val name = node.getName() ?: throw IllegalArgumentException(“name expected”)
}
The !! Operator
We can write b!!, and this will return a non-null value of b (e.g., a String in our example) or throw an NPE if b is null:
val l = b!!.length()
Thus, if you want an NPE, you can have it, but you have to ask for it explicitly, and it does not appear out of the blue.
Safe Casts
Regular casts may result into a ClassCastException if the object is not of the target type. Another option is to use safe casts that return null if the attempt was not successful:
val aInt: Int? = a as? Int