aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJelena Petrovic <jelenapetrovic.7119@gmail.com>2022-11-18 02:40:29 +0100
committerJelena Petrovic <jelenapetrovic.7119@gmail.com>2022-11-18 02:40:29 +0100
commit7b3b8988f5abb87c17d1459ab80d129b4985fe4f (patch)
tree76328370f613f966ba418a73adfa201d25894390
parentd49c17b695f131f9faf2e419e163df80dde37a88 (diff)
delimicno odradjeno stranicenje #36
-rw-r--r--Client/BrzoDoLokacije/app/build.gradle3
-rw-r--r--Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Adapters/ShowPostsAdapter.kt33
-rw-r--r--Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentShowPosts.kt81
-rw-r--r--Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Interfaces/IBackendApi.kt7
-rw-r--r--Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Models/Post.kt10
-rw-r--r--Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/paging/SearchPostsPagingSource.kt36
-rw-r--r--Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/paging/SearchPostsRepository.kt30
-rw-r--r--Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/paging/SearchPostsViewModel.kt25
-rw-r--r--Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/paging/SearchPostsViewModelFactory.kt15
9 files changed, 201 insertions, 39 deletions
diff --git a/Client/BrzoDoLokacije/app/build.gradle b/Client/BrzoDoLokacije/app/build.gradle
index db4ed1b..e1ad943 100644
--- a/Client/BrzoDoLokacije/app/build.gradle
+++ b/Client/BrzoDoLokacije/app/build.gradle
@@ -52,6 +52,9 @@ dependencies {
implementation 'com.google.android.gms:play-services-location:21.0.1'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'androidx.recyclerview:recyclerview:1.2.1'
+ implementation "androidx.paging:paging-runtime:3.0.0-alpha03"
+ implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1"
+
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Adapters/ShowPostsAdapter.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Adapters/ShowPostsAdapter.kt
index bbcf9e4..a827dcb 100644
--- a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Adapters/ShowPostsAdapter.kt
+++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Adapters/ShowPostsAdapter.kt
@@ -8,6 +8,8 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.ViewGroup
import android.widget.Toast
+import androidx.paging.PagingDataAdapter
+import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.example.brzodolokacije.Activities.ActivitySinglePost
@@ -25,10 +27,23 @@ import retrofit2.Response
class ShowPostsAdapter (val activity:Activity,val items : MutableList<PostPreview>)
- : RecyclerView.Adapter<ShowPostsAdapter.ViewHolder>() {
+ : PagingDataAdapter<PostPreview, ShowPostsAdapter.ViewHolder>(REPO_COMPARATOR) {
private lateinit var token: String
private lateinit var imageApi: IBackendApi
+ companion object{
+ private val REPO_COMPARATOR=object:DiffUtil.ItemCallback<PostPreview>(){
+ override fun areContentsTheSame(oldItem: PostPreview, newItem: PostPreview): Boolean {
+ return oldItem._id==newItem._id
+ }
+
+ override fun areItemsTheSame(oldItem: PostPreview, newItem: PostPreview): Boolean {
+ return oldItem._id==newItem._id
+ }
+ }
+ }
+
+
//constructer has one argument - list of objects that need to be displayed
//it is bound to xml of single item
private lateinit var binding: PostPreviewBinding
@@ -42,20 +57,18 @@ class ShowPostsAdapter (val activity:Activity,val items : MutableList<PostPrevie
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
//sets components of particular item
- holder.bind(items[position])
+ holder.bind(getItem(position)!!)
holder.itemView.setOnClickListener {
//Toast.makeText(activity,item._id,Toast.LENGTH_LONG).show()
- val intent:Intent = Intent(activity,ActivitySinglePost::class.java)
- var b=Bundle()
- items[position].location.type=LocationType.ADA
- b.putParcelable("selectedPost", items[position])
- intent.putExtras(b)
- activity.startActivity(intent)
+// val intent:Intent = Intent(activity,ActivitySinglePost::class.java)
+// var b=Bundle()
+// items[position].location.type=LocationType.ADA
+// b.putParcelable("selectedPost", items[position])
+// intent.putExtras(b)
+// activity.startActivity(intent)
}
}
-
- override fun getItemCount() = items.size
inner class ViewHolder(itemView: PostPreviewBinding) : RecyclerView.ViewHolder(itemView.root) {
fun bind(item: PostPreview) {
binding.apply {
diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentShowPosts.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentShowPosts.kt
index 83f6429..84df389 100644
--- a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentShowPosts.kt
+++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Fragments/FragmentShowPosts.kt
@@ -10,6 +10,10 @@ import android.view.View
import android.view.ViewGroup
import android.widget.ImageButton
import android.widget.Toast
+import androidx.lifecycle.ViewModelProvider
+import androidx.lifecycle.lifecycleScope
+import androidx.paging.PagingDataAdapter
+import androidx.paging.cachedIn
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
@@ -23,8 +27,14 @@ import com.example.brzodolokacije.Services.RetrofitHelper
import com.example.brzodolokacije.Services.SharedPreferencesHelper
import com.example.brzodolokacije.databinding.FragmentHomeBinding
import com.example.brzodolokacije.databinding.FragmentShowPostsBinding
+import com.example.brzodolokacije.paging.SearchPostsRepository
+import com.example.brzodolokacije.paging.SearchPostsViewModel
+import com.example.brzodolokacije.paging.SearchPostsViewModelFactory
import kotlinx.android.synthetic.main.fragment_show_posts.*
import kotlinx.android.synthetic.main.fragment_show_posts.view.*
+import kotlinx.coroutines.flow.collectLatest
+import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.launch
import okhttp3.ResponseBody
import retrofit2.Call
import retrofit2.Response
@@ -35,13 +45,15 @@ class FragmentShowPosts : Fragment(), SwipeRefreshLayout.OnRefreshListener {
private lateinit var binding: FragmentShowPostsBinding
private var posts : MutableList<PostPreview> = mutableListOf()
private var linearManagerVar: RecyclerView.LayoutManager? = null
- private var adapterVar: RecyclerView.Adapter<ShowPostsAdapter.ViewHolder>? = null
+ private var adapterVar: ShowPostsAdapter? = null
private var recyclerView: RecyclerView?=null
private var gridManagerVar: RecyclerView.LayoutManager?=null
private var swipeRefreshLayout:SwipeRefreshLayout?=null
+ private lateinit var searchPostsViewModel:SearchPostsViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
+ setUpViewModel()
binding=FragmentShowPostsBinding.inflate(layoutInflater)
//instantiate adapter and linearLayout
adapterVar=ShowPostsAdapter(requireActivity(),posts)
@@ -49,6 +61,11 @@ class FragmentShowPosts : Fragment(), SwipeRefreshLayout.OnRefreshListener {
gridManagerVar=GridLayoutManager(activity,2)
}
+ private fun setUpViewModel() {
+ val factory=SearchPostsViewModelFactory(RetrofitHelper.getInstance(),requireActivity())
+ searchPostsViewModel=ViewModelProvider(this@FragmentShowPosts,factory).get(SearchPostsViewModel::class.java)
+ }
+
fun setUpListeners(rootView: View?){
rootView?.findViewById<ImageButton>(R.id.btnGridLayout)?.setOnClickListener() {
if(recyclerView?.layoutManager!=gridManagerVar){
@@ -66,32 +83,38 @@ class FragmentShowPosts : Fragment(), SwipeRefreshLayout.OnRefreshListener {
}
fun requestToBack(){
- val postApi= RetrofitHelper.getInstance()
- val token=SharedPreferencesHelper.getValue("jwt", requireActivity())
- val request=postApi.getPosts("Bearer "+token)
- request.enqueue(object : retrofit2.Callback<MutableList<PostPreview>?> {
- override fun onResponse(call: Call<MutableList<PostPreview>?>, response: Response<MutableList<PostPreview>?>) {
- if(response.isSuccessful){
- posts=response.body()!!
- recyclerView?.adapter=ShowPostsAdapter(requireActivity(),posts)
- Toast.makeText(
- activity, "prosao zahtev", Toast.LENGTH_LONG
- ).show()
- swipeRefreshLayout?.isRefreshing=false
- }else{
- if(response.errorBody()!=null)
- Toast.makeText(activity, response.errorBody()!!.string(), Toast.LENGTH_LONG).show();
- }
-
-
+ lifecycleScope.launch{
+ searchPostsViewModel.fetchPosts().distinctUntilChanged().collectLatest {
+ adapterVar?.submitData(it)
+ swipeRefreshLayout?.isRefreshing=false
}
-
- override fun onFailure(call: Call<MutableList<PostPreview>?>, t: Throwable) {
- Toast.makeText(
- activity, t.toString(), Toast.LENGTH_LONG
- ).show();
- }
- })
+ }
+// val postApi= RetrofitHelper.getInstance()
+// val token=SharedPreferencesHelper.getValue("jwt", requireActivity())
+// val request=postApi.getPosts("Bearer "+token)
+// request.enqueue(object : retrofit2.Callback<MutableList<PostPreview>?> {
+// override fun onResponse(call: Call<MutableList<PostPreview>?>, response: Response<MutableList<PostPreview>?>) {
+// if(response.isSuccessful){
+// posts=response.body()!!
+// recyclerView?.adapter=ShowPostsAdapter(requireActivity(),posts)
+// Toast.makeText(
+// activity, "prosao zahtev", Toast.LENGTH_LONG
+// ).show()
+// swipeRefreshLayout?.isRefreshing=false
+// }else{
+// if(response.errorBody()!=null)
+// Toast.makeText(activity, response.errorBody()!!.string(), Toast.LENGTH_LONG).show();
+// }
+//
+//
+// }
+//
+// override fun onFailure(call: Call<MutableList<PostPreview>?>, t: Throwable) {
+// Toast.makeText(
+// activity, t.toString(), Toast.LENGTH_LONG
+// ).show();
+// }
+// })
}
override fun onCreateView(
@@ -115,14 +138,16 @@ class FragmentShowPosts : Fragment(), SwipeRefreshLayout.OnRefreshListener {
R.color.purple_700
)
swipeRefreshLayout?.post(kotlinx.coroutines.Runnable {
- swipeRefreshLayout?.isRefreshing=true
+ //swipeRefreshLayout?.isRefreshing=true
requestToBack()
})
return rootView
}
override fun onRefresh() {
- requestToBack()
+ //requestToBack()
+ adapterVar!!.notifyDataSetChanged()
+ Log.d("main",adapterVar!!.itemCount.toString())
}
} \ No newline at end of file
diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Interfaces/IBackendApi.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Interfaces/IBackendApi.kt
index 2f5cff1..6d09251 100644
--- a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Interfaces/IBackendApi.kt
+++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Interfaces/IBackendApi.kt
@@ -54,6 +54,13 @@ interface IBackendApi {
@GET("/api/user/posts")
fun getMyPosts(@Header("Authorization") authHeader:String):Call<MutableList<PostPreview>>
+ @GET("/api/post/locations/{id}/posts")
+ suspend fun getPagedPosts(@Header("Authorization") authHeader: String,
+ @Path("id") locationId:String,
+ @Query("page") page:Int,
+ @Query("sorttype") sorttype:Int,
+ @Query("filterdate") filterdate:Int
+ ):PagedPosts
//@POST("putanja")
//fun add(@Body obj:Post,@Header("Authorization") authHeader:String):Call<Post>
} \ No newline at end of file
diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Models/Post.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Models/Post.kt
index 3bbcc0c..f990133 100644
--- a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Models/Post.kt
+++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/Models/Post.kt
@@ -71,4 +71,12 @@ data class Rating(
data class RatingReceive(
var rating:Int,
var postId:String
-) \ No newline at end of file
+)
+
+data class PagedPosts(
+ var page:Int,
+ var index:Int,
+ var totalpages:Int,
+ var totalposts:Int,
+ var posts:MutableList<PostPreview>
+)
diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/paging/SearchPostsPagingSource.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/paging/SearchPostsPagingSource.kt
new file mode 100644
index 0000000..2f69a7a
--- /dev/null
+++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/paging/SearchPostsPagingSource.kt
@@ -0,0 +1,36 @@
+package com.example.brzodolokacije.paging
+
+import android.app.Activity
+import android.util.Log
+import androidx.paging.PagingSource
+import com.example.brzodolokacije.Interfaces.IBackendApi
+import com.example.brzodolokacije.Models.PagedPosts
+import com.example.brzodolokacije.Models.PostPreview
+import com.example.brzodolokacije.Services.SharedPreferencesHelper
+import retrofit2.HttpException
+import java.io.IOException
+
+class SearchPostsPagingSource(
+ val backend: IBackendApi,
+ val activity: Activity
+):PagingSource<Int,PostPreview>() {
+ override suspend fun load(params: LoadParams<Int>): LoadResult<Int, PostPreview> {
+ val page=params.key?:0
+ val token=SharedPreferencesHelper.getValue("jwt", activity)
+ return try{
+ val response=backend.getPagedPosts("Bearer "+token,"6375784fe84e2d53df32bf03",
+ page,1,1
+ )
+ Log.d("main",page.toString())
+ LoadResult.Page(
+ response.posts,prevKey=if(page==0) null else page-1,
+ nextKey=if(response.posts.isEmpty()) null else page+1
+ )
+ }catch(exception:IOException){
+ return LoadResult.Error(exception)
+ }catch(exception:HttpException){
+ return LoadResult.Error(exception)
+ }
+ }
+
+} \ No newline at end of file
diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/paging/SearchPostsRepository.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/paging/SearchPostsRepository.kt
new file mode 100644
index 0000000..ae3a684
--- /dev/null
+++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/paging/SearchPostsRepository.kt
@@ -0,0 +1,30 @@
+package com.example.brzodolokacije.paging
+
+import android.app.Activity
+import androidx.paging.Pager
+import androidx.paging.PagingConfig
+import androidx.paging.PagingData
+import androidx.paging.cachedIn
+import com.example.brzodolokacije.Models.PostPreview
+import com.example.brzodolokacije.Services.RetrofitHelper
+import kotlinx.coroutines.flow.Flow
+
+class SearchPostsRepository(val activity: Activity) {
+ companion object{
+ const val DEFAULT_PAGE_SIZE=20
+ const val DEFAULT_PAGE_INDEX=1
+
+ fun getInstance(activity: Activity)=SearchPostsRepository(activity)
+ }
+
+ fun letSearchedPostsFlow(pagingConfig: PagingConfig=getDefaultPageConfig()): Flow<PagingData<PostPreview>> {
+ return Pager(
+ config=pagingConfig,
+ pagingSourceFactory = {SearchPostsPagingSource(RetrofitHelper.getInstance(),activity)}
+ ).flow
+ }
+
+ private fun getDefaultPageConfig(): PagingConfig {
+ return PagingConfig(pageSize= DEFAULT_PAGE_SIZE, enablePlaceholders = false)
+ }
+} \ No newline at end of file
diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/paging/SearchPostsViewModel.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/paging/SearchPostsViewModel.kt
new file mode 100644
index 0000000..d0bf3ef
--- /dev/null
+++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/paging/SearchPostsViewModel.kt
@@ -0,0 +1,25 @@
+package com.example.brzodolokacije.paging
+
+import android.app.Activity
+import androidx.lifecycle.ViewModel
+import androidx.lifecycle.viewModelScope
+import androidx.paging.Pager
+import androidx.paging.PagingConfig
+import androidx.paging.PagingData
+import androidx.paging.cachedIn
+import com.example.brzodolokacije.Interfaces.IBackendApi
+import com.example.brzodolokacije.Models.PostPreview
+import kotlinx.coroutines.flow.Flow
+
+class SearchPostsViewModel(
+ private val api:IBackendApi,
+ val activity:Activity
+): ViewModel() {
+ val posts =
+ Pager(config = PagingConfig(pageSize = 10), pagingSourceFactory = {
+ SearchPostsPagingSource(api,activity)
+ }).flow.cachedIn(viewModelScope)
+ fun fetchPosts(): Flow<PagingData<PostPreview>>{
+ return SearchPostsRepository.getInstance(activity).letSearchedPostsFlow().cachedIn(viewModelScope)
+ }
+} \ No newline at end of file
diff --git a/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/paging/SearchPostsViewModelFactory.kt b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/paging/SearchPostsViewModelFactory.kt
new file mode 100644
index 0000000..cddea54
--- /dev/null
+++ b/Client/BrzoDoLokacije/app/src/main/java/com/example/brzodolokacije/paging/SearchPostsViewModelFactory.kt
@@ -0,0 +1,15 @@
+package com.example.brzodolokacije.paging
+
+import android.app.Activity
+import androidx.lifecycle.ViewModel
+import androidx.lifecycle.ViewModelProvider
+import com.example.brzodolokacije.Interfaces.IBackendApi
+
+class SearchPostsViewModelFactory(
+ val api:IBackendApi,
+ val activity: Activity
+):ViewModelProvider.NewInstanceFactory() {
+ override fun <T : ViewModel> create(modelClass: Class<T>): T {
+ return SearchPostsViewModel(api,activity) as T
+ }
+} \ No newline at end of file