How to detect a swipe without detecting a tap in kotlin - android-studio

I have been programming an app in kotlin. This app allows a user to swipe through an imageView and plays a sound when a user taps the screen. The onSwipeTouchListener class below is the onTouchListener for my imageView. I am using the onSwipeTouchListener to also listen for taps so that the app can play a sound when the user taps the screen. The issue is when a user swipes, the program detects a tap as well as a swipe. This results in the app playing a sound when it is not supposed to.
If someone could help me with this bug I'd much appreciate it.
here is my code:
package com.example.articulate_r
import android.animation.Animator
import android.content.Context
import android.media.MediaPlayer
import android.net.Uri
import android.view.GestureDetector
import android.view.MotionEvent
import android.view.View
import android.widget.ImageView
import android.widget.TextView
open class OnSwipeTouchListener(
private val ctx: Context,
private val imageView: ImageView,
private val textView: TextView,
private val firstAnimatorRight: Animator,
private val secondAnimatorRight: Animator,
private val firstAnimatorLeft: Animator,
private val secondAnimatorLeft: Animator
) : View.OnTouchListener {
private val gestureDetector: GestureDetector
companion object {
private val SWIPE_THRESHOLD = 100
private val SWIPE_VELOCITY_THRESHOLD = 100
}
init {
gestureDetector = GestureDetector(ctx, GestureListener())
}
override fun onTouch(v: View, event: MotionEvent): Boolean {
return gestureDetector.onTouchEvent(event)
}
private inner class GestureListener : GestureDetector.SimpleOnGestureListener() {
lateinit private var audioPlayer1 : MediaPlayer
override fun onDown(e: MotionEvent): Boolean {
playAudio(audioFiles[counter])
return true
}
override fun onFling(
e1: MotionEvent,
e2: MotionEvent,
velocityX: Float,
velocityY: Float
): Boolean {
var result = false
try {
val diffX = e2.x - e1.x
if (Math.abs(diffX) > SWIPE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) {
if (diffX > 0) {
onSwipeRight()
} else {
onSwipeLeft()
}
result = true
}
} catch (exception: Exception) {
exception.printStackTrace()
}
return result
}
}
var images = arrayOf(R.drawable.minecow, R.drawable.minepig,R.drawable.minechick)
var imageNames = arrayOf("Cows", "Pigs", "Chickens")
var audioFiles = arrayOf(R.raw.cows_and, R.raw.pigs_and, R.raw.chickens_and)
var counter = 0
open fun onSwipeRight() {
println("swiped right")
if (counter == 0) {
counter = images.size - 1
}
else {
counter--
}
animateRight(images[counter])
textView.text = imageNames[counter]
println(counter)
}
open fun onSwipeLeft() {
println("swiped left")
if (counter == images.size - 1) {
counter = 0
}
else {
counter++
}
animateLeft(images[counter])
textView.text = imageNames[counter]
println(counter)
}
private fun playAudio(audioFile: Int) {
var audioPlayer = MediaPlayer.create(ctx, audioFile)
audioPlayer.setVolume(100f,100f)
audioPlayer.start()
}
private fun animateLeft(drawableImage: Int) {
firstAnimatorLeft.setTarget(imageView)
secondAnimatorLeft.setTarget(imageView)
firstAnimatorLeft.setDuration(250)
secondAnimatorLeft.setDuration(250)
firstAnimatorLeft.start()
firstAnimatorLeft.addListener(
object : Animator.AnimatorListener {
override fun onAnimationStart(animation: Animator) {
}
override fun onAnimationEnd(animation: Animator) {
imageView.setImageDrawable(ctx.getDrawable(drawableImage))
secondAnimatorLeft.start()
}
override fun onAnimationCancel(animation: Animator) {}
override fun onAnimationRepeat(p0: Animator?) {}
}
)
}
private fun animateRight(drawableImage: Int) {
firstAnimatorRight.setTarget(imageView)
secondAnimatorRight.setTarget(imageView)
firstAnimatorRight.setDuration(250)
secondAnimatorRight.setDuration(250)
firstAnimatorRight.start()
firstAnimatorRight.addListener(
object : Animator.AnimatorListener {
override fun onAnimationStart(animation: Animator) {
}
override fun onAnimationEnd(animation: Animator) {
imageView.setImageDrawable(ctx.getDrawable(drawableImage))
secondAnimatorRight.start()
}
override fun onAnimationCancel(animation: Animator) {}
override fun onAnimationRepeat(p0: Animator?) {}
}
)
}
}

Related

Firebase Realtime Database images are not showing up in fragment kotlin class

I'm trying to show images from my Firebase Realtime Database storage. I've done this before with a previous version of my app, but the difference is how I implemented it. My adapter and arraylist class are exactly the same, but instead of using an activity I switched to using fragments.
What I essentially did was copy my old work and make the appropriate changes so I wouldn't run into errors, but unfortunately I ran into some. My images from Firebase are not showing up at all and I'm not sure what is the problem.
Adapter Class
class AbstractAdapter(private val mContext: Context, private val abstractList: ArrayList<Abstract>) : RecyclerView.Adapter<AbstractAdapter.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.abstract_image_view, parent, false)
return ViewHolder(view)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
Glide.with(mContext)
.load(abstractList[position].abstract)
.into(holder.imageView)
}
override fun getItemCount(): Int {
return abstractList.size
}
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
var imageView: ImageView = itemView.findViewById(R.id.abstractImageView)
}
companion object {
private const val Tag = "RecyclerView"
}
}
Data class
class Abstract {
var abstract: String? = null
constructor() {}
constructor(abstract: String?) {
this.abstract = abstract
}
}
Fragment in which images will be shown
class AbstractWallpapers: Fragment(), PurchasesUpdatedListener {
private lateinit var subscribeAbstract: Button
private var billingClient: BillingClient? = null
lateinit var recyclerView: RecyclerView
lateinit var abstractlist: ArrayList<Abstract>
private var recyclerAdapterAbstract: AbstractAdapter? = null
private var myRef3: DatabaseReference? = null
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_abstract_wallpaper, container, false)
recyclerView = requireView().findViewById(R.id.abstract_recyclerView)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
recyclerView = view.findViewById(R.id.abstract_recyclerView)
val layoutManager = LinearLayoutManager(requireActivity())
recyclerView.layoutManager = layoutManager
recyclerView.setHasFixedSize(true)
myRef3 = FirebaseDatabase.getInstance().reference
abstractlist = ArrayList()
ClearAll()
GetDataFromFirebase()
subscribeAbstract = view.findViewById(R.id.abstract_subscribe_btn)
subscribeAbstract.setOnClickListener {
subscribeAbstract()
}
// Establish connection to billing client
//check subscription status from google play store cache
//to check if item is already Subscribed or subscription is not renewed and cancelled
billingClient = BillingClient.newBuilder(requireActivity()).enablePendingPurchases().setListener(this).build()
billingClient!!.startConnection(object : BillingClientStateListener {
override fun onBillingSetupFinished(billingResult: BillingResult) {
if (billingResult.responseCode == BillingClient.BillingResponseCode.OK) {
val queryPurchase = billingClient!!.queryPurchases(BillingClient.SkuType.SUBS)
val queryPurchases = queryPurchase.purchasesList
if (queryPurchases != null && queryPurchases.size > 0) {
handlePurchases(queryPurchases)
} else {
saveSubscribeValueToPref(false)
}
}
}
override fun onBillingServiceDisconnected() {
Toast.makeText(requireActivity(), "Service Disconnected", Toast.LENGTH_SHORT).show()
}
})
//item subscribed
if (subscribeValueFromPref) {
subscribeAbstract.visibility = View.GONE
} else {
subscribeAbstract.visibility = View.VISIBLE
}
}
// Code related to Firebase
#SuppressLint("NotifyDataSetChanged")
private fun GetDataFromFirebase() {
val query: Query = myRef3!!.child("Abstract")
query.addListenerForSingleValueEvent(object : ValueEventListener {
#SuppressLint("NotifyDataSetChanged")
override fun onDataChange(snapshot: DataSnapshot) {
for (dataSnapshot: DataSnapshot in snapshot.children) {
val abstract = Abstract()
abstract.abstract = dataSnapshot.child("abstract").value.toString()
abstractlist.add(abstract)
}
recyclerAdapterAbstract = abstractlist.let { AbstractAdapter(requireActivity(), it) }
recyclerView.adapter = recyclerAdapterAbstract
recyclerAdapterAbstract!!.notifyDataSetChanged()
}
override fun onCancelled(error: DatabaseError) {}
})
if (recyclerAdapterAbstract != null) recyclerAdapterAbstract!!.notifyDataSetChanged()
}
private fun ClearAll() {
abstractlist.clear()
abstractlist = ArrayList()
}
I fixed my problem. It turns out my rules in Firebase Realtime Database rules for read were set to false instead. My code works perfect. It was only a stupid error on my part.

rest Daily step counter android

`Hello friends, good morning. What should I do to restart the pedometer? I saw many samples, but what they all had in common was to click on the desired view to restart the pedometer. But I do not want that to happen. The number of steps should be 0 every 24 hours. My codes:
Thanks for the code to explain
class Home : Fragment(), SensorEventListener {
lateinit var binding: FragmentHomeBinding
private var sensorManager: SensorManager? = null
private var running = false
private var totalStep = 0f
private var previousTotalStep = 0f
//
private lateinit var mHandler: Handler
private var calories = 0.0
val todayDate: String = DateFormat.getDateInstance(DateFormat.MEDIUM).format(Date())
val dateForCalories = "$todayDate-kcal"
override fun onResume() {
super.onResume()
running = true
val stepSensor = sensorManager?.getDefaultSensor(Sensor.TYPE_STEP_COUNTER)
sensorManager?.registerListener(this, stepSensor, SensorManager.SENSOR_DELAY_UI)
}
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)
//load View model
detailsViewModel.messageTodayLiveData.observe(viewLifecycleOwner) {
binding.homeLayout.messageDay.text = it.message
}
materialDrawer()
loadData()
resetSteps()
calculateCalories()
sensorManager = requireContext().getSystemService(Context.SENSOR_SERVICE) as SensorManager
}
private fun resetSteps() {
}
private fun saveDate() {
Constant.editor(requireContext()).putFloat(STEPNUMBER, previousTotalStep).apply()
}
private fun loadData() {
previousTotalStep = Constant.getSharePref(requireContext()).getFloat(STEPNUMBER, 0f)
}
override fun onSensorChanged(event: SensorEvent?) {
if (running)
totalStep = event!!.values[0]
val currentSteps = totalStep.toInt() - previousTotalStep.toInt()
binding.homeLayout.txtSteps.text = ("$currentSteps")
binding.homeLayout.txtKilometers.text =
String.format(getString(R.string.meters_today), stepsToMeters(currentSteps))
binding.homeLayout.progressStep.apply {
setProgressWithAnimation(currentSteps.toFloat())
}
}
override fun onAccuracyChanged(p0: Sensor?, p1: Int) {
}
}
Service codes
class MyService : Service(), SensorEventListener {
private var sensorManager: SensorManager? = null
private var running = false
private var totalStep = 0f
private var previousTotalStep = 0f
val todayDate: String = DateFormat.getDateInstance(DateFormat.MEDIUM).format(Date())
private lateinit var sharedPref: SharedPreferences
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
try {
running = true
val stepSensor = sensorManager?.getDefaultSensor(Sensor.TYPE_STEP_COUNTER)
sensorManager?.registerListener(this, stepSensor, SensorManager.SENSOR_DELAY_UI)
} catch (e: Exception) {
}
return START_STICKY
}
override fun onBind(p0: Intent?): IBinder? {
return null
}
override fun onSensorChanged(event: SensorEvent?) {
if (running) {
totalStep = event!!.values[0]
val currentSteps = totalStep.toInt() - previousTotalStep.toInt()
Constant.editor(this).putFloat(STEPNUMBER, previousTotalStep).apply()
}
}
override fun onAccuracyChanged(p0: Sensor?, p1: Int) {
TODO("Not yet implemented")
}
override fun stopService(name: Intent?): Boolean {
return super.stopService(name)
}
override fun onDestroy() {
val intent = Intent(this, MyPhoneReceiver::class.java)
sendBroadcast(intent)
super.onDestroy()
}
}
Broadcast codes
class MyPhoneReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
if (intent.action?.equals(Intent.ACTION_BOOT_COMPLETED, ignoreCase = true) == true) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context.startForegroundService(Intent(context, MyService::class.java))
} else {
context.startService(Intent(context, MyService::class.java))
}
}
}
}

How To Show Interstitial Ads in The getView Function in Kotlin?

I'm a Beginner in Kotlin and I want a way to display Interstitial Ad every time I click on the button tvName, but on the contrary, the app crashes whenever I click on the button. I searched for the solution for a long time.
Here's MainActivity
import ...
#Suppress("UNREACHABLE_CODE")
class MainActivity : AppCompatActivity() {
lateinit var mAdView : AdView
var adapter:ChaptersAdapter?=null
var listOfChapters= ArrayList<Chapters>()
#SuppressLint("WrongViewCast")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
MobileAds.initialize(this) {}
mAdView = findViewById(R.id.adView)
val adRequest = AdRequest.Builder().build()
mAdView.loadAd(adRequest)
loadChapters()
adapter = ChaptersAdapter(listOfChapters, this)
lvchapters.adapter = adapter
MobileAds.initialize(this,
"ca-app-pub-3940256099942544~3347511713")
mInterstitialAd = InterstitialAd(this)
mInterstitialAd.adUnitId = "ca-app-pub-3940256099942544/1033173712"
mInterstitialAd.loadAd(AdRequest.Builder().build())
}
fun loadChapters(){
listOfChapters.add(Chapters(" Chapter 1 ", applicationContext.assets.open("Chapter0.txt").bufferedReader().use {
it.readText()
}
))
listOfChapters.add(Chapters(" Chapter 2 ", applicationContext.assets.open("Chapter1.txt").bufferedReader().use {
it.readText()
}
))
}
class ChaptersAdapter: BaseAdapter {
var context:Context?=null
var listOfChaptersLocal= ArrayList<Chapters>()
constructor(listOfChapters:ArrayList<Chapters>,context:Context){
listOfChaptersLocal=listOfChapters
this.context=context
}
override fun getView(p0: Int, p1: View?, p2: ViewGroup?): View {
val chapters= listOfChaptersLocal[p0]
var inflator= context!!.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
val chaptersView=inflator.inflate(R.layout.list_chapters,null)
chaptersView.tvName.text= chapters.name!!
chaptersView.**tvName.setOnClickListener** {
// **i want to show the Ads in this time frame** but like this example it didn't work
if (mInterstitialAd.isLoaded) {
mInterstitialAd.show()
} else {
Log.d("TAG", "The interstitial wasn't loaded yet.")
}
val intent =Intent(context,ChapterDetails::class.java)
intent.putExtra("name",chapters.name!!)
intent.putExtra("des",chapters.des!!)
context!!.startActivity(intent)
}
return chaptersView
}
override fun getItem(p0: Int): Any {
return listOfChaptersLocal[p0]
}
override fun getItemId(p0: Int): Long {
return p0.toLong()
}
override fun getCount(): Int {
return listOfChaptersLocal.size
}
}
}

android crash error: java.lang.IllegalStateException

I have a home dash board activity containing navigation view. when the app starts it behaves normally. but when i try to click on navigation menu and open notes my app crashes showing this error message.
java.lang.IllegalStateException: Fragment NoteFragment not attached to a context
Below is my code regarding this. the exception occurs when trying to add LinearLayoutManager to recycler view in noteFragment
/**
* Fundoo Notes
* #description HomeDashBoardActivity displays all user actions.
* #file HomeDashBoardActivity.kt
* #author ksoundarya4
* #version 1.0
* #since 07/02/2020
*/
package com.bridgelabz.fundoonotes.note_module.dashboard_page.view
import android.content.Context
import android.content.Intent
import android.content.SharedPreferences
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import androidx.appcompat.app.ActionBarDrawerToggle
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.Toolbar
import androidx.drawerlayout.widget.DrawerLayout
import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import com.bridgelabz.fundoonotes.R
import com.bridgelabz.fundoonotes.label_module.view.LabelFragment
import com.bridgelabz.fundoonotes.note_module.dashboard_page.model.Note
import com.bridgelabz.fundoonotes.note_module.dashboard_page.viewmodel.DashBoardViewModel
import com.bridgelabz.fundoonotes.note_module.dashboard_page.viewmodel.DashBoardViewModelFactory
import com.bridgelabz.fundoonotes.note_module.note_page.view.AddNoteFragment
import com.bridgelabz.fundoonotes.repository.local_service.DatabaseHelper
import com.bridgelabz.fundoonotes.user_module.login.view.LoginActivity
import com.bridgelabz.fundoonotes.user_module.login.view.toast
import com.bridgelabz.fundoonotes.user_module.registration.model.User
import com.google.android.material.floatingactionbutton.FloatingActionButton
import com.google.android.material.navigation.NavigationView
class HomeDashBoardActivity : AppCompatActivity() {
private val dashBoadViewModelFactory: DashBoardViewModelFactory by lazy {
DashBoardViewModelFactory(DatabaseHelper(this))
}
private val dashBoardViewModel: DashBoardViewModel by lazy {
ViewModelProvider(this, dashBoadViewModelFactory).get(DashBoardViewModel::class.java)
}
private val toolbar: Toolbar by lazy {
findViewById<Toolbar>(R.id.toolbar)
}
private val drawerLayout: DrawerLayout by lazy {
findViewById<DrawerLayout>(R.id.drawer_layout)
}
private val navigationView: NavigationView by lazy {
findViewById<NavigationView>(R.id.nav_view)
}
private val floatingActionButton: FloatingActionButton by lazy {
findViewById<FloatingActionButton>(R.id.fab)
}
private val preferences: SharedPreferences by lazy {
this.getSharedPreferences(
"LaunchScreen",
Context.MODE_PRIVATE
)
}
private lateinit var authenticatedEmail: String
private var authenticatedUser: User? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_home_dash_board)
setSupportActionBar(toolbar)
initHomeDashBoardActivity()
authenticateUser()
setClickOnFloatingActionButton()
setNavigationItemClicked()
}
private fun authenticateUser() {
dashBoardViewModel.authenticatedUser(authenticatedEmail)
dashBoardViewModel.getUser().observe(this, Observer {
observeUser(it)
})
}
private fun observeUser(user: User?) {
if (user != null)
authenticatedUser = user
}
private fun initHomeDashBoardActivity() {
getUserSharedPreferences()
setActionBarToggle()
setNoteFragment()
}
private fun setNoteFragment() {
navigationView.setCheckedItem(R.id.nav_home)
val fragment = NoteFragment()
replaceFragment(fragment)
}
private fun getUserSharedPreferences() {
val editor = preferences.edit()
val email = preferences.getString("email", "")
authenticatedEmail = email!!
editor.apply()
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.home_dash_board, menu)
return true
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
return when (item.itemId) {
R.id.app_bar_user_info -> {
startUserProfileFragment()
toast(getString(R.string.tast_when_user_profile_clicked))
true
}
else -> super.onOptionsItemSelected(item)
}
}
override fun onBackPressed() {
callFragmentsOnBackPressed()
super.onBackPressed()
}
/**Function to set Floating Action Bar when it is clicked*/
private fun setClickOnFloatingActionButton() {
floatingActionButton.setOnClickListener {
val bundle = setNoteArguments()
replaceAddNoteFragment(bundle)
}
}
private fun setNoteArguments(): Bundle? {
val bundle = Bundle()
val note = Note()
if (authenticatedUser != null)
note.userId = authenticatedUser!!.id
bundle.putSerializable(getString(R.string.note), note)
return bundle
}
/**Function to set Navigation Items when they are clicked*/
private fun setNavigationItemClicked(): Boolean {
navigationView.setNavigationItemSelectedListener { item ->
when (item.itemId) {
R.id.nav_home -> {
replaceFragment(NoteFragment())
return#setNavigationItemSelectedListener true
}
R.id.nav_sing_out -> {
onSignOutMenuClick()
return#setNavigationItemSelectedListener true
}
R.id.nav_archive -> {
replaceFragment(ArchiveFragment())
return#setNavigationItemSelectedListener true
}
R.id.nav_delete -> {
replaceFragment(TrashFragment())
return#setNavigationItemSelectedListener true
}
R.id.nav_label -> {
replaceFragment(LabelFragment())
return#setNavigationItemSelectedListener true
}
R.id.nav_reminder -> {
replaceFragment(ReminderFragment())
return#setNavigationItemSelectedListener true
}
else -> return#setNavigationItemSelectedListener false
}
}
return true
}
private fun replaceFragment(fragment: Fragment?) {
drawerLayout.closeDrawer(navigationView)
val transaction = supportFragmentManager.beginTransaction()
transaction.replace(R.id.fragment_container, fragment!!)
transaction.commit()
}
/**Function to set Action Bar Toggle of Drawer Layout*/
private fun setActionBarToggle() {
val actionBarDrawerToggle = ActionBarDrawerToggle(
this,
drawerLayout,
toolbar,
R.string.navigation_drawer_open,
R.string.navigation_drawer_close
)
drawerLayout.addDrawerListener(actionBarDrawerToggle)
actionBarDrawerToggle.syncState()
}
/**Function to set alert dialog when SignOut
* Menu item is clicked */
private fun onSignOutMenuClick() {
removePreference()
signOutAlertDialog()
}
private fun removePreference() {
if (preferences.contains("email")) {
val editor = preferences.edit()
editor.clear().apply()
}
}
/**Function that performs sign out alert operation*/
private fun signOutAlertDialog() {
val alertDialogBuilder = AlertDialog.Builder(this)
alertDialogBuilder.setMessage(getString(R.string.sign_out_alert_message))
alertDialogBuilder.setTitle(getString(R.string.sign_out_alert_title))
alertDialogBuilder.setCancelable(false)
alertDialogBuilder
.setPositiveButton(
getString(R.string.sign_out_alert_positive_button)
) { _, _ ->
navigateToLoginScreen()
toast(
getString(R.string.toast_when_sign_out_alert_positive_button_clicked)
)
}
alertDialogBuilder.setNegativeButton(getString(R.string.sign_out_alerst_negative_button))
{ dialog, _ ->
drawerLayout.closeDrawer(navigationView)
dialog.cancel()
}
val alertDialog = alertDialogBuilder.create()
alertDialog.show()
}
/**Function to tell fragment that back navigation is Pressed*/
private fun callFragmentsOnBackPressed() {
val fragments: List<Fragment> = supportFragmentManager.fragments
for (fragment in fragments) {
if (fragment is OnBackPressed) {
fragment.onBackPressed()
setNoteFragment()
}
}
}
/**Function to replace home dash board with AddNoteFragment*/
private fun replaceAddNoteFragment(bundle: Bundle?) {
val fragment = AddNoteFragment()
fragment.arguments = bundle
val transaction = supportFragmentManager.beginTransaction()
transaction.replace(R.id.fragment_container, fragment)
.addToBackStack(null)
.commit()
}
/**Function to navigate to LoginActivity*/
private fun navigateToLoginScreen() {
val intent = Intent(this, LoginActivity::class.java)
finish()
startActivity(intent)
}
private fun startUserProfileFragment(): Boolean {
val fragmentManager = supportFragmentManager
val reminderDialog = UserProfileDialogFragment()
reminderDialog.arguments = Bundle().apply {
putSerializable(getString(R.string.authenticated_user), authenticatedUser)
}
reminderDialog.show(fragmentManager, getString(R.string.dialog_reminder_title))
return true
}
}
This is my note fragment
package com.bridgelabz.fundoonotes.note_module.dashboard_page.view
import android.os.Bundle
import android.util.Log
import android.view.*
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.SearchView
import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.RecyclerView
import com.bridgelabz.fundoonotes.R
import com.bridgelabz.fundoonotes.note_module.dashboard_page.model.Note
import com.bridgelabz.fundoonotes.note_module.dashboard_page.view.recycler_view_strategy.RecyclerViewType
import com.bridgelabz.fundoonotes.note_module.dashboard_page.view.recycler_view_strategy.LinearRecyclerViewManager
import com.bridgelabz.fundoonotes.note_module.dashboard_page.view.recycler_view_strategy.RecyclerViewLayoutManager
import com.bridgelabz.fundoonotes.note_module.dashboard_page.view.recycler_view_strategy.StaggeredRecyclerViewtManager
import com.bridgelabz.fundoonotes.note_module.dashboard_page.viewmodel.NoteTableManagerFactory
import com.bridgelabz.fundoonotes.note_module.dashboard_page.viewmodel.SharedViewModel
import com.bridgelabz.fundoonotes.note_module.note_page.view.AddNoteFragment
import com.bridgelabz.fundoonotes.repository.local_service.DatabaseHelper
import com.bridgelabz.fundoonotes.repository.local_service.note_module.NoteTableManagerImpl
class NoteFragment : Fragment(), OnNoteClickListener {
private val noteFactory by lazy {
NoteTableManagerFactory(NoteTableManagerImpl(DatabaseHelper(requireContext())))
}
private val sharedViewModel: SharedViewModel by lazy {
requireActivity().run {
ViewModelProvider(
this,
noteFactory
).get(SharedViewModel::class.java)
}
}
private val recyclerView: RecyclerView by lazy {
requireView().findViewById<RecyclerView>(R.id.notes_recycler_view)
}
private lateinit var noteAdapter: NoteViewAdapter
private lateinit var notes: ArrayList<Note>
private var recyclerViewType = RecyclerViewType.ListView
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
setHasOptionsMenu(true)
return inflater.inflate(R.layout.fragment_note, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
sharedViewModel.getRecyclerViewType()
.observe(requireActivity(), Observer { recyclerViewType = it })
sharedViewModel.getSimpleNoteLiveData()
.observe(requireActivity(), Observer { observeNotes(it) })
}
private fun initRecyclerView() {
recyclerView.setHasFixedSize(true)
recyclerView.layoutManager = setRecyclerViewType(recyclerViewType)
recyclerView.adapter = noteAdapter
}
private fun observeNotes(noteList: ArrayList<Note>) {
Log.d("noteList", noteList.toString())
notes = noteList
noteAdapter = NoteViewAdapter(notes, this)
noteAdapter.notifyDataSetChanged()
initRecyclerView()
}
override fun onClick(adapterPosition: Int) {
val note = notes[adapterPosition]
val bundle = Bundle()
bundle.putSerializable(getString(R.string.note), note)
replaceWithAddNoteFragment(bundle)
}
override fun onLongClick(adapterPosition: Int) {
val note = notes[adapterPosition]
Toast.makeText(requireActivity(), "$note", Toast.LENGTH_SHORT).show()
}
private fun replaceWithAddNoteFragment(bundle: Bundle) {
val addNoteFragment = AddNoteFragment()
addNoteFragment.arguments = bundle
requireActivity().supportFragmentManager.beginTransaction()
.replace(R.id.fragment_container, addNoteFragment).addToBackStack(null).commit()
}
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
(requireActivity() as AppCompatActivity).supportActionBar!!.title =
getString(R.string.menu_notes)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
return when (item.itemId) {
R.id.app_bar_recycler_view -> {
switchRecyclerViewType()
switchIcon(item)
true
}
R.id.app_bar_search_note -> {
val searchView = item.actionView as SearchView
searchView.setOnQueryTextListener(searchQueryListener)
true
}
else -> false
}
}
private val searchQueryListener = object : SearchView.OnQueryTextListener {
override fun onQueryTextSubmit(query: String?): Boolean {
return false
}
override fun onQueryTextChange(newText: String?): Boolean {
noteAdapter.filter.filter(newText)
return false
}
}
private fun switchIcon(item: MenuItem) {
if (recyclerViewType == RecyclerViewType.ListView)
item.setIcon(R.drawable.ic_grid_view_white)
else {
item.setIcon(R.drawable.ic_list_view_white)
}
}
private fun switchRecyclerViewType() {
when (recyclerViewType) {
RecyclerViewType.GridView -> {
sharedViewModel.setRecyclerViewType(RecyclerViewType.ListView)
recyclerView.layoutManager = setRecyclerViewType(recyclerViewType)
}
RecyclerViewType.ListView -> {
sharedViewModel.setRecyclerViewType(RecyclerViewType.GridView)
recyclerView.layoutManager = setRecyclerViewType(recyclerViewType)
}
}
}
private fun setRecyclerViewType(viewType: RecyclerViewType): RecyclerView.LayoutManager {
val layoutManager = RecyclerViewLayoutManager()
layoutManager.addRecyclerView(recyclerView)
return when (viewType) {
RecyclerViewType.ListView -> {
layoutManager.setRecyclerView(LinearRecyclerViewManager(requireContext()))
}
RecyclerViewType.GridView -> {
layoutManager.setRecyclerView(
StaggeredRecyclerViewtManager(
numberOfRows = 2,
orientation = 1
)
)
}
}
}
}
There's likely that you are pressing twice the button or somehow the navigate call triggers twice.

Getting Unresolved Reference from Singleton Class

I am working with android studio and in Kotlin. I am working with a Singleton class so my confusion is that my getInstance function is not being called when I am trying to add that into my setupRecyclerView function and it keeps saying it is an unresolved reference. I also have the issue that my NewsListActivity.SimpleItemRecyclerViewAdapter also keeps getting an unresolved reference when I try to reference it. Any help would be greatly appreciated.
package edu.uw.amjadz.material_news
import android.content.Context
import android.graphics.Bitmap
import android.util.LruCache
import com.android.volley.Request
import com.android.volley.RequestQueue
import com.android.volley.toolbox.ImageLoader
import com.android.volley.toolbox.Volley
class Singleton private constructor(context: Context){
private var INSTANCE: edu.uw.amjadz.material_news.Singleton? = null
fun getInstance(context: Context): edu.uw.amjadz.material_news.Singleton {
if(INSTANCE == null){
INSTANCE = Singleton(context)
}
return INSTANCE as edu.uw.amjadz.material_news.Singleton
}
val requestQueue: RequestQueue by lazy {
Volley.newRequestQueue(context.applicationContext)
}
val imageLoader: ImageLoader by lazy {
ImageLoader(requestQueue,
object : ImageLoader.ImageCache{
private val cache = LruCache<String, Bitmap>(20)
override fun getBitmap(url: String?): Bitmap {
return cache.get(url)
}
override fun putBitmap(url: String?, bitmap: Bitmap?) {
cache.put(url, bitmap)
}
}
)
}
fun <T> add(req: Request<T>){
requestQueue.add(req)
}
}
private fun setupRecyclerView(recyclerView: RecyclerView) {
recyclerView.setAdapter(null)
val key = getString(R.string.NEWS_API_KEY)
val url = "https://newsapi.org/v2/everything?q=bitcoin&from=2018-10-01&sortBy=publishedAt&apiKey=$key"
val jsonObjectRequest = JsonObjectRequest(
Request.Method.GET, url, null,
Response.Listener { response ->
recyclerView.adapter = NewsListActivity.SimpleItemRecyclerViewAdapter(this, DummyContent.parseData(response.toString()), twoPane)
},
Response.ErrorListener { error ->
}
)
Singleton.getInstance(this).add(jsonObjectRequest)
if (twoPane){
recyclerView.layoutManager = LinearLayoutManager(this)
} else {
recyclerView.layoutManager = GridLayoutManager(this, 2)
}
}
}
class SimpleItemRecyclerViewAdapter(
private val parentActivity: NewsListActivity,
private val values: List<DummyContent.DummyItem>,
private val twoPane: Boolean
) :
RecyclerView.Adapter<SimpleItemRecyclerViewAdapter.ViewHolder>() {
private val onClickListener: View.OnClickListener
init {
onClickListener = View.OnClickListener { v ->
val item = v.tag as DummyContent.DummyItem
if (twoPane) {
val fragment = NewsDetailFragment().apply {
arguments = Bundle().apply {
putString(NewsDetailFragment.ARG_ITEM_ID, item.id)
}
}
parentActivity.supportFragmentManager
.beginTransaction()
.replace(R.id.news_detail_container, fragment)
.commit()
} else {
val intent = Intent(v.context, NewsDetailActivity::class.java).apply {
putExtra(NewsDetailFragment.ARG_ITEM_ID, item.id)
}
v.context.startActivity(intent)
}
}
}

Resources