mvp+dagger2
In this tutorial, we’ll be developing an application using MVP, Dagger2, Retrofit and RxJava.
在本教程中,我们将使用MVP , Dagger2 , Retrofit和RxJava开发应用程序。
These days cryptocurrency is the latest fad. So we’ll be creating a cryptocurrency application using the above things.
如今,加密货币是最新的时尚。 因此,我们将使用以上内容创建一个加密货币应用程序。
总览 (Overview)
To proceed further you must have an overview of the Model View Presenter, Dependency Injection, Retrofit and RxJava libraries.
We have covered them individually and in combination with the following tutorial links specified:
要进一步进行操作,您必须具有Model View Presenter,依赖注入,翻新和RxJava库的概述。
我们已经单独介绍了它们,并结合了以下指定的教程链接:
- Android MVP Android MVP
- Android Dagger2 Android Dagger2
- Android Retrofit Android改造
- Android RxJava Android RxJava
- Android Dagger2 + Retrofit Android Dagger2 +改装
- Android RxJava + Retrofit Android RxJava +改造
- MVP + Dagger2 MVP +匕首2
If you know the basics of the above things, the following example should be an easy ride. Let’s dive right in!
如果您了解上述内容的基础知识,那么下面的示例应该很容易。 让我们潜入吧!
Create a new Android Studio project.
创建一个新的Android Studio项目。
图书馆 (Libaries)
Add the following libraries in your app’s build.gradle
file.
RxAndroid is just like RxJava. It contains the schedulers and threads for the Android framework.
RxAndroid就像RxJava。 它包含Android框架的调度程序和线程。
项目结构 (Project Structure)
The di package contains the dependency injection – Dagger2 related files. The mvp package consists of the MVP related ones and so on.
di软件包包含依赖项注入– Dagger2相关文件。 mvp软件包包括与MVP相关的软件包,依此类推。
Where and how do we start?
It can get confusing when we are asked to use so many different things in our project.
我们从哪里开始,如何开始?
当要求我们在项目中使用这么多不同的东西时,这可能会造成混乱。
The beginning is always tricky. Once we know the process, everything becomes easy.
开始总是很棘手。 一旦我们知道了过程,一切就变得容易了。
So let’s list down our requirements and how we’ll approach them.
因此,让我们列出我们的要求以及我们将如何处理它们。
Our application would contain a single activity. It would host a RecyclerView to display the data from the API call. For the API call we’ll use Retrofit and RxJava.
我们的应用程序将包含一个活动。 它将托管一个RecyclerView来显示来自API调用的数据。 对于API调用,我们将使用Retrofit和RxJava。
- Create your activity and
recyclerview
xml layouts first. Lock the Design before you code. 首先创建您的活动并recyclerview
xml布局。 在编码之前,请锁定设计。 - Create the APIInterface.java class. It defines the API calls to be made. 创建APIInterface.java类。 它定义了要进行的API调用。
- Create the POJO data class which would parse the response from the API call. 创建POJO数据类,它将解析来自API调用的响应。
- Start by creating the Interface for the MVP – MainActivityContract.java. 首先为MVP创建接口– MainActivityContract.java。
- Create the di modules, components, scopes and qualifiers. 创建di模块,组件,作用域和限定符。
- Now create the PresenterImpl. 现在创建PresenterImpl。
- Finally, write the MainActivity and RecyclerViewAdapter classes plugging the Dependencies and the MVP pattern in. 最后,编写MainActivity和RecyclerViewAdapter类,将Dependencies和MVP模式插入其中。
布局代码 (Layout code)
activity_main.xml
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:app="https://schemas.android.com/apk/res-auto"
xmlns:tools="https://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<ProgressBar
android:id="@+id/progressBar"
style="?android:attr/progressBarStyleLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
recycler_view_list_row.xml
recycler_view_list_row.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:app="https://schemas.android.com/apk/res-auto"
android:id="@+id/constraintLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp">
<TextView
android:id="@+id/txtCoin"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toTopOf="@+id/txtCurrentPrice"
app:layout_constraintTop_toTopOf="parent"
/>
<TextView
android:id="@+id/txtCurrentPrice"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@+id/txtCoin"
/>
<TextView
android:id="@+id/txtOneHourChange"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent" />
<TextView
android:id="@+id/txtOneHour"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:text="1H"
app:layout_constraintEnd_toStartOf="@+id/txtOneHourChange"
app:layout_constraintTop_toTopOf="@+id/txtOneHourChange" />
<TextView
android:id="@+id/txt24HourChange"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/txtOneHourChange" />
<TextView
android:id="@+id/txt7Day"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:text="7D"
app:layout_constraintEnd_toStartOf="@+id/txt7DayChange"
app:layout_constraintTop_toTopOf="@+id/txt7DayChange" />
<TextView
android:id="@+id/txt24Hour"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:text="24H"
app:layout_constraintBottom_toTopOf="@+id/txt7DayChange"
app:layout_constraintEnd_toStartOf="@+id/txt24HourChange"
app:layout_constraintTop_toTopOf="@+id/txt24HourChange" />
<TextView
android:id="@+id/txt7DayChange"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/txt24HourChange" />
</android.support.constraint.ConstraintLayout>
APIInterface.java
APIInterface.java
package com.journaldev.mvpdagger2retroiftrxjava.retrofit;
import com.journaldev.mvpdagger2retroiftrxjava.pojo.CryptoData;
import java.util.List;
import retrofit2.http.GET;
import retrofit2.http.Query;
import rx.Observable;
public interface APIInterface {
@GET("ticker/?")
Observable<List<CryptoData>> getData(@Query("limit") String limit);
}
The base URL would be defined in our RetrofitModule.
We’re using this API.
基本URL将在我们的RetrofitModule中定义。
我们正在使用此 API。
CryptoData.java
CryptoData.java
package com.journaldev.mvpdagger2retroiftrxjava.pojo;
import com.google.gson.annotations.SerializedName;
public class CryptoData {
@SerializedName("id")
public String id;
@SerializedName("name")
public String name;
@SerializedName("symbol")
public String symbol;
@SerializedName("rank")
public String rank;
@SerializedName("price_usd")
public String priceUsd;
@SerializedName("price_btc")
public String priceBtc;
@SerializedName("24h_volume_usd")
public String _24hVolumeUsd;
@SerializedName("market_cap_usd")
public String marketCapUsd;
@SerializedName("available_supply")
public String availableSupply;
@SerializedName("total_supply")
public String totalSupply;
@SerializedName("percent_change_1h")
public String percentChange1h;
@SerializedName("percent_change_24h")
public String percentChange24h;
@SerializedName("percent_change_7d")
public String percentChange7d;
@SerializedName("last_updated")
public String lastUpdated;
}
MainActivityContract.java
This is the blueprint of our View-Model-Presenter:
MainActivityContract.java
这是我们的View-Model-Presenter的蓝图:
package com.journaldev.mvpdagger2retroiftrxjava.mvp;
import com.journaldev.mvpdagger2retroiftrxjava.pojo.CryptoData;
import java.util.List;
public interface MainActivityContract {
interface View {
void showData(List<CryptoData> data);
void showError(String message);
void showComplete();
void showProgress();
void hideProgress();
}
interface Presenter {
void loadData();
}
}
ActivityScope.java
ActivityScope.java
package com.journaldev.mvpdagger2retroiftrxjava.di.scopes;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import javax.inject.Scope;
@Scope
@Retention(RetentionPolicy.CLASS)
public @interface ActivityScope {
}
ApplicationScope.java
ApplicationScope.java
package com.journaldev.mvpdagger2retroiftrxjava.di.scopes;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import javax.inject.Scope;
@Scope
@Retention(RetentionPolicy.CLASS)
public @interface ApplicationScope {
}
ActivityContext.java
ActivityContext.java
package com.journaldev.mvpdagger2retroiftrxjava.di.qualifier;
import javax.inject.Qualifier;
@Qualifier
public @interface ActivityContext {
}
ApplicationContext.java
ApplicationContext.java
package com.journaldev.mvpdagger2retroiftrxjava.di.qualifier;
import javax.inject.Qualifier;
@Qualifier
public @interface ApplicationContext {
}
ContextModule.java
ContextModule.java
package com.journaldev.mvpdagger2retroiftrxjava.di.module;
import android.content.Context;
import com.journaldev.mvpdagger2retroiftrxjava.di.qualifier.ApplicationContext;
import com.journaldev.mvpdagger2retroiftrxjava.di.scopes.ApplicationScope;
import dagger.Module;
import dagger.Provides;
@Module
public class ContextModule {
private Context context;
public ContextModule(Context context) {
this.context = context;
}
@Provides
@ApplicationScope
@ApplicationContext
public Context provideContext() {
return context;
}
}
MainActivityContextModule.java
MainActivityContextModule.java
package com.journaldev.mvpdagger2retroiftrxjava.di.module;
import android.content.Context;
import com.journaldev.mvpdagger2retroiftrxjava.MainActivity;
import com.journaldev.mvpdagger2retroiftrxjava.di.qualifier.ActivityContext;
import com.journaldev.mvpdagger2retroiftrxjava.di.scopes.ActivityScope;
import dagger.Module;
import dagger.Provides;
@Module
public class MainActivityContextModule {
private MainActivity mainActivity;
public Context context;
public MainActivityContextModule(MainActivity mainActivity) {
this.mainActivity = mainActivity;
context = mainActivity;
}
@Provides
@ActivityScope
public MainActivity providesMainActivity() {
return mainActivity;
}
@Provides
@ActivityScope
@ActivityContext
public Context provideContext() {
return context;
}
}
RetrofitModule.java
RetrofitModule.java
package com.journaldev.mvpdagger2retroiftrxjava.di.module;
import com.journaldev.mvpdagger2retroiftrxjava.di.scopes.ApplicationScope;
import com.journaldev.mvpdagger2retroiftrxjava.retrofit.APIInterface;
import dagger.Module;
import dagger.Provides;
import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;
@Module
public class RetrofitModule {
@Provides
@ApplicationScope
APIInterface getApiInterface(Retrofit retroFit) {
return retroFit.create(APIInterface.class);
}
@Provides
@ApplicationScope
Retrofit getRetrofit(OkHttpClient okHttpClient) {
return new Retrofit.Builder()
.baseUrl("https://api.coinmarketcap.com/v1/")
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.client(okHttpClient)
.build();
}
@Provides
@ApplicationScope
OkHttpClient getOkHttpCleint(HttpLoggingInterceptor httpLoggingInterceptor) {
return new OkHttpClient.Builder()
.addInterceptor(httpLoggingInterceptor)
.build();
}
@Provides
@ApplicationScope
HttpLoggingInterceptor getHttpLoggingInterceptor() {
HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor();
httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
return httpLoggingInterceptor;
}
}
MainActivityMvpModule.java
MainActivityMvpModule.java
package com.journaldev.mvpdagger2retroiftrxjava.di.module;
import com.journaldev.mvpdagger2retroiftrxjava.di.scopes.ActivityScope;
import com.journaldev.mvpdagger2retroiftrxjava.mvp.MainActivityContract;
import dagger.Module;
import dagger.Provides;
@Module
public class MainActivityMvpModule {
private final MainActivityContract.View mView;
public MainActivityMvpModule(MainActivityContract.View mView) {
this.mView = mView;
}
@Provides
@ActivityScope
MainActivityContract.View provideView() {
return mView;
}
}
AdapterModule.java
AdapterModule.java
package com.journaldev.mvpdagger2retroiftrxjava.di.module;
import com.journaldev.mvpdagger2retroiftrxjava.MainActivity;
import com.journaldev.mvpdagger2retroiftrxjava.RecyclerViewAdapter;
import com.journaldev.mvpdagger2retroiftrxjava.di.scopes.ActivityScope;
import dagger.Module;
import dagger.Provides;
@Module(includes = {MainActivityContextModule.class})
public class AdapterModule {
@Provides
@ActivityScope
public RecyclerViewAdapter getCoinList(RecyclerViewAdapter.ClickListener clickListener) {
return new RecyclerViewAdapter(clickListener);
}
@Provides
@ActivityScope
public RecyclerViewAdapter.ClickListener getClickListener(MainActivity mainActivity) {
return mainActivity;
}
}
Components are what inject the dependencies from the Modules.
组件是注入来自模块的依赖关系的组件。
ApplicationComponent.java
ApplicationComponent.java
package com.journaldev.mvpdagger2retroiftrxjava.di.component;
import android.content.Context;
import com.journaldev.mvpdagger2retroiftrxjava.MyApplication;
import com.journaldev.mvpdagger2retroiftrxjava.di.module.ContextModule;
import com.journaldev.mvpdagger2retroiftrxjava.di.module.RetrofitModule;
import com.journaldev.mvpdagger2retroiftrxjava.di.qualifier.ApplicationContext;
import com.journaldev.mvpdagger2retroiftrxjava.di.scopes.ApplicationScope;
import com.journaldev.mvpdagger2retroiftrxjava.retrofit.APIInterface;
import dagger.Component;
@ApplicationScope
@Component(modules = {ContextModule.class, RetrofitModule.class})
public interface ApplicationComponent {
APIInterface getApiInterface();
@ApplicationContext
Context getContext();
void injectApplication(MyApplication myApplication);
}
MainActivityComponent.java
MainActivityComponent.java
package com.journaldev.mvpdagger2retroiftrxjava.di.component;
import android.content.Context;
import com.journaldev.mvpdagger2retroiftrxjava.MainActivity;
import com.journaldev.mvpdagger2retroiftrxjava.di.module.AdapterModule;
import com.journaldev.mvpdagger2retroiftrxjava.di.module.MainActivityMvpModule;
import com.journaldev.mvpdagger2retroiftrxjava.di.qualifier.ActivityContext;
import com.journaldev.mvpdagger2retroiftrxjava.di.scopes.ActivityScope;
import dagger.Component;
@ActivityScope
@Component(modules = {AdapterModule.class, MainActivityMvpModule.class}, dependencies = ApplicationComponent.class)
public interface MainActivityComponent {
@ActivityContext
Context getContext();
void injectMainActivity(MainActivity mainActivity);
}
PresenterImpl.java
PresenterImpl.java
package com.journaldev.mvpdagger2retroiftrxjava.mvp;
import com.journaldev.mvpdagger2retroiftrxjava.pojo.CryptoData;
import com.journaldev.mvpdagger2retroiftrxjava.retrofit.APIInterface;
import java.util.List;
import javax.inject.Inject;
import rx.Observer;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;
public class PresenterImpl implements MainActivityContract.Presenter {
APIInterface apiInterface;
MainActivityContract.View mView;
@Inject
public PresenterImpl(APIInterface apiInterface, MainActivityContract.View mView) {
this.apiInterface = apiInterface;
this.mView = mView;
}
@Override
public void loadData() {
mView.showProgress();
apiInterface.getData("10").subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<List<CryptoData>>() {
@Override
public void onCompleted() {
mView.showComplete();
mView.hideProgress();
}
@Override
public void onError(Throwable e) {
mView.showError("Error occurred");
mView.hideProgress();
}
@Override
public void onNext(List<CryptoData> data) {
mView.showData(data);
}
});
}
}
@Inject
on the constructor says that this class’s object would be injected in the MainActivity.
The Presenter invokes the required View interface’s methods that’ll trigger the actions in the MainActivity.
构造函数上的@Inject
表示此类的对象将被注入MainActivity中。
Presenter调用所需的View接口的方法,这些方法将触发MainActivity中的操作。
MyApplication.java
MyApplication.java
package com.journaldev.mvpdagger2retroiftrxjava;
import android.app.Activity;
import android.app.Application;
import com.journaldev.mvpdagger2retroiftrxjava.di.component.ApplicationComponent;
import com.journaldev.mvpdagger2retroiftrxjava.di.component.DaggerApplicationComponent;
import com.journaldev.mvpdagger2retroiftrxjava.di.module.ContextModule;
public class MyApplication extends Application {
ApplicationComponent applicationComponent;
@Override
public void onCreate() {
super.onCreate();
applicationComponent = DaggerApplicationComponent.builder().contextModule(new ContextModule(this)).build();
applicationComponent.injectApplication(this);
}
public static MyApplication get(Activity activity){
return (MyApplication) activity.getApplication();
}
public ApplicationComponent getApplicationComponent() {
return applicationComponent;
}
}
MainActivity.java
MainActivity.java
package com.journaldev.mvpdagger2retroiftrxjava;
import android.content.Context;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.Toast;
import com.journaldev.mvpdagger2retroiftrxjava.di.component.ApplicationComponent;
import com.journaldev.mvpdagger2retroiftrxjava.di.component.DaggerMainActivityComponent;
import com.journaldev.mvpdagger2retroiftrxjava.di.component.MainActivityComponent;
import com.journaldev.mvpdagger2retroiftrxjava.di.module.MainActivityContextModule;
import com.journaldev.mvpdagger2retroiftrxjava.di.module.MainActivityMvpModule;
import com.journaldev.mvpdagger2retroiftrxjava.di.qualifier.ActivityContext;
import com.journaldev.mvpdagger2retroiftrxjava.di.qualifier.ApplicationContext;
import com.journaldev.mvpdagger2retroiftrxjava.mvp.MainActivityContract;
import com.journaldev.mvpdagger2retroiftrxjava.mvp.PresenterImpl;
import com.journaldev.mvpdagger2retroiftrxjava.pojo.CryptoData;
import java.util.List;
import javax.inject.Inject;
public class MainActivity extends AppCompatActivity implements MainActivityContract.View, RecyclerViewAdapter.ClickListener {
private RecyclerView recyclerView;
private ProgressBar progressBar;
MainActivityComponent mainActivityComponent;
@Inject
public RecyclerViewAdapter recyclerViewAdapter;
@Inject
@ApplicationContext
public Context mContext;
@Inject
@ActivityContext
public Context activityContext;
@Inject
PresenterImpl presenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ApplicationComponent applicationComponent = MyApplication.get(this).getApplicationComponent();
mainActivityComponent = DaggerMainActivityComponent.builder()
.mainActivityContextModule(new MainActivityContextModule(this))
.mainActivityMvpModule(new MainActivityMvpModule(this))
.applicationComponent(applicationComponent)
.build();
mainActivityComponent.injectMainActivity(this);
recyclerView = findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(activityContext));
recyclerView.setAdapter(recyclerViewAdapter);
progressBar = findViewById(R.id.progressBar);
presenter.loadData();
}
@Override
public void launchIntent(String name) {
Toast.makeText(mContext, name, Toast.LENGTH_SHORT).show();
// startActivity(new Intent(activityContext, DetailActivity.class).putExtra("name", name));
}
@Override
public void showData(List<CryptoData> data) {
recyclerViewAdapter.setData(data);
}
@Override
public void showError(String message) {
Toast.makeText(mContext, message, Toast.LENGTH_SHORT).show();
}
@Override
public void showComplete() {
}
@Override
public void showProgress() {
progressBar.setVisibility(View.VISIBLE);
}
@Override
public void hideProgress() {
progressBar.setVisibility(View.GONE);
}
}
Thanks to DI and MVP, we’ve injected everything and separated the network calls from the MainActivity.
The MainActivity.java only populates the views as per the instructions from the Presenter.
感谢DI和MVP,我们注入了所有内容,并将网络调用与MainActivity分开。
MainActivity.java仅按照Presenter中的说明填充视图。
The code for the RecyclerViewAdapter.java class is given below:
下面给出了RecyclerViewAdapter.java类的代码:
package com.journaldev.mvpdagger2retroiftrxjava;
import android.support.constraint.ConstraintLayout;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.journaldev.mvpdagger2retroiftrxjava.pojo.CryptoData;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> {
private List<CryptoData> data;
private RecyclerViewAdapter.ClickListener clickListener;
@Inject
public RecyclerViewAdapter(ClickListener clickListener) {
this.clickListener = clickListener;
data = new ArrayList<>();
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new ViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_view_list_row, parent, false));
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.txtCoin.setText(data.get(position).symbol);
holder.txtCurrentPrice.setText(data.get(position).priceUsd);
holder.txt1HourChange.setText(data.get(position).percentChange1h + "%");
holder.txt24HourChange.setText(data.get(position).percentChange24h + "%");
holder.txt7DayChange.setText(data.get(position).percentChange7d + "%");
}
@Override
public int getItemCount() {
return data.size();
}
class ViewHolder extends RecyclerView.ViewHolder {
private TextView txtCoin;
private TextView txtCurrentPrice;
private TextView txt1HourChange;
private TextView txt24HourChange;
private TextView txt7DayChange;
private ConstraintLayout constraintLayoutContainer;
ViewHolder(View itemView) {
super(itemView);
txtCoin = itemView.findViewById(R.id.txtCoin);
txtCurrentPrice = itemView.findViewById(R.id.txtCurrentPrice);
txt1HourChange = itemView.findViewById(R.id.txtOneHourChange);
txt24HourChange = itemView.findViewById(R.id.txt24HourChange);
txt7DayChange = itemView.findViewById(R.id.txt7DayChange);
constraintLayoutContainer = itemView.findViewById(R.id.constraintLayout);
constraintLayoutContainer.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
clickListener.launchIntent(data.get(getAdapterPosition()).name);
}
});
}
}
public interface ClickListener {
void launchIntent(String name);
}
public void setData(List<CryptoData> data) {
this.data.addAll(data);
notifyDataSetChanged();
}
}
REBUILD the Project to create the Dagger files automatically.
重建项目以自动创建Dagger文件。
The output of the above application in action is given below:
This brings an end to this hands-on tutorial in which we’ve used MVP, Dagger2, Retrofit, RxJava along with a RecyclerView. You can download the project from the link below.
这结束了本动手教程,在该教程中,我们将MVP,Dagger2,Retrofit,RxJava和RecyclerView一起使用。 您可以从下面的链接下载项目。
翻译自: https://www.journaldev.com/20654/android-mvp-dagger2-retrofit-rxjava
mvp+dagger2