Created
February 23, 2021 10:01
-
-
Save iamnaran/5702e390098ad57146b6a944bc069b7b to your computer and use it in GitHub Desktop.
Search Recycler View
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="utf-8"?> | |
<androidx.core.widget.NestedScrollView | |
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"> | |
<androidx.constraintlayout.widget.ConstraintLayout | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:layout_marginStart="8dp" | |
android:layout_marginEnd="8dp" | |
android:fitsSystemWindows="true"> | |
<include | |
android:id="@+id/title_layout" | |
layout="@layout/item_title_profile" | |
android:layout_width="0dp" | |
android:layout_height="wrap_content" | |
app:layout_constraintEnd_toEndOf="parent" | |
app:layout_constraintStart_toStartOf="parent" | |
app:layout_constraintTop_toTopOf="parent" /> | |
<include | |
android:id="@+id/search_layout" | |
layout="@layout/item_search_photos" | |
android:layout_width="0dp" | |
android:layout_height="wrap_content" | |
app:layout_constraintEnd_toEndOf="parent" | |
app:layout_constraintStart_toStartOf="parent" | |
app:layout_constraintTop_toBottomOf="@+id/title_layout" /> | |
<androidx.recyclerview.widget.RecyclerView | |
android:id="@+id/recycler_view" | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:clipToPadding="false" | |
android:paddingTop="10dp" | |
android:paddingBottom="60dp" | |
app:layout_constraintBottom_toBottomOf="parent" | |
app:layout_constraintTop_toBottomOf="@+id/search_layout" /> | |
</androidx.constraintlayout.widget.ConstraintLayout> | |
</androidx.core.widget.NestedScrollView> | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
object ApiEndPoints { | |
const val LOGIN = "login" | |
const val REGISTER = "register" | |
const val HOME = "home" | |
const val PHOTOS_URL = "list" | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
interface ApiHelper { | |
suspend fun getPhotos(): Response<List<Photos>> | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
interface ApiService { | |
@POST(ApiEndPoints.LOGIN) | |
@FormUrlEncoded | |
suspend fun userLogin( | |
@Field("email") userEmail: String, | |
@Field("password") userPassword: String | |
): Response<User> | |
@GET(ApiEndPoints.HOME) | |
suspend fun homeFeeds(): Response<Home> | |
@GET(ApiEndPoints.PHOTOS_URL) | |
suspend fun getPhotosUrl(): Response<List<Photos>> | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="utf-8"?> | |
<shape xmlns:android="http://schemas.android.com/apk/res/android" | |
android:shape="rectangle"> | |
<solid android:color="@color/colorContainer" /> | |
<corners android:radius="8dp" /> | |
</shape> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="utf-8"?> | |
<androidx.cardview.widget.CardView 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_margin="15dp" | |
app:cardCornerRadius="8dp" | |
android:layout_height="wrap_content"> | |
<androidx.constraintlayout.widget.ConstraintLayout | |
android:layout_width="match_parent" | |
android:layout_height="match_parent"> | |
<ImageView | |
android:id="@+id/imageView" | |
android:layout_width="match_parent" | |
android:layout_height="200dp" | |
android:scaleType="centerCrop" | |
app:layout_constraintTop_toTopOf="parent" | |
tools:srcCompat="@tools:sample/backgrounds/scenic" /> | |
<TextView | |
android:id="@+id/name" | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:layout_marginTop="200dp" | |
android:padding="20dp" | |
android:text="Hello World" | |
android:textColor="@color/colorPrimaryText" | |
app:layout_constraintBottom_toBottomOf="parent" | |
app:layout_constraintTop_toTopOf="@+id/imageView" /> | |
</androidx.constraintlayout.widget.ConstraintLayout> | |
</androidx.cardview.widget.CardView> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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="wrap_content"> | |
<SearchView | |
android:id="@+id/search_view" | |
android:layout_width="0dp" | |
android:layout_marginTop="5dp" | |
android:layout_marginBottom="5dp" | |
android:layout_marginStart="8dp" | |
android:layout_marginEnd="8dp" | |
android:layout_height="wrap_content" | |
android:includeFontPadding="false" | |
android:padding="2dp" | |
style="@style/SearchViewStyle" | |
android:textColor="@color/colorPrimaryText" | |
android:textSize="16sp" | |
app:iconifiedByDefault="false" | |
android:textStyle="bold" | |
app:layout_constraintBottom_toBottomOf="parent" | |
app:layout_constraintEnd_toEndOf="parent" | |
app:layout_constraintHorizontal_bias="1.0" | |
app:layout_constraintStart_toStartOf="parent" | |
app:layout_constraintTop_toTopOf="parent" | |
app:layout_constraintVertical_bias="0.0" | |
app:queryHint="Search Photos" /> | |
</androidx.constraintlayout.widget.ConstraintLayout> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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="wrap_content"> | |
<TextView | |
android:id="@+id/toolbar_title" | |
android:layout_width="0dp" | |
android:layout_height="wrap_content" | |
android:layout_marginTop="10dp" | |
android:layout_marginBottom="10dp" | |
android:padding="10dp" | |
android:includeFontPadding="false" | |
android:text="Photos" | |
android:textSize="18sp" | |
android:textStyle="bold" | |
app:layout_constraintBottom_toBottomOf="parent" | |
app:layout_constraintEnd_toEndOf="parent" | |
app:layout_constraintHorizontal_bias="1.0" | |
app:layout_constraintStart_toStartOf="parent" | |
app:layout_constraintTop_toTopOf="parent" | |
app:layout_constraintVertical_bias="0.0" /> | |
</androidx.constraintlayout.widget.ConstraintLayout> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import com.google.gson.annotations.SerializedName | |
data class Photos( | |
@SerializedName("author") | |
var author: String, // Matthew Wiebe | |
@SerializedName("download_url") | |
var downloadUrl: String, // https://picsum.photos/id/1025/4951/3301 | |
@SerializedName("height") | |
var height: Int, // 3301 | |
@SerializedName("id") | |
var id: String, // 1025 | |
@SerializedName("url") | |
var url: String, // https://unsplash.com/photos/U5rMrSI7Pn4 | |
@SerializedName("width") | |
var width: Int // 4951 | |
) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.template.androidtemplate.ui.photos.view | |
import androidx.appcompat.app.AppCompatActivity | |
import android.os.Bundle | |
import android.widget.SearchView | |
import androidx.activity.viewModels | |
import androidx.lifecycle.Observer | |
import androidx.recyclerview.widget.LinearLayoutManager | |
import com.google.gson.Gson | |
import com.template.androidtemplate.R | |
import com.template.androidtemplate.data.model.Photos | |
import com.template.androidtemplate.ui.photos.adapter.PhotosAdapter | |
import com.template.androidtemplate.ui.photos.viewmodel.PhotosViewModel | |
import com.template.androidtemplate.utils.Status | |
import dagger.hilt.android.AndroidEntryPoint | |
import kotlinx.android.synthetic.main.activity_photos.* | |
@AndroidEntryPoint | |
class PhotosActivity : AppCompatActivity() , SearchView.OnQueryTextListener{ | |
private val photosViewModel: PhotosViewModel by viewModels() | |
private lateinit var photosAdapter: PhotosAdapter | |
override fun onCreate(savedInstanceState: Bundle?) { | |
super.onCreate(savedInstanceState) | |
setContentView(R.layout.activity_photos) | |
setUpViews() | |
doObserveWork() | |
} | |
private fun setUpViews() { | |
search_layout.findViewById<SearchView>(R.id.search_view) | |
.setOnQueryTextListener(this) | |
recycler_view.layoutManager = LinearLayoutManager(this, | |
LinearLayoutManager.VERTICAL,false) | |
photosAdapter = PhotosAdapter() | |
recycler_view.adapter = photosAdapter | |
} | |
private fun doObserveWork() { | |
photosViewModel.progressBarVisibility.observe(this, Observer { | |
}) | |
photosViewModel.getPhotosFeed().observe(this, Observer { | |
when (it.status) { | |
Status.SUCCESS -> { | |
val gson: Gson = Gson() | |
renderPhotosList(it.data!!) | |
} | |
Status.ERROR -> { | |
} | |
Status.LOADING -> { | |
} | |
} | |
}) | |
} | |
private fun renderPhotosList(photosList: List<Photos>) { | |
photosAdapter.addData(photosList) | |
photosAdapter.notifyDataSetChanged() | |
} | |
override fun onQueryTextSubmit(query: String?): Boolean { | |
photosAdapter.filter.filter(query) | |
return false | |
} | |
override fun onQueryTextChange(newText: String?): Boolean { | |
photosAdapter.filter.filter(newText) | |
return false | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.template.androidtemplate.ui.photos.adapter | |
import android.util.Log | |
import android.view.LayoutInflater | |
import android.view.View | |
import android.view.ViewGroup | |
import android.widget.Filter | |
import android.widget.Filterable | |
import androidx.recyclerview.widget.RecyclerView | |
import com.bumptech.glide.Glide | |
import com.template.androidtemplate.R | |
import com.template.androidtemplate.data.model.Photos | |
import kotlinx.android.synthetic.main.item_row_photos.view.* | |
import kotlin.collections.ArrayList | |
open class PhotosAdapter : | |
RecyclerView.Adapter<PhotosAdapter.DataViewHolder>(), Filterable { | |
//Image world pixels | |
var photosList: ArrayList<Photos> = ArrayList() | |
var photosListFiltered: ArrayList<Photos> = ArrayList() | |
var onItemClick: ((Photos) -> Unit)? = null | |
inner class DataViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { | |
init { | |
itemView.setOnClickListener { | |
onItemClick?.invoke(photosListFiltered[adapterPosition]) | |
} | |
} | |
fun bind(result: Photos) { | |
itemView.name.text = result.id +" "+ result.author | |
Glide.with(itemView.imageView.context).load(result.downloadUrl).into(itemView.imageView) | |
} | |
} | |
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = DataViewHolder( | |
LayoutInflater.from(parent.context).inflate( | |
R.layout.item_row_photos, parent, | |
false | |
) | |
) | |
override fun onBindViewHolder(holder: DataViewHolder, position: Int) { | |
holder.bind(photosListFiltered[position]) | |
} | |
override fun getItemCount(): Int = photosListFiltered.size | |
fun addData(list: List<Photos>) { | |
photosList = list as ArrayList<Photos> | |
photosListFiltered = photosList | |
notifyDataSetChanged() | |
} | |
override fun getFilter(): Filter { | |
return object : Filter() { | |
override fun performFiltering(constraint: CharSequence?): FilterResults { | |
val charString = constraint?.toString() ?: "" | |
if (charString.isEmpty()) photosListFiltered = photosList else { | |
val filteredList = ArrayList<Photos>() | |
photosList | |
.filter { | |
(it.id.contains(constraint!!)) or | |
(it.author.contains(constraint)) | |
} | |
.forEach { filteredList.add(it) } | |
photosListFiltered = filteredList | |
Log.e("performFiltering: t1: ", filteredList.size.toString()) | |
} | |
return FilterResults().apply { values = photosListFiltered } | |
} | |
override fun publishResults(constraint: CharSequence?, results: FilterResults?) { | |
photosListFiltered = if (results?.values == null) | |
ArrayList() | |
else | |
results.values as ArrayList<Photos> | |
notifyDataSetChanged() | |
Log.e("performFiltering: t2 ", "called" + photosListFiltered.size) | |
} | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.template.androidtemplate.data.repository | |
import com.template.androidtemplate.data.api.ApiHelper | |
import javax.inject.Inject | |
class PhotosRepository @Inject constructor( | |
private val apiHelper: ApiHelper | |
) { | |
suspend fun photosFeed() = apiHelper.getPhotos() | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.template.androidtemplate.ui.photos.viewmodel | |
import androidx.lifecycle.LiveData | |
import androidx.lifecycle.MutableLiveData | |
import androidx.lifecycle.ViewModel | |
import androidx.lifecycle.viewModelScope | |
import com.template.androidtemplate.data.helper.PreferencesHelper | |
import com.template.androidtemplate.data.model.Photos | |
import com.template.androidtemplate.data.repository.PhotosRepository | |
import com.template.androidtemplate.utils.NetworkHelper | |
import com.template.androidtemplate.utils.Resource | |
import dagger.hilt.android.lifecycle.HiltViewModel | |
import kotlinx.coroutines.launch | |
import javax.inject.Inject | |
@HiltViewModel | |
class PhotosViewModel @Inject constructor( | |
private val networkHelper: NetworkHelper, | |
private val preferencesHelper: PreferencesHelper, | |
private val photosRepository: PhotosRepository | |
) : ViewModel() { | |
private val TAG = PhotosViewModel::class.qualifiedName | |
var progressBarVisibility: MutableLiveData<Boolean> = MutableLiveData() | |
var onResponse: MutableLiveData<Resource<List<Photos>>> = MutableLiveData() | |
fun isProgressBarVisible(): LiveData<Boolean> { | |
return progressBarVisibility | |
} | |
fun getPhotosFeed(): LiveData<Resource<List<Photos>>>{ | |
return onResponse | |
} | |
init { | |
doPhotosWork(); | |
} | |
private fun doPhotosWork() { | |
viewModelScope.launch { | |
if (networkHelper.isNetworkConnected()){ | |
photosRepository.photosFeed().let { | |
if (it.isSuccessful){ | |
onResponse.postValue(Resource.success(it.body())) | |
// preferencesHelper.setHomeFeeds(it.body()) | |
progressBarVisibility.postValue(false) | |
}else{ | |
onResponse.postValue(Resource.error(it.errorBody().toString(),null)) | |
progressBarVisibility.postValue(false) | |
} | |
} | |
} | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<style name="SearchViewStyle" parent="Widget.AppCompat.SearchView"> | |
<!-- Gets rid of the search icon --> | |
<!-- <item name="searchIcon">@null</item>--> | |
<!-- Gets rid of the "underline" in the text --> | |
<item name="queryBackground">@color/colorContainer</item> | |
<item name="background">@color/colorContainer</item> | |
<!-- Gets rid of the search icon when the SearchView is expanded --> | |
<item name="searchHintIcon">@null</item> | |
<!-- The hint text that appears when the user has not typed anything --> | |
<item name="queryHint">@string/search_photos</item> | |
<item name="android:queryHint">@string/search_photos</item> | |
<item name="android:background">@drawable/background_search</item> | |
<!-- <item name="closeIcon">@drawable/ic_clo</item>--> | |
<item name="android:textColor">@color/colorAccent</item> | |
<item name="android:textColorSecondary">@color/colorAccent</item> | |
</style> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment