I am unable to use RecyclerView although I had created Adapter(RecyclerView) and ViewHolder(RecyclerView) so I tried using of ListView and it worked for me.
What should I do for converting ListView to RecyclerView?
package com.example.cryptotracker
import android.os.Bundle
import android.util.Log
import android.widget.Adapter
import android.widget.ArrayAdapter
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import kotlinx.android.synthetic.main.activity_main.*
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
var rf : Retrofit = Retrofit.Builder().baseUrl(RetroInterface.BASE_URL)
.addConverterFactory(GsonConverterFactory.create()).build()
var API : RetroInterface = rf.create(RetroInterface::class.java)
var call:Call<List<Crypto?>?>? = API.posts
call?.enqueue(object :Callback<List<Crypto?>?>{
override fun onResponse(
call: Call<List<Crypto?>?>,
response: Response<List<Crypto?>?>
) {
var postList :List<Crypto>? = response.body() as List<Crypto>
var post : Array<String?> = arrayOfNulls<String>(postList!!.size)
for ( i in postList!!.indices)
post[i] = postList!![i]!!.name
var adapter = ArrayAdapter<String>(applicationContext,android.R.layout.simple_dropdown_item_1line,post)
listview.adapter = adapter
}
override fun onFailure(call: Call<List<Crypto?>?>, t: Throwable) {
TODO("Not yet implemented")
}
})
}
}
====================== Adapter & ViewHolder(RecyclerView) ===================
package com.example.cryptotracker
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
class CryptoAdapter(val context:Context, val crypto:List<Crypto> ):RecyclerView.Adapter<CryptoViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CryptoViewHolder {
val view:View = LayoutInflater.from(context).inflate(R.layout.item_crypto,parent,false)
return CryptoViewHolder(view)
}
override fun onBindViewHolder(holder: CryptoViewHolder, position: Int) {
val current_item:Crypto = crypto1[position]
holder.cryptoName.text = current_item.name
holder.cryptoId.text = current_item.exchange
holder.cryptoUrl.text = current_item.website
}
override fun getItemCount(): Int {
return crypto1.size
}
}
class CryptoViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
var cryptoName = itemView.findViewById<TextView>(R.id.cryptoName)
var cryptoId = itemView.findViewById<TextView>(R.id.cryptoExchangeId)
var cryptoUrl = itemView.findViewById<TextView>(R.id.cryptoUrl)
}
============================ Data class ===========================
package com.example.cryptotracker
data class Crypto (
val exchange_id:String,
val name:String,
val website:String,
)
Replace below lines :
var adapter = ArrayAdapter<String>(applicationContext,android.R.layout.simple_dropdown_item_1line,post)
listview.adapter = adapter
With this :
if(postList != null) {
var cryptoAdapter = CryptoAdapter(this#MainActivity,postList)
recyclerview.layoutManager = LinearLayoutManager(this#MainActivity)
recyclerview.adapter = cryptoAdapter
}
Also in CryptoAdapter.kt
override fun getItemCount(): Int {
return crypto.size
}
Related
this project observation internet connectivity ,how i convert code from composablle activity to empty activity what instant of collectAsState for empty activity
get code form video youtube observation internet connectivity video
interface observeconnectivity
package com.plcoding.observeconnectivity
import kotlinx.coroutines.flow.Flow
interface ConnectivityObserver {
fun observe(): Flow<Status>
enum class Status {
Available, Unavailable, Losing, Lost
}
}
observeconnectivity class
package com.plcoding.observeconnectivity
import android.content.Context
import android.net.ConnectivityManager
import android.net.Network
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.callbackFlow
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.launch
#OptIn(ExperimentalCoroutinesApi::class)
class NetworkConnectivityObserver(
private val context: Context
): ConnectivityObserver {
private val connectivityManager =
context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
override fun observe(): Flow<ConnectivityObserver.Status> {
return callbackFlow {
val callback = object : ConnectivityManager.NetworkCallback() {
override fun onAvailable(network: Network) {
super.onAvailable(network)
launch { send(ConnectivityObserver.Status.Available) }
}
override fun onLosing(network: Network, maxMsToLive: Int) {
super.onLosing(network, maxMsToLive)
launch { send(ConnectivityObserver.Status.Losing) }
}
override fun onLost(network: Network) {
super.onLost(network)
launch { send(ConnectivityObserver.Status.Lost) }
}
override fun onUnavailable() {
super.onUnavailable()
launch { send(ConnectivityObserver.Status.Unavailable) }
}
}
connectivityManager.registerDefaultNetworkCallback(callback)
awaitClose {
connectivityManager.unregisterNetworkCallback(callback)
}
}.distinctUntilChanged()
}
}
how convert MainActivity composble activity to empty activity?
package com.plcoding.observeconnectivity
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Surface
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.lifecycle.lifecycleScope
import com.plcoding.observeconnectivity.ui.theme.ObserveConnectivityTheme
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
class MainActivity : ComponentActivity() {
private lateinit var connectivityObserver: ConnectivityObserver
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
connectivityObserver = NetworkConnectivityObserver(applicationContext)
setContent {
ObserveConnectivityTheme {
val status by connectivityObserver.observe().collectAsState(
initial = ConnectivityObserver.Status.Unavailable
)
Box(
modifier = Modifier.fillMaxSize(),
contentAlignment = Alignment.Center
) {
Text(text = "Network status: $status")
}
}
}
}
}
theme.kt
package com.plcoding.observeconnectivity.ui.theme
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.material.MaterialTheme
import androidx.compose.material.darkColors
import androidx.compose.material.lightColors
import androidx.compose.runtime.Composable
private val DarkColorPalette = darkColors(
primary = Purple200,
primaryVariant = Purple700,
secondary = Teal200
)
private val LightColorPalette = lightColors(
primary = Purple500,
primaryVariant = Purple700,
secondary = Teal200
/* Other default colors to override
background = Color.White,
surface = Color.White,
onPrimary = Color.White,
onSecondary = Color.Black,
onBackground = Color.Black,
onSurface = Color.Black,
*/
)
#Composable
fun ObserveConnectivityTheme(
darkTheme: Boolean = isSystemInDarkTheme(),
content: #Composable () -> Unit
) {
val colors = if (darkTheme) {
DarkColorPalette
} else {
LightColorPalette
}
MaterialTheme(
colors = colors,
typography = Typography,
shapes = Shapes,
content = content
)
}
I am using RecyclerView in my app. But I'm getting this error in the Logcat. Here is my Codes;
My Fragment
package com.ahmetkaan.kediy.Fragments
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.widget.SearchView
import androidx.fragment.app.Fragment
import androidx.navigation.Navigation
import androidx.recyclerview.widget.StaggeredGridLayoutManager
import com.ahmetkaan.kediy.R
import com.ahmetkaan.kediy.adapter.NotesAdapter
import com.ahmetkaan.kediy.database.NotesDatabase
import com.ahmetkaan.kediy.databinding.FragmentHomeBinding
import com.ahmetkaan.kediy.entities.Notlar
import kotlinx.coroutines.launch
import java.util.*
import kotlin.collections.ArrayList
class Home : BaseFragment() {
lateinit var binding : FragmentHomeBinding
var arrNotes = ArrayList<Notlar>()
var notesAdapter: NotesAdapter = NotesAdapter()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = FragmentHomeBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.recyclerView.setHasFixedSize(true)
binding.recyclerView.layoutManager = StaggeredGridLayoutManager(2,StaggeredGridLayoutManager.VERTICAL)
launch {
context?.let {
val notes = NotesDatabase.getDatabase(it).noteDao().getAllNotes()
notesAdapter.setData(notes)
arrNotes = notes as ArrayList<Notlar>
binding.recyclerView.adapter = notesAdapter
}
}
binding.searchView.setOnQueryTextListener( object : SearchView.OnQueryTextListener{
override fun onQueryTextSubmit(p0: String?): Boolean {
return true
}
override fun onQueryTextChange(p0: String?): Boolean {
var tempArr = ArrayList<Notlar>()
for (arr in arrNotes){
if (arr.not!!.toLowerCase(Locale.getDefault()).contains(p0.toString())){
tempArr.add(arr)
}
}
notesAdapter.setData(tempArr)
notesAdapter.notifyDataSetChanged()
return true
}
})
notesAdapter.setOnClickListener(onClicked)
binding.notEkle.setOnClickListener {
val action = HomeDirections.actionHome2ToNotOlustur()
Navigation.findNavController(requireActivity(), R.id.fragmentContainerView).navigate(action)
}
binding.calendar.setOnClickListener {
val action = HomeDirections.actionHome2ToCalendar2()
Navigation.findNavController(requireActivity(), R.id.fragmentContainerView).navigate(action)
}
}
private val onClicked = object :NotesAdapter.OnItemClickListener {
override fun onClicked(notesId: Int) {
val fragment: Fragment
val bundle = Bundle()
bundle.putInt("noteId", notesId)
fragment = NotOlustur.newInstance()
fragment.arguments = bundle
val action = HomeDirections.actionHome2ToNotOlustur()
Navigation.findNavController(requireActivity(), R.id.fragmentContainerView)
.navigate(action)
}
}
}
My Adapter
package com.ahmetkaan.kediy.adapter
import android.graphics.BitmapFactory
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.cardview.widget.CardView
import androidx.core.graphics.drawable.toDrawable
import androidx.recyclerview.widget.RecyclerView
import com.ahmetkaan.kediy.R
import com.ahmetkaan.kediy.entities.Notlar
import kotlin.collections.ArrayList
class NotesAdapter() :
RecyclerView.Adapter<NotesAdapter.NotesViewHolder>() {
var listener:OnItemClickListener? = null
var arrList = ArrayList<Notlar>()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): NotesViewHolder {
return NotesViewHolder(
LayoutInflater.from(parent.context).inflate(R.layout.item_notlar,parent,false)
)
}
override fun getItemCount(): Int {
return arrList.size
}
fun setData(arrNotesList: List<Notlar>){
arrList = arrNotesList as ArrayList<Notlar>
}
fun setOnClickListener(listener1: OnItemClickListener){
listener = listener1
}
override fun onBindViewHolder(holder: NotesViewHolder, position: Int) {
holder.itemView.findViewById<TextView>(R.id.theNotC).text = arrList[position].not
holder.itemView.findViewById<TextView>(R.id.dateTimeC).text = arrList[position].dateTime
if (arrList[position].impPathBackground != null){
holder.itemView.findViewById<ImageView>(R.id.backgroundC).setImageBitmap(BitmapFactory.decodeFile(arrList[position].impPathBackground))
} else {
holder.itemView.findViewById<ImageView>(R.id.backgroundC).setImageDrawable(R.drawable.ronin.toDrawable())
}
if (arrList[position].impPathBackground != null){
holder.itemView.findViewById<ImageView>(R.id.backgroundC).setImageBitmap(BitmapFactory.decodeFile(arrList[position].impPathLogo))
} else {
holder.itemView.findViewById<ImageView>(R.id.backgroundC).setImageDrawable(R.drawable.logo1.toDrawable())
}
holder.itemView.findViewById<CardView>(R.id.cardView).setOnClickListener {
listener!!.onClicked(arrList[position].id!!)
}
}
class NotesViewHolder(view:View) : RecyclerView.ViewHolder(view){
}
interface OnItemClickListener{
fun onClicked(noteId:Int)
}
}
I searched a lot on the internet but I didn't understand much because they are all in java language. It didn't work even though I tried what I understood. Unlike others, I used CoroutineScope(launch) I think it was because of it, but I'm not sure. What should i do?
Setting the adapter should be in the main thread. But you wrapped it in launch.
binding.recyclerView.adapter = notesAdapter
I have added a color picker to my simple note app. Right now the problem is when the user clicks to update the note then the background color isn't showing. How can I fix that?
....................................................................................................................................................................................................
Adapter.kt
package com.example.noteapp.ui.Adapter
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.appcompat.view.menu.ActionMenuItemView
import androidx.cardview.widget.CardView
import androidx.navigation.Navigation
import androidx.recyclerview.widget.RecyclerView
import com.example.noteapp.databinding.ItemNotesBinding
import com.example.noteapp.model.Notes
import com.example.noteapp.ui.Fragments.HomeFragment
import com.example.noteapp.ui.Fragments.HomeFragmentDirections
import com.google.android.material.card.MaterialCardView
import io.noties.markwon.AbstractMarkwonPlugin
import io.noties.markwon.Markwon
import io.noties.markwon.MarkwonVisitor
import io.noties.markwon.ext.strikethrough.StrikethroughPlugin
import io.noties.markwon.ext.tasklist.TaskListPlugin
import org.commonmark.node.SoftLineBreak
class NotesAdapter(val requirContext : Context, val notesList : List<Notes>) :
RecyclerView.Adapter<NotesAdapter.notesViewHolder>() {
class notesViewHolder(val binding: ItemNotesBinding) : RecyclerView.ViewHolder(binding.root) {
val content : TextView = binding.notessubtitle
val markwon = Markwon.builder(itemView.context)
.usePlugin(StrikethroughPlugin.create())
.usePlugin(TaskListPlugin.create(itemView.context))
.usePlugin(object : AbstractMarkwonPlugin() {
override fun configureVisitor(builder: MarkwonVisitor.Builder) {
super.configureVisitor(builder)
builder.on(
SoftLineBreak::class.java
){visitor, _ -> visitor.forceNewLine()}
}
})
.build()
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): notesViewHolder {
return notesViewHolder(ItemNotesBinding.inflate(LayoutInflater.from(parent.context),parent,
false
)
)
}
override fun onBindViewHolder(holder: notesViewHolder, position: Int) {
val data = notesList[position]
holder.binding.notestitle.text = data.title
holder.binding.notessubtitle.text = data.notes
holder.binding.noteItemLayoutParent.setCardBackgroundColor(data.color)
holder.binding.noteItemLayoutParent.transitionName="recyclerView_${data.id}"
holder.binding.root.setOnClickListener {
val action = HomeFragmentDirections.actionHomeFragmentToEditnotesFragmemt(data)
Navigation.findNavController(it).navigate(action)
}
}
override fun getItemCount() = notesList.size
}
EditNoteFragment
package com.example.noteapp.ui.Fragments
import android.graphics.Color
import android.os.Bundle
import android.text.format.DateFormat
import android.util.Log
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.core.os.bundleOf
import androidx.core.view.ViewCompat
import androidx.fragment.app.setFragmentResult
import androidx.fragment.app.viewModels
import androidx.navigation.Navigation
import androidx.navigation.fragment.navArgs
import com.example.noteapp.R
import com.example.noteapp.ViewModel.NotesViewModel
import com.example.noteapp.databinding.BottomsheetlayoutBinding
import com.example.noteapp.databinding.FragmentEditnotesFragmemtBinding
import com.example.noteapp.model.Notes
import com.example.noteapp.ui.Adapter.NotesAdapter
import com.example.noteapp.utils.hideKeyboard
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.google.android.material.transition.MaterialContainerTransform
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import java.text.SimpleDateFormat
import java.util.*
class EditnotesFragmemt : Fragment() {
val oldNotes by navArgs<EditnotesFragmemtArgs>()
lateinit var binding : FragmentEditnotesFragmemtBinding
val viewModel : NotesViewModel by viewModels()
private var color = -1
private lateinit var result : String
private val job = CoroutineScope(Dispatchers.Main)
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
binding = FragmentEditnotesFragmemtBinding.inflate(layoutInflater,container,false)
binding.editingedittextnote.setText(oldNotes.data.notes)
binding.editingedittexttitle.setText(oldNotes.data.title)
val animation = MaterialContainerTransform().apply {
drawingViewId = R.id.createFragment
scrimColor = Color.TRANSPARENT
duration = 300L
}
sharedElementEnterTransition=animation
sharedElementReturnTransition=animation
ViewCompat.setTransitionName(
binding.editFragmentxmlid,"recyclerView_${oldNotes.data?.id}"
)
binding.backbutton.setOnClickListener {
requireView().hideKeyboard()
Navigation.findNavController(it).popBackStack()
}
binding.editingedittextnote.setText(oldNotes.data.notes)
binding.editingedittexttitle.setText(oldNotes.data.title)
binding.fabcolorpick.setOnClickListener {
val bottomSheetDialog = BottomSheetDialog(
requireContext(),
R.style.BottomSheetDialogTheme
)
val bottomSheetView : View = layoutInflater.inflate(
R.layout.bottomsheetlayout,
null,
)
val bottomSheetBinding = BottomsheetlayoutBinding.bind(bottomSheetView)
bottomSheetBinding.apply {
colorpicker.apply {
setSelectedColor(color)
setOnColorSelectedListener {
value->
color = value
binding.apply {
editFragmentxmlid.setBackgroundColor(color)
toolbarfragmentnotecontent.setBackgroundColor(color)
bottombar.setBackgroundColor(color)
activity?.window?.statusBarColor = color
}
bottomSheetBinding.bottomSheetparent.setCardBackgroundColor(color)
}
}
bottomSheetparent.setCardBackgroundColor(color)
}
bottomSheetView.post{
bottomSheetDialog.behavior.state = BottomSheetBehavior.STATE_EXPANDED
}
bottomSheetDialog.setContentView(bottomSheetBinding.root)
bottomSheetDialog.show();
}
binding.btneditdonenotes.setOnClickListener {
updateNotes(it)
}
try {
binding.editingedittextnote.setOnFocusChangeListener { _, hasFocus ->
if (hasFocus)
{
binding.bottombar.visibility = View.VISIBLE
binding.editingedittextnote.setStylesBar(binding.styleBar)
}else{
binding.bottombar.visibility = View.GONE
}
}
}catch (e: Throwable) {
Log.d("TAG", e.stackTraceToString())
}
return binding.root
}
private fun updateNotes(it: View?) {
val title = binding.editingedittexttitle.text.toString()
val notes = binding.editingedittextnote.text.toString()
val d = Date()
val notesDate: CharSequence = DateFormat.format("MMM d, yyy ", d.time)
val data = Notes(
oldNotes.data.id,
title = title,
notes = notes,
date = notesDate.toString(),
color= color,
)
binding.apply {
job.launch {
editFragmentxmlid.setBackgroundColor(data.color)
}
toolbarfragmentnotecontent.setBackgroundColor(data.color)
bottombar.setBackgroundColor(data.color)
}
activity?.window?.statusBarColor=data.color
result = "Note Saved"
setFragmentResult(
"key",
bundleOf("bundleKey" to result)
)
viewModel.updateNotes(data)
Toast.makeText(context, "Edit Note Successfully", Toast.LENGTH_SHORT).show()
Navigation.findNavController(it!!).navigate(R.id.action_editnotesFragmemt_to_homeFragment)
}
}
sorry for the inconvenience, but this is my first time trying this. I've been trying on doing this app which it has a recyclerView which I intent it to open a chrome page. The thing is, I'm not able to implement the itemOnClickListener despite having tried a lot of videos. Could you point out where is my mistake?
My Adapter:
package com.example.practica1.adapter
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.core.content.ContentProviderCompat.requireContext
import androidx.fragment.app.FragmentActivity
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.example.practica1.R
import com.example.practica1.data.Video
class MainAdapter(private val context: Context, private val videos: List<Video>,
val listener: MyOnClickListener
): RecyclerView.Adapter<MainAdapter.ViewHolder>(){
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MainAdapter.ViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_cartoon, parent, false)
return ViewHolder(view)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val video = videos[position]
holder.title.text = video.data.short_title
holder.serieTitle.text = video.data.show.title
holder.durationTitle.text = video.data.video.duration + " seg"
Glide.with(context)
.load(video.data.imagepath)
.diskCacheStrategy(DiskCacheStrategy.ALL)
.override(400, 400)
.centerCrop()
.into(holder.imagePrev)
}
override fun getItemCount() = videos.size
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView){
val title: TextView = itemView.findViewById(R.id.videoTitle)
val serieTitle: TextView = itemView.findViewById(R.id.serieTitle)
val durationTitle: TextView = itemView.findViewById(R.id.durationTitle)
val imagePrev: ImageView = itemView.findViewById(R.id.photoPreview)
init{
itemView.setOnClickListener{
val position = adapterPosition
listener.onClick(position)
}
}
}
interface MyOnClickListener{
fun onClick(position: Int)
}
}
The fragment in which I tried to implement the method (The toast message doesn't appear)
package com.example.practica1.fragments
import android.os.Bundle
import android.util.Log
import android.util.Log.d
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.fragment.app.Fragment
import androidx.navigation.Navigation
import androidx.recyclerview.widget.RecyclerView
import com.example.practica1.R
import com.example.practica1.adapter.MainAdapter
import com.example.practica1.data.ApiInterface
import com.example.practica1.data.Video
import com.example.practica1.databinding.FragmentMenuBinding
import com.haerul.bottomfluxdialog.BottomFluxDialog
import com.haerul.bottomfluxdialog.BottomFluxDialog.OnInputListener
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
class MenuFragment : Fragment() {
private var _binding: FragmentMenuBinding? = null
private val binding get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
_binding = FragmentMenuBinding.inflate(inflater, container, false)
val view = inflater.inflate(R.layout.fragment_menu, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val retrofit = Retrofit.Builder()
.baseUrl("https://www.cartoonnetwork.com.co")
.addConverterFactory(GsonConverterFactory.create())
.build()
val api = retrofit.create(ApiInterface::class.java)
showProgress()
api.fetchAllVideos().enqueue(object : Callback<List<Video>> {
override fun onResponse(call: Call<List<Video>>, response: Response<List<Video>>) {
if (response.isSuccessful()) {
d("daniel", "onResponse ${response.body()!![0].id}")
if (response.body()!!.size > 0) {
showData(response.body()!!)
getResult(true, "Sucess")
} else
getResult(false, response.message())
hideProgress()
}
}
override fun onFailure(call: Call<List<Video>>, t: Throwable) {
d("daniel", "onFailure")
getResult(false, "Request Timeout. Please Try Again!")
hideProgress()
}
})
binding.search.setOnClickListener { v -> showDialog(v) }
}
fun showData(videos: List<Video>){
val test: RecyclerView = requireActivity().findViewById(R.id.recycler_viewMenu)
test.apply{
adapter = MainAdapter(context, videos, object: MainAdapter.MyOnClickListener{
override fun onClick(position: Int) {
Toast.makeText(requireContext(), position, Toast.LENGTH_SHORT).show()
}
})
}
}
fun showProgress(){
binding.swipeRefresh.setRefreshing(true)
binding.emptyView.setVisibility(View.GONE)
binding.shimmer.startShimmer()
binding.shimmer.setVisibility(View.VISIBLE)
binding.recyclerViewMenu.setVisibility(View.GONE)
}
fun hideProgress(){
binding.swipeRefresh.setRefreshing(false)
binding.shimmer.stopShimmer()
binding.shimmer.setVisibility(View.GONE)
binding.recyclerViewMenu.setVisibility(View.VISIBLE)
}
fun getResult(status: Boolean, message: String){
if(!status) {
binding.emptyView.setVisibility(View.VISIBLE)
binding.textEmptyErr.setText(message)
}
else
binding.emptyView.setVisibility((View.GONE))
}
private fun showDialog(view: View){
BottomFluxDialog.inputDialog(requireActivity())
.setTextTitle("Input Title")
.setTextMessage("This is an input message")
.setRightButtonText("SUBMIT")
.setInputListener(object : OnInputListener {
override fun onSubmitInput(text: String?) {
val bundle = Bundle()
bundle.putString("search", text)
Navigation.findNavController(view)
.navigate(R.id.action_menuFragment_to_listFragment, bundle)
}
override fun onCancelInput() {}
})
.show()
}
}
Thanks!
If your data is showing in the recycler view and you are getting crash on item click than
replace this toast link :-
Toast.makeText(requireContext(), position, Toast.LENGTH_SHORT).show()
with this :-
Toast.makeText(requireContext(), "$position", Toast.LENGTH_SHORT).show()
or if your video list is not visible in recycler view than you need to implement layout manager in recycler view you can add it on xml or in code also.
I want to share variable : master between MainActivity to ListAdapter. Can you tell me how to do it ? I tried with bundles and a lot of things, but in the end I received errors.
Main Activity
package com.example.roomapp
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import androidx.fragment.app.Fragment
import androidx.navigation.findNavController
import androidx.navigation.ui.setupActionBarWithNavController
import com.example.roomapp.AESKnowledgeFcatory.decrypt
import com.example.roomapp.HashUtils.sha256
import com.example.roomapp.fragments.add.AddFragment
import kotlinx.android.synthetic.main.activitycreate.*
import kotlinx.android.synthetic.main.activitylogin.*
import kotlinx.android.synthetic.main.custom_row.*
import kotlin.properties.ReadOnlyProperty
import kotlin.reflect.KProperty
class MainActivity : AppCompatActivity() {
var master: String = "0"
var checkLogin2: String = ""
var lf_ch = false
fun createMaster(v:View){
this.master = this.editmasterpass.text.toString()
val sharedPref = this.getPreferences(MODE_PRIVATE) ?:return
with (sharedPref.edit()){
putString("cheie",sha256(master))
commit()
}
val sharedPref2 = this.getPreferences(MODE_PRIVATE) ?: return
val defaultValue = sharedPref2.getString("cheie", "ABA")
System.out.println(" Key value = " + defaultValue)
setContentView(R.layout.activity_main)
}
fun checklogin(v: View)
{
this.checkLogin2 = this.editTextTextPassword.text.toString()
val castoras = this.getPreferences(MODE_PRIVATE)
val defaultValue2 = castoras.getString("cheie", "ABA")
if(sha256(this.checkLogin2)==defaultValue2.toString())
{
setContentView(R.layout.activity_main)
}
else {
textView3.text="Incorrect Password"
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val castoras = this.getPreferences(MODE_PRIVATE)
val defaultValue2 = castoras.getString("cheie", "key not found")
System.out.println("Abracanabra= "+defaultValue2.toString())
if ((defaultValue2.toString())=="key not found") {
setContentView(R.layout.activitycreate)
}
else {
setContentView((R.layout.activitylogin))
}
}
override fun onSupportNavigateUp(): Boolean {
val navController = findNavController(R.id.fragment)
return navController.navigateUp() || super.onSupportNavigateUp()
}
// cum sa pasam variabila master
}
ListAdapter
package com.example.roomapp.fragments.list
import android.app.PendingIntent.getActivity
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.example.roomapp.AESKnowledgeFcatory.encrypt
import com.example.roomapp.R
import com.example.roomapp.data.User
import kotlinx.android.synthetic.main.custom_row.view.*
import android.content.SharedPreferences
import com.example.roomapp.MainActivity
class ListAdapter: RecyclerView.Adapter<ListAdapter.MyViewHolder>() {
private var userList = emptyList<User>()
class MyViewHolder(itemView: View): RecyclerView.ViewHolder(itemView) {}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
return MyViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.custom_row, parent, false))
}
override fun getItemCount(): Int {
return userList.size
}
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
val currentItem = userList[position]
holder.itemView.id_txt.text = currentItem.id.toString()
holder.itemView.firstName_txt.text = currentItem.firstName
// I want to use the master string here, master+currentItem.salt
holder.itemView.lastName_txt.text = encrypt(currentItem.lastName,currentItem.salt)
holder.itemView.salt_txt.text = currentItem.salt
}
fun setData(user: List<User>){
this.userList = user
notifyDataSetChanged()
}
}
I need a method that can pass me the "master" variable to ListAdapter, because I need to pass certain informations.
List fragment
package com.example.roomapp.fragments.list
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.LinearLayoutManager
import com.example.roomapp.R
import com.example.roomapp.data.UserViewModel
import kotlinx.android.synthetic.main.fragment_list.view.*
class ListFragment() : Fragment() {
private lateinit var mUserViewModel: UserViewModel
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
val view = inflater.inflate(R.layout.fragment_list, container, false)
// Recyclerview
val adapter = ListAdapter()
val recyclerView = view.recyclerview
recyclerView.adapter = adapter
recyclerView.layoutManager = LinearLayoutManager(requireContext())
// UserViewModel
mUserViewModel = ViewModelProvider(this).get(UserViewModel::class.java)
mUserViewModel.readAllData.observe(viewLifecycleOwner, Observer { user ->
adapter.setData(user)
})
view.floatingActionButton.setOnClickListener {
findNavController().navigate(R.id.action_listFragment_to_addFragment)
}
return view
}
}
You can simply add a constructor parameter in your ListAdapter and pass the value of master string when creating the ListAdapter in MainActivity, this can be done as
class ListAdapter(private val master: String):
RecyclerView.Adapter<ListAdapter.MyViewHolder>()
and in your MainActivity, where you create object of ListAdapter, pass the value of master
listAdapter = ListAdapter(master)
Now you can use master in your ListAdapter as you like