Add base viewmodel and recyclerview adapter logic

This commit is contained in:
2019-09-13 17:21:41 +02:00
committed by Matte23
parent 57ecdd8062
commit d87210e1ca
11 changed files with 107 additions and 19 deletions

View File

@@ -0,0 +1,32 @@
package net.underdesk.circolapp.adapters
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import kotlinx.android.synthetic.main.item_circular.view.*
import net.underdesk.circolapp.R
import net.underdesk.circolapp.data.Circular
class CircularLetterAdapter(private val circulars: List<Circular>) :
RecyclerView.Adapter<CircularLetterAdapter.CircularLetterViewHolder>() {
inner class CircularLetterViewHolder(view: View) : RecyclerView.ViewHolder(view) {
var title: TextView = view.circular_title_textview
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CircularLetterViewHolder {
val itemView = LayoutInflater.from(parent.context)
.inflate(R.layout.item_circular, parent, false)
return CircularLetterViewHolder(itemView)
}
override fun onBindViewHolder(holder: CircularLetterViewHolder, position: Int) {
holder.title.text = circulars[position].name
}
override fun getItemCount() = circulars.size
}

View File

@@ -23,7 +23,7 @@ import androidx.room.PrimaryKey
@Entity(tableName = "circulars") @Entity(tableName = "circulars")
data class Circular( data class Circular(
@PrimaryKey(autoGenerate = true) val id: Long, @PrimaryKey(autoGenerate = true) val id: Long?,
val name: String, val name: String,
val url: String val url: String
) )

View File

@@ -18,7 +18,6 @@
package net.underdesk.circolapp.data package net.underdesk.circolapp.data
import androidx.lifecycle.LiveData
import androidx.room.Dao import androidx.room.Dao
import androidx.room.Insert import androidx.room.Insert
import androidx.room.OnConflictStrategy import androidx.room.OnConflictStrategy
@@ -27,8 +26,11 @@ import androidx.room.Query
@Dao @Dao
interface CircularDao { interface CircularDao {
@Query("SELECT * FROM circulars") @Query("SELECT * FROM circulars")
fun getCirculars(): LiveData<List<Circular>> fun getCirculars(): List<Circular>
@Insert(onConflict = OnConflictStrategy.REPLACE) @Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertAll(circulars: List<Circular>) fun insertAll(circulars: List<Circular>)
@Query("DELETE FROM circulars")
fun deleteAll()
} }

View File

@@ -25,7 +25,10 @@ import android.view.ViewGroup
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProviders import androidx.lifecycle.ViewModelProviders
import androidx.recyclerview.widget.LinearLayoutManager
import kotlinx.android.synthetic.main.fragment_circular_letters.view.*
import net.underdesk.circolapp.R import net.underdesk.circolapp.R
import net.underdesk.circolapp.adapters.CircularLetterAdapter
import net.underdesk.circolapp.viewmodels.CircularLetterViewModel import net.underdesk.circolapp.viewmodels.CircularLetterViewModel
class CircularLetterFragment : Fragment() { class CircularLetterFragment : Fragment() {
@@ -37,11 +40,14 @@ class CircularLetterFragment : Fragment() {
container: ViewGroup?, container: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?
): View? { ): View? {
val root = inflater.inflate(R.layout.fragment_circular_letters, container, false)
root.circulars_list.layoutManager = LinearLayoutManager(context)
circularLetterViewModel = circularLetterViewModel =
ViewModelProviders.of(this).get(CircularLetterViewModel::class.java) ViewModelProviders.of(this).get(CircularLetterViewModel::class.java)
val root = inflater.inflate(R.layout.fragment_circular_letters, container, false) circularLetterViewModel.circulars.observe(this, Observer {
circularLetterViewModel.text.observe(this, Observer { root.circulars_list.adapter = CircularLetterAdapter(it)
}) })
return root return root
} }

View File

@@ -40,7 +40,7 @@ class FavouritesFragment : Fragment() {
circularLetterViewModel = circularLetterViewModel =
ViewModelProviders.of(this).get(CircularLetterViewModel::class.java) ViewModelProviders.of(this).get(CircularLetterViewModel::class.java)
val root = inflater.inflate(R.layout.fragment_circular_letters, container, false) val root = inflater.inflate(R.layout.fragment_circular_letters, container, false)
circularLetterViewModel.text.observe(this, Observer { circularLetterViewModel.circulars.observe(this, Observer {
}) })
return root return root

View File

@@ -40,7 +40,7 @@ class RemindersFragment : Fragment() {
circularLetterViewModel = circularLetterViewModel =
ViewModelProviders.of(this).get(CircularLetterViewModel::class.java) ViewModelProviders.of(this).get(CircularLetterViewModel::class.java)
val root = inflater.inflate(R.layout.fragment_circular_letters, container, false) val root = inflater.inflate(R.layout.fragment_circular_letters, container, false)
circularLetterViewModel.text.observe(this, Observer { circularLetterViewModel.circulars.observe(this, Observer {
}) })
return root return root

View File

@@ -19,6 +19,7 @@
package net.underdesk.circolapp.server package net.underdesk.circolapp.server
import com.google.gson.Gson import com.google.gson.Gson
import net.underdesk.circolapp.data.Circular
import net.underdesk.circolapp.server.pojo.Response import net.underdesk.circolapp.server.pojo.Response
import org.jsoup.Jsoup import org.jsoup.Jsoup
import java.io.IOException import java.io.IOException
@@ -33,16 +34,16 @@ class DataFetcher {
} }
@Throws(IOException::class) @Throws(IOException::class)
fun getCircularsFromServer(): ArrayList<Pair<String, String>> { public fun getCircularsFromServer(): List<Circular> {
val json = gson.fromJson(retrieveDataFromServer(), Response::class.java) val json = gson.fromJson(retrieveDataFromServer(), Response::class.java)
val document = Jsoup.parseBodyFragment(json.content!!.rendered) val document = Jsoup.parseBodyFragment(json.content!!.rendered)
val htmlList = document.getElementsByTag("ul")[0].getElementsByTag("a") val htmlList = document.getElementsByTag("ul")[0].getElementsByTag("a")
val list = ArrayList<Pair<String, String>>() val list = ArrayList<Circular>()
htmlList.forEach { element -> htmlList.forEach { element ->
list.add(Pair(element.text(), element.attr("href"))) list.add(Circular(null, element.text(), element.attr("href")))
} }
return list return list

View File

@@ -18,14 +18,41 @@
package net.underdesk.circolapp.viewmodels package net.underdesk.circolapp.viewmodels
import android.app.Application
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel import net.underdesk.circolapp.data.AppDatabase
import net.underdesk.circolapp.data.Circular
import net.underdesk.circolapp.server.DataFetcher
class CircularLetterViewModel : ViewModel() { class CircularLetterViewModel(application: Application) : AndroidViewModel(application) {
private val _text = MutableLiveData<String>().apply { private val _circulars: MutableLiveData<List<Circular>> by lazy {
value = "" MutableLiveData<List<Circular>>().also {
loadCirculars()
}
}
val circulars: LiveData<List<Circular>> = _circulars
private fun loadCirculars() {
object : Thread() {
override fun run() {
_circulars.postValue(AppDatabase.getInstance(getApplication()).circularDao().getCirculars())
updateCirculars()
}
}.start()
}
private fun updateCirculars() {
val fetcher = DataFetcher()
val newCirculars = fetcher.getCircularsFromServer()
if (newCirculars.size != _circulars.value?.size ?: true) {
_circulars.postValue(newCirculars)
AppDatabase.getInstance(getApplication()).circularDao().deleteAll()
AppDatabase.getInstance(getApplication()).circularDao().insertAll(newCirculars)
}
} }
val text: LiveData<String> = _text
} }

View File

@@ -3,8 +3,7 @@
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/container" android:id="@+id/container"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent">
android:paddingTop="?attr/actionBarSize">
<com.google.android.material.bottomnavigation.BottomNavigationView <com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/nav_view" android:id="@+id/nav_view"

View File

@@ -1,6 +1,13 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/circulars_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:layout_editor_absoluteX="168dp"
tools:layout_editor_absoluteY="235dp" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,14 @@
<?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:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:orientation="vertical">
<TextView
android:id="@+id/circular_title_textview"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>