From 131dc7aa08da1427a519c8a78a8105ea3da6b87a Mon Sep 17 00:00:00 2001 From: Jarne Demeulemeester Date: Thu, 3 Jun 2021 17:46:10 +0200 Subject: [PATCH] Add Server Select layout with RecyclerView --- app/build.gradle | 3 +- .../dev/jdtech/jellyfin/AddServerFragment.kt | 5 +- .../dev/jdtech/jellyfin/BindingAdapters.kt | 12 ++ .../dev/jdtech/jellyfin/database/Server.kt | 9 ++ .../serverselect/ServerGridAdapter.kt | 49 ++++++++ .../serverselect/ServerSelectFragment.kt | 33 ++++++ .../serverselect/ServerSelectViewModel.kt | 19 +++ app/src/main/res/drawable/server_add_icon.xml | 11 ++ .../main/res/layout/fragment_add_server.xml | 111 +++++++++--------- app/src/main/res/layout/fragment_login.xml | 3 +- .../res/layout/fragment_server_select.xml | 80 +++++++++++++ app/src/main/res/layout/server_item.xml | 46 ++++++++ app/src/main/res/navigation/navigation.xml | 14 ++- app/src/main/res/values/strings.xml | 2 + app/src/main/res/values/styles.xml | 4 + 15 files changed, 340 insertions(+), 61 deletions(-) create mode 100644 app/src/main/java/dev/jdtech/jellyfin/BindingAdapters.kt create mode 100644 app/src/main/java/dev/jdtech/jellyfin/database/Server.kt create mode 100644 app/src/main/java/dev/jdtech/jellyfin/serverselect/ServerGridAdapter.kt create mode 100644 app/src/main/java/dev/jdtech/jellyfin/serverselect/ServerSelectFragment.kt create mode 100644 app/src/main/java/dev/jdtech/jellyfin/serverselect/ServerSelectViewModel.kt create mode 100644 app/src/main/res/drawable/server_add_icon.xml create mode 100644 app/src/main/res/layout/fragment_server_select.xml create mode 100644 app/src/main/res/layout/server_item.xml diff --git a/app/build.gradle b/app/build.gradle index b43fceeb..98a6ce08 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,6 +1,7 @@ plugins { id 'com.android.application' id 'kotlin-android' + id 'org.jetbrains.kotlin.kapt' } android { @@ -32,7 +33,7 @@ android { } buildFeatures { - viewBinding true + dataBinding true } } diff --git a/app/src/main/java/dev/jdtech/jellyfin/AddServerFragment.kt b/app/src/main/java/dev/jdtech/jellyfin/AddServerFragment.kt index 0b8fe765..2c741e6d 100644 --- a/app/src/main/java/dev/jdtech/jellyfin/AddServerFragment.kt +++ b/app/src/main/java/dev/jdtech/jellyfin/AddServerFragment.kt @@ -15,14 +15,13 @@ class AddServerFragment : Fragment() { override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? - ): View? { + ): View { _binding = FragmentAddServerBinding.inflate(inflater, container, false) - val view = binding.root binding.buttonConnect.setOnClickListener { v: View -> v.findNavController().navigate(R.id.action_addServerFragment_to_loginFragment) } - return view + return binding.root } } \ No newline at end of file diff --git a/app/src/main/java/dev/jdtech/jellyfin/BindingAdapters.kt b/app/src/main/java/dev/jdtech/jellyfin/BindingAdapters.kt new file mode 100644 index 00000000..4e828e89 --- /dev/null +++ b/app/src/main/java/dev/jdtech/jellyfin/BindingAdapters.kt @@ -0,0 +1,12 @@ +package dev.jdtech.jellyfin + +import androidx.databinding.BindingAdapter +import androidx.recyclerview.widget.RecyclerView +import dev.jdtech.jellyfin.database.Server +import dev.jdtech.jellyfin.serverselect.ServerGridAdapter + +@BindingAdapter("listData") +fun bindRecyclerView(recyclerView: RecyclerView, data: List?) { + val adapter = recyclerView.adapter as ServerGridAdapter + adapter.submitList(data) +} \ No newline at end of file diff --git a/app/src/main/java/dev/jdtech/jellyfin/database/Server.kt b/app/src/main/java/dev/jdtech/jellyfin/database/Server.kt new file mode 100644 index 00000000..54f44263 --- /dev/null +++ b/app/src/main/java/dev/jdtech/jellyfin/database/Server.kt @@ -0,0 +1,9 @@ +package dev.jdtech.jellyfin.database + +import java.util.* + +data class Server( + val id: UUID, + val name: String, + val address: String +) \ No newline at end of file diff --git a/app/src/main/java/dev/jdtech/jellyfin/serverselect/ServerGridAdapter.kt b/app/src/main/java/dev/jdtech/jellyfin/serverselect/ServerGridAdapter.kt new file mode 100644 index 00000000..f728bad3 --- /dev/null +++ b/app/src/main/java/dev/jdtech/jellyfin/serverselect/ServerGridAdapter.kt @@ -0,0 +1,49 @@ +package dev.jdtech.jellyfin.serverselect + +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.recyclerview.widget.DiffUtil +import androidx.recyclerview.widget.ListAdapter +import androidx.recyclerview.widget.RecyclerView +import dev.jdtech.jellyfin.database.Server +import dev.jdtech.jellyfin.databinding.ServerItemBinding + +class ServerGridAdapter(val onClickListener: OnClickListener) : + ListAdapter(DiffCallback) { + class ServerViewHolder(private var binding: ServerItemBinding) : + RecyclerView.ViewHolder(binding.root) { + fun bind(server: Server) { + binding.server = server + binding.executePendingBindings() + } + } + + companion object DiffCallback : DiffUtil.ItemCallback() { + override fun areItemsTheSame(oldItem: Server, newItem: Server): Boolean { + return oldItem.id == newItem.id + } + + override fun areContentsTheSame(oldItem: Server, newItem: Server): Boolean { + return oldItem == newItem + } + } + + override fun onCreateViewHolder( + parent: ViewGroup, + viewType: Int + ): ServerGridAdapter.ServerViewHolder { + return ServerViewHolder(ServerItemBinding.inflate(LayoutInflater.from(parent.context))) + } + + override fun onBindViewHolder(holder: ServerGridAdapter.ServerViewHolder, position: Int) { + val server = getItem(position) + holder.itemView.setOnClickListener { + onClickListener.onClick(server) + } + holder.bind(server) + } + + class OnClickListener(val clickListener: (server: Server) -> Unit) { + fun onClick(server: Server) = clickListener(server) + } +} \ No newline at end of file diff --git a/app/src/main/java/dev/jdtech/jellyfin/serverselect/ServerSelectFragment.kt b/app/src/main/java/dev/jdtech/jellyfin/serverselect/ServerSelectFragment.kt new file mode 100644 index 00000000..cb11fe75 --- /dev/null +++ b/app/src/main/java/dev/jdtech/jellyfin/serverselect/ServerSelectFragment.kt @@ -0,0 +1,33 @@ +package dev.jdtech.jellyfin.serverselect + +import android.os.Bundle +import androidx.fragment.app.Fragment +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.lifecycle.ViewModelProvider +import androidx.navigation.fragment.findNavController +import dev.jdtech.jellyfin.R +import dev.jdtech.jellyfin.databinding.FragmentServerSelectBinding + + +class ServerSelectFragment : Fragment() { + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + val binding = FragmentServerSelectBinding.inflate(inflater) + + val viewModel = ViewModelProvider(this).get(ServerSelectViewModel::class.java) + + binding.lifecycleOwner = this + binding.viewModel = viewModel + binding.serversRecyclerView.adapter = ServerGridAdapter(ServerGridAdapter.OnClickListener { + }) + + binding.buttonAddServer.setOnClickListener { + this.findNavController().navigate(R.id.action_serverSelectFragment_to_addServerFragment) + } + return binding.root + } +} \ No newline at end of file diff --git a/app/src/main/java/dev/jdtech/jellyfin/serverselect/ServerSelectViewModel.kt b/app/src/main/java/dev/jdtech/jellyfin/serverselect/ServerSelectViewModel.kt new file mode 100644 index 00000000..51f1b8f2 --- /dev/null +++ b/app/src/main/java/dev/jdtech/jellyfin/serverselect/ServerSelectViewModel.kt @@ -0,0 +1,19 @@ +package dev.jdtech.jellyfin.serverselect + +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import dev.jdtech.jellyfin.database.Server +import java.util.* + +class ServerSelectViewModel : ViewModel() { + private val _servers = MutableLiveData>() + val servers: LiveData> + get() = _servers + + init { + val server = Server(UUID.randomUUID(), "JDTech", "https://jellyfin.jdtech.dev") + val demoServer = Server(UUID.randomUUID(), "Demo", "https://demo.jellyfin.org") + _servers.value = listOf(server, demoServer) + } +} \ No newline at end of file diff --git a/app/src/main/res/drawable/server_add_icon.xml b/app/src/main/res/drawable/server_add_icon.xml new file mode 100644 index 00000000..71645176 --- /dev/null +++ b/app/src/main/res/drawable/server_add_icon.xml @@ -0,0 +1,11 @@ + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_add_server.xml b/app/src/main/res/layout/fragment_add_server.xml index 5f791ac7..fce1fa49 100644 --- a/app/src/main/res/layout/fragment_add_server.xml +++ b/app/src/main/res/layout/fragment_add_server.xml @@ -1,63 +1,66 @@ - + xmlns:tools="http://schemas.android.com/tools"> - - - - + android:layout_height="match_parent" + tools:context=".AddServerFragment"> - - + + + android:layout_marginStart="24dp" + android:layout_marginEnd="24dp" + android:orientation="vertical" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/image_banner" + app:layout_constraintVertical_bias="0.36"> -