Skip to content

Instantly share code, notes, and snippets.

@anandrex5
Created August 8, 2022 10:05
Show Gist options
  • Save anandrex5/9b09a92c0a0900059ee9da218683800a to your computer and use it in GitHub Desktop.
Save anandrex5/9b09a92c0a0900059ee9da218683800a to your computer and use it in GitHub Desktop.
APi_RxJava_Retrofit_RecyclerView (API TYPE - QUERY)
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<EditText android:id="@+id/inputBookName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:layout_margin="20dp"
android:hint="enter book name"
/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/inputBookName"
android:layout_margin="05dp"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
package com.example.api_rxjava.adapter
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.example.api_rxjava.R
import com.example.api_rxjava.network.VolumeInfo
import kotlinx.android.synthetic.main.recycler_list_row.view.*
//create adapter and implements three methods
class BookListAdapter: RecyclerView.Adapter<BookListAdapter.MyViewHolder>() {
var bookListData = ArrayList<VolumeInfo>()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BookListAdapter.MyViewHolder {
val inflater = LayoutInflater.from(parent.context).inflate(R.layout.recycler_list_row, parent,false)
return MyViewHolder(inflater)
}
override fun onBindViewHolder(holder: BookListAdapter.MyViewHolder, position: Int) {
holder.bind(bookListData[position])
}
override fun getItemCount(): Int {
return bookListData.size
}
class MyViewHolder(view: View): RecyclerView.ViewHolder(view) {
val tvTitle = view.tvTitle
val tvPublisher = view.tvPublisher
val tvDescription = view.tvDescription
val thumbImageView = view.thumbImageView
fun bind(data: VolumeInfo) {
tvTitle.text =data.volumeInfo.title
tvPublisher.text =data.volumeInfo.publisher
tvDescription.text =data.volumeInfo.description
val url = data.volumeInfo?.imageLinks.smallThumbnail
Glide.with(thumbImageView)
.load(url)
.circleCrop()
.into(thumbImageView)
}
}
}
package com.example.api_rxjava.network
data class BookListModel(val items: ArrayList<VolumeInfo>)
data class VolumeInfo(val volumeInfo: BookInfo)
data class BookInfo(val title: String, val publisher: String, val description: String, val imageLinks: ImageLinks)
data class ImageLinks(val smallThumbnail:String)
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
id "kotlin-android-extensions"
}
android {
compileSdk 32
buildToolsVersion "29.0.3"
defaultConfig {
applicationId "com.example.api_rxjava"
minSdk 21
targetSdk 32
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
}
dependencies {
implementation 'androidx.core:core-ktx:1.7.0'
implementation 'androidx.appcompat:appcompat:1.3.0'
implementation 'com.google.android.material:material:1.4.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
implementation fileTree(dir: "libs", include: ["*.jar"])
implementation 'androidx.core:core-ktx:1.3.2'
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.2'
implementation 'androidx.recyclerview:recyclerview:1.2.0-alpha06'
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
implementation 'com.github.bumptech.glide:glide:4.11.0'
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.9.0'
implementation 'androidx.recyclerview:recyclerview:1.2.0'
// for adding cardview
implementation 'androidx.cardview:cardview:1.0.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
implementation 'io.reactivex.rxjava2:rxandroid:2.1.0'
implementation 'io.reactivex.rxjava2:rxjava:2.2.0'
implementation("androidx.recyclerview:recyclerview:1.2.1")
implementation("androidx.cardview:cardview:1.0.0")
implementation 'com.google.code.gson:gson:2.8.7'
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
implementation("com.squareup.okhttp3:logging-interceptor:4.10.0")
implementation "androidx.lifecycle:lifecycle-extensions:2.2.0"
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.2.0"
implementation "android.arch.lifecycle:viewmodel:1.1.0"
}
package com.example.api_rxjava
import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.StaggeredGridLayoutManager.VERTICAL
import com.example.api_rxjava.adapter.BookListAdapter
import com.example.api_rxjava.network.BookListModel
import com.example.api_rxjava.viewmodel.MainActivityViewModel
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
lateinit var viewModel: MainActivityViewModel
lateinit var bookListAdapter: BookListAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
initSearchBox()
initRecyclerView()
}
fun initSearchBox() {
inputBookName.addTextChangedListener(object : TextWatcher{
override fun afterTextChanged(s: Editable?) {
}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
loadAPIData(s.toString())
}
})
}
fun initRecyclerView(){
recyclerView.apply {
layoutManager = LinearLayoutManager(this@MainActivity)
val decoration = DividerItemDecoration(applicationContext, VERTICAL)
addItemDecoration(decoration)
bookListAdapter = BookListAdapter()
adapter =bookListAdapter
}
}
//make function api call from ViewModel
fun loadAPIData(input: String) {
viewModel = ViewModelProvider(this).get(MainActivityViewModel::class.java)
viewModel.getBookListObserver().observe(this, Observer<BookListModel>{
if(it != null) {
//update adapter...
bookListAdapter.bookListData = it.items
bookListAdapter.notifyDataSetChanged()
}
else {
Toast.makeText(this, "Error in fetching data", Toast.LENGTH_SHORT).show()
}
})
viewModel.makeApiCall(input)
}
}
package com.example.api_rxjava.viewmodel
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.example.api_rxjava.network.BookListModel
import com.example.api_rxjava.network.RetroInstance
import com.example.api_rxjava.network.RetroService
import io.reactivex.Observer
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers
class MainActivityViewModel: ViewModel() {
lateinit var bookList: MutableLiveData<BookListModel>
init {
bookList = MutableLiveData()
}
fun getBookListObserver(): MutableLiveData<BookListModel> {
return bookList
}
fun makeApiCall(query: String) {
val retroInstance = RetroInstance.getRetroInstance().create(RetroService::class.java)
retroInstance.getBookListFromApi(query)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(getBookListObserverRx())
}
private fun getBookListObserverRx():Observer<BookListModel> {
return object :Observer<BookListModel>{
override fun onComplete() {
//hide progress indicator .
}
override fun onError(e: Throwable) {
bookList.postValue(null)
}
override fun onNext(t: BookListModel) {
bookList.postValue(t)
}
override fun onSubscribe(d: Disposable) {
//start showing progress indicator.
}
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView android:id="@+id/thumbImageView"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_gravity="center"
android:layout_margin="10dp"
/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<TextView android:id="@+id/tvTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18sp"
android:textStyle="bold"
android:textColor="#000"
android:layout_margin="10dp"
/>
<TextView android:id="@+id/tvPublisher"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16sp"
android:textStyle="bold"
android:layout_marginStart="10dp"
/>
<TextView android:id="@+id/tvDescription"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="14sp"
android:textColor="@color/teal_700"
android:maxLines="3"
android:layout_margin="10dp"
/>
</LinearLayout>
</LinearLayout>
package com.example.api_rxjava.network
import com.google.gson.Gson
import retrofit2.Retrofit
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
import retrofit2.converter.gson.GsonConverterFactory
class RetroInstance {
companion object {
val baseURL = "https://www.googleapis.com/books/v1/"
fun getRetroInstance() : Retrofit {
//build API
return Retrofit.Builder()
.baseUrl(baseURL)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build()
}
}
}
package com.example.api_rxjava.network
import io.reactivex.Observable
import retrofit2.http.GET
import retrofit2.http.Query
interface RetroService {
@GET("volumes")
//take input from the user as Query
fun getBookListFromApi(@Query("q") query: String): Observable<BookListModel>
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment