📜 ⬆️ ⬇️

Tutorial on creating a tracker cryptocurrency for android on Kotlin

image

Not long ago, there was an article in Habré in which it was proposed to make 8 educational projects . I liked the cryptocurrency tracker there, so that it was at least somehow more interesting than just a Get request, it was decided to make it to Kotlin. So, in this tutorial you will learn the following:


Introduction


Let’s miss how to include Kotlin’s support and other obvious and understandable things, such as creating a project. We will use this api

Manifest setting


In order to make requests you need to have permission to use the network:
')
<uses-permission android:name="android.permission.INTERNET"/> 

Adding Libraries to Gradle


We will need Retrofit and RxAndroid.

  //Retrofit compile "com.squareup.retrofit2:retrofit:2.3.0" compile "com.squareup.retrofit2:adapter-rxjava2:2.3.0" compile "com.squareup.retrofit2:converter-gson:2.3.0" //RxAndroid compile "io.reactivex.rxjava2:rxandroid:2.0.1" 

Create layouts


activity_main.xml
 <?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.kram.vlad.cryptocurrency.activitys.MainActivity"> <android.support.v7.widget.RecyclerView android:id="@+id/recyclerView" android:layout_width="match_parent" android:layout_height="match_parent"/> </android.support.constraint.ConstraintLayout> 


RecyclerView needs to know what its elements look like. For this we need to create item.xml.

item.xml
 <?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="wrap_content"> <android.support.v7.widget.CardView android:layout_width="match_parent" android:layout_height="wrap_content"> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView android:id="@+id/imageView" android:layout_width="wrap_content" android:layout_height="wrap_content" app:srcCompat="@drawable/ic_launcher_background"/> <TextView android:id="@+id/symbol" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_marginStart="11dp" android:layout_marginTop="11dp" android:layout_toEndOf="@+id/imageView" android:text="TextView" android:textColor="@android:color/black" android:textSize="18sp" android:textStyle="bold"/> <TextView android:id="@+id/textView2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBottom="@+id/symbol" android:layout_marginStart="11dp" android:layout_toEndOf="@+id/symbol" android:text="|" android:textColor="@android:color/black" android:textSize="18sp"/> <TextView android:id="@+id/name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBottom="@+id/textView2" android:layout_marginStart="12dp" android:layout_toEndOf="@+id/textView2" android:text="TextView" android:textColor="@android:color/black" android:textSize="14sp"/> <TextView android:id="@+id/money" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBottom="@+id/name" android:layout_alignParentEnd="true" android:layout_marginEnd="13dp" android:text="TextView" android:textColor="@android:color/black" android:textSize="14sp" android:textStyle="bold"/> <TextView android:id="@+id/textView6" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBottom="@+id/imageView" android:layout_marginBottom="10dp" android:layout_marginLeft="20dp" android:layout_toEndOf="@+id/imageView" android:text="24h:"/> <TextView android:id="@+id/textView7" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBaseline="@+id/textView6" android:layout_alignBottom="@+id/textView6" android:layout_alignEnd="@+id/name" android:text="7d:"/> <TextView android:id="@+id/hours" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBaseline="@+id/textView6" android:layout_alignBottom="@+id/textView6" android:layout_toEndOf="@+id/textView6" android:text="-2.94%" android:textStyle="bold"/> <TextView android:id="@+id/days" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBottom="@+id/textView7" android:layout_toEndOf="@+id/textView7" android:text="+10.19%" android:textStyle="bold"/> </RelativeLayout> </android.support.v7.widget.CardView> </android.support.constraint.ConstraintLayout> 


Make a model for parsing the answer.


For such purposes, any pojo generator would work well.

ResponseItrem
 data class ResponseItem(@SerializedName("id") @Expose var id: String?, @SerializedName("name") @Expose var name: String?, @SerializedName("symbol") @Expose var symbol: String?, @SerializedName("rank") @Expose var rank: String?, @SerializedName("price_usd") @Expose var priceUsd: String?, @SerializedName("price_btc") @Expose var priceBtc: String?, @SerializedName("24h_volume_usd") @Expose var _24hVolumeUsd: String?, @SerializedName("market_cap_usd") @Expose var marketCapUsd: String?, @SerializedName("available_supply") @Expose var availableSupply: String?, @SerializedName("total_supply") @Expose var totalSupply: String?, @SerializedName("max_supply") @Expose var maxSupply: String?, @SerializedName("percent_change_1h") @Expose var percentChange1h: String?, @SerializedName("percent_change_24h") @Expose var percentChange24h: String?, @SerializedName("percent_change_7d") @Expose var percentChange7d: String?, @SerializedName("last_updated") @Expose var lastUpdated: String?) { 


Create a simple get request


We will use Rx so our Get function must return Observable. Also right here we create a Factory, from it we will receive a Retrofit object.

Getinterface
 interface RetrofitGetInterface { @GET("v1/ticker/") fun getCryptocurrency(): Observable<List<ResponseItem>> companion object Factory { fun create(): RetrofitGetInterface { val retrofit = Retrofit.Builder() .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .addConverterFactory(GsonConverterFactory.create()) //    .baseUrl("https://api.coinmarketcap.com/") //    .build() return retrofit.create(RetrofitGetInterface::class.java) } } } 


Make a request


For queries we will use Rx. If you are not familiar with reactive programming, you do not know what you are losing.

Request Code
 val apiService = RetrofitGetInterface.create() apiService.getCryptocurrency() .observeOn(AndroidSchedulers.mainThread())//      .subscribeOn(Schedulers.io()) //  io -       .subscribe({ result -> arrayListInit(result) //     }, { error -> error.printStackTrace() }) 


Making an adapter for the list


 class RecyclerViewAdapter(private val result: List<ResponseItem>, val resources: Resources):RecyclerView.Adapter<RecyclerViewAdapter.CardViewHolder>() 

The data that we received from our query needs to be thrown into some array (List) ResponseItem. It must be transferred to the adapter so that it fills our list.

In GetItemCount, we must return the size of the array in order for the adapter to know how many items will be on our list.

 override fun getItemCount() = result.size //    

In OnCreateViewHolder we have to inflate the layout of our item.

 override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): CardViewHolder { return CardViewHolder(LayoutInflater.from(parent?.context) .inflate(R.layout.item, parent, false)) // RecyclerView    item } 

All the time in the code some CardViewHolder is lit. It must fill the views of each item with data from the array.

  class CardViewHolder(itemView: View?) : RecyclerView.ViewHolder(itemView) { fun bind(result: List<ResponseItem>, position: Int, resources: Resources) { val responseItem: ResponseItem = result.get(position) itemView.symbol.text = responseItem.symbol itemView.name.text = responseItem.name ... } } 

The bind function takes all the necessary data and fills the view with it. We call this function in onBindViewHolder. And thanks to the syntax of the language we do it quite nicely.

 override fun onBindViewHolder(holder: CardViewHolder, position: Int) = holder.bind(result, position, resources) 

Last step: attach our adapter


To do this, you just need to register in Kalbeke:

 recyclerView.adapter = RecyclerViewAdapter(result, resources) recyclerView.layoutManager = LinearLayoutManager(this) 

Sources here . The tutorial came out pretty short and simple, so there were few explanations, but if something is not clear I can answer, and yet we have a ready tracker cryptocurrency.

Source: https://habr.com/ru/post/344630/


All Articles