I've been exploring the concept of lambdas and how they provide a simpler syntax while implementing functional interfaces.
As per this article, if there is one method it's quite easy to implement the lambda. So,
interface OnClickListener {
public void onClick(View v);
}
Can be used like:
etDate.setOnClickListener(view -> Timber.i("the date is xyz"));
I've seen this work for interfaces with methods having different types of arguments as well, for example:
public interface Observer<T> {
void onSubscribe(Disposable d);
void onNext(T t);
void onError(Throwable e);
void onComplete();
}
Can be used as
api.getData()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(response -> {
Toast.makeText(this, "Result: " + response.toString(), Toast.LENGTH_LONG).show();
}, error -> {
Toast.makeText(this, "API returned an error: " + error.getLocalizedMessage(), Toast.LENGTH_LONG).show();
});
So I was able to use onNext followed by onError this way.
But take a look at the DrawerListener interface:
I'm not able to use this using RetroLambda. The IDE doesn't suggest me to change the code to lambda and neither am I able to use it as such. I have to write it like this...
drawer.addDrawerListener(new DrawerLayout.DrawerListener() {
@Override
public void onDrawerSlide(View drawerView, float slideOffset) {
// My action goes here
}
@Override
public void onDrawerOpened(View drawerView) {
}
@Override
public void onDrawerClosed(View drawerView) {
}
@Override
public void onDrawerStateChanged(int newState) {
}
});
...which isn't neat. I am hoping for a solution to write it like:
drawer.addDrawerListener(view, offset -> {
// My action goes here
});
Lambdas are suitable only when there is only 1 abstract method to implement. In case of DrawerListener, there are 4 methods which need to be implemented. That is the reason you cannot code it the way you wanted. If you are adamant on using lambdas , you can create an interface that extends DrawerListener and provide default implementations for the methods in that. For this minSDK version should be 24 and jack should be enabled.
interface CustomDrawerListener extends DrawerLayout.DrawerListener{
@Override
void onDrawerSlide(View drawerView, float slideOffset);
@Override
default public void onDrawerOpened(View drawerView) {
}
@Override
default public void onDrawerClosed(View drawerView) {
}
@Override
default public void onDrawerStateChanged(int newState) {
}
}
Then you can write add drawer listener as follows:
d1.addDrawerListener((CustomDrawerListener)(view,offset)->{
// My action goes here
});
build.gradle changes:
android {
defaultConfig {
minSdkVersion 24
//others
jackOptions {
enabled true
}
}
//other stuff
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}