This question already has answers here:
Android: Internet connectivity change listener
(12 answers)
How to set timer in android?
(24 answers)
Closed last year.
How can I make something in my Java constantly check for connectivity of internet I already have something that checks for connectivity of internet but do not know how to make it constant
Current connectivity checker
public static boolean isNetworkAvailable(Context context) {
ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
if (connectivityManager != null) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
NetworkCapabilities capabilities = connectivityManager.getNetworkCapabilities(connectivityManager.getActiveNetwork());
return capabilities != null && (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) || capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) || capabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET));
} else {
NetworkInfo activeNetwork = connectivityManager.getActiveNetworkInfo();
return activeNetwork != null && activeNetwork.isConnected();
}
}
return false;
}]
I have done it in Kotlin. If you face problem in converting Kotlin into Java you can ask me for help.
So, I am using Broadcast Receiver and detect whenever the network state changed and when there is no Internet, a dialogBox will show.
MainActivity.kt
class MainActivity : AppCompatActivity() {
private var br: BroadcastReceiver? = null
private var filter: IntentFilter? = null
private var mContext: MainActivity? = null
private var isPaused = false
private var toConfirm = true
private var noInternetBuilder: AlertDialog.Builder? = null
private var noInternetDialog: AlertDialog? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
br = MyBroadCastReceiver()
filter = IntentFilter()
filter?.addAction("android.net.conn.CONNECTIVITY_CHANGE")
mContext = this#MainActivity
mContext?.registerReceiver(br, filter)
}
/**
* Broadcast for Internet Checking
*
*/
inner class MyBroadCastReceiver : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
if (!isNetworkStatusAvailable(this#MainActivity)) {
if (!isPaused) {
toConfirm = true
if (noInternetDialog != null) {
noInternetDialog?.dismiss()
}
showDialogNoInternet(this#MainActivity)
}
toConfirm = false
} else {
toConfirm = true
if (noInternetDialog != null) {
if (noInternetDialog!!.isShowing) {
noInternetDialog?.dismiss()
}
}
}
}
}
fun isNetworkStatusAvailable(context: Context): Boolean {
var result = false
val connectivityManager =
context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
val networkCapabilities = connectivityManager.activeNetwork ?: return false
val actNw =
connectivityManager.getNetworkCapabilities(networkCapabilities) ?: return false
result = when {
actNw.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> true
actNw.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> true
actNw.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) -> true
else -> false
}
} else {
#Suppress("DEPRECATION")
connectivityManager.run {
connectivityManager.activeNetworkInfo?.run {
result = when (type) {
ConnectivityManager.TYPE_WIFI -> true
ConnectivityManager.TYPE_MOBILE -> true
ConnectivityManager.TYPE_ETHERNET -> true
else -> false
}
}
}
}
return result
}
fun showDialogNoInternet(activity: Activity) {
noInternetBuilder = AlertDialog.Builder(activity)
val viewGroup = findViewById<ViewGroup>(android.R.id.content)
val dialogView: View = LayoutInflater.from(viewGroup.context)
.inflate(R.layout.dialog_nointernet, viewGroup, false)
noInternetBuilder!!.setView(dialogView)
noInternetDialog = noInternetBuilder!!.create()
noInternetDialog!!.setCancelable(false)
noInternetDialog!!.window!!.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
val btn = dialogView.findViewById<View>(R.id.btnOkInternet) as Button
btn.setOnClickListener {
resultInternetLauncher.launch(Intent(Settings.ACTION_WIFI_SETTINGS))
noInternetDialog?.dismiss()
}
noInternetDialog!!.show()
}
override fun onPause() {
super.onPause()
isPaused = true
}
override fun onResume() {
super.onResume()
isPaused = false
if (!toConfirm) {
if (noInternetDialog != null) {
noInternetDialog?.dismiss()
}
showDialogNoInternet(mContext!!)
}
}
}
Must implement override fun onPause() and override fun onResume() along with it because it will control the crashes of dialogBox.
Related
I have a code that checks if the device is connected, but it only works if I start the app from scratch
What I want is that the view changes visibility as soon as the internet is connected or disconnected
When the connection is lost or disconnected, for example, I want the main view to become invisible and make a textview "No Internet" visible.
here what im using right now, but as i said it works if the app start from scratch
// onCreate ------------
// Internet on/off
if (isOnline()) {
noInternet.setVisibility(View.INVISIBLE); // Online
mainRelativeLayout.setVisibility(View.VISIBLE);
} else {
noInternet.setVisibility(View.VISIBLE); // Disconnected
mainRelativeLayout.setVisibility(View.INVISIBLE);
}
// ----------- onCreate.
// Internet on/off
public boolean isOnline() {
boolean connected = false;
try {
ConnectivityManager connectivityManager = (ConnectivityManager) this.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
connected = networkInfo != null && networkInfo.isAvailable() && networkInfo.isConnected();
return connected;
} catch (Exception e) {
e.printStackTrace();
}
return connected;
}
You can do this by simple ConnectionLiveData:
class ConnectionLiveData(val context: Context) : LiveData<Boolean>() {
private var connectivityManager: ConnectivityManager =
context.getSystemService(CONNECTIVITY_SERVICE) as ConnectivityManager
private lateinit var connectivityManagerCallback: ConnectivityManager.NetworkCallback
private val networkRequestBuilder: NetworkRequest.Builder = NetworkRequest.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
override fun onActive() {
super.onActive()
updateConnection()
when {
Build.VERSION.SDK_INT >= Build.VERSION_CODES.N -> connectivityManager.registerDefaultNetworkCallback(
getConnectivityMarshmallowManagerCallback()
)
Build.VERSION.SDK_INT >= Build.VERSION_CODES.M -> marshmallowNetworkAvailableRequest()
else -> lollipopNetworkAvailableRequest()
}
}
override fun onInactive() {
super.onInactive()
connectivityManager.unregisterNetworkCallback(connectivityManagerCallback)
}
#TargetApi(Build.VERSION_CODES.M)
private fun marshmallowNetworkAvailableRequest() {
connectivityManager.registerNetworkCallback(
networkRequestBuilder.build(),
getConnectivityMarshmallowManagerCallback()
)
}
#TargetApi(Build.VERSION_CODES.LOLLIPOP)
private fun lollipopNetworkAvailableRequest() {
connectivityManager.registerNetworkCallback(
networkRequestBuilder.build(),
getConnectivityLollipopManagerCallback()
)
}
private fun getConnectivityLollipopManagerCallback(): ConnectivityManager.NetworkCallback {
connectivityManagerCallback = object : ConnectivityManager.NetworkCallback() {
override fun onAvailable(network: Network) {
super.onAvailable(network)
postValue(true)
}
override fun onLost(network: Network) {
super.onLost(network)
postValue(false)
}
}
return connectivityManagerCallback
}
private fun getConnectivityMarshmallowManagerCallback(): ConnectivityManager.NetworkCallback {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
connectivityManagerCallback = object : ConnectivityManager.NetworkCallback() {
override fun onCapabilitiesChanged(
network: Network,
networkCapabilities: NetworkCapabilities
) {
super.onCapabilitiesChanged(network, networkCapabilities)
networkCapabilities.let { capabilities ->
if (capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) && capabilities.hasCapability(
NetworkCapabilities.NET_CAPABILITY_VALIDATED
)
) {
postValue(true)
}
}
}
override fun onLost(network: Network) {
super.onLost(network)
postValue(false)
}
}
return connectivityManagerCallback
} else {
throw IllegalAccessError("Accessing wrong API version")
}
}
private fun updateConnection() {
val activeNetwork: NetworkInfo? = connectivityManager.activeNetworkInfo
postValue(activeNetwork?.isConnected == true)
}
}
In your activity/fragment :
ConnectionLiveData(this).observe(this) { value ->
if (value) {
//has connection
} else {
//no connection
}
}
I tried the codes from the forum all of which is in Java. It was converted to Kotlin by IDE but it's not working. I've just started learning Android. Please help me with this. I've attached the converted code below. Also, I added this -
val webUrl = webView.url
if (webUrl != null) {
shouldOverrideUrlLoading(webView,webUrl)
}
inside OnCreate. Not sure if that's correct or not.
Below is the code---
private fun shouldOverrideUrlLoading(view: WebView, url: String) {
view.loadUrl(url)
if (url.startsWith("whatsapp://")) {
view.stopLoading()
try {
val whatsappIntent = Intent(Intent.ACTION_SEND)
whatsappIntent.type = "text/plain"
whatsappIntent.setPackage("com.whatsapp")
whatsappIntent.putExtra(
Intent.EXTRA_TEXT,
view.url.toString() + " - Shared from webview "
)
startActivity(whatsappIntent)
} catch (ex: ActivityNotFoundException) {
val makeShortText = "Whatsapp has not been installed"
Toast.makeText(this, makeShortText, Toast.LENGTH_SHORT).show()
}
}
}
Expecting your quick support. Thanks.
i had the same issue this is the solution i found
class KaboekieWebsite : AppCompatActivity() {
lateinit var myWebView: WebView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_kaboekie_website)
myWebView = findViewById(R.id.KaboekieWebsiteView)
myWebView.webViewClient = WebViewClient()
myWebView.settings.setSupportZoom(true)
myWebView.settings.loadsImagesAutomatically
myWebView.settings.javaScriptEnabled = true
myWebView.setWebViewClient(Callback())
myWebView.loadUrl("https://www.Kaboekie.be/")
myWebView.webViewClient = object : WebViewClient() {
override fun shouldOverrideUrlLoading(webView: WebView, url: String): Boolean {
if (url.startsWith("intent://")) {
val intent = Intent.parseUri(url, Intent.URI_INTENT_SCHEME)
if (intent != null) {
val fallbackUrl = intent.getStringExtra("browser_fallback_url")
return if (fallbackUrl != null) {
webView.loadUrl(fallbackUrl)
true
} else {
false
}
}
}
else if (url.startsWith("tel:")){
val intent = Intent(Intent.ACTION_DIAL)
intent.data = Uri.parse(url)
startActivity(intent)
return true
}
else if (url.startsWith("mailto:")) {
val intent = Intent(Intent.ACTION_VIEW)
val data = Uri.parse(
url + Uri.encode("subject") + "&body=" + Uri.encode(
"body"
)
)
intent.data = data
startActivity(intent)
return true
}
return false
}
}
}
override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
// Check if the key event was the Back button and if there's history
if (keyCode == KeyEvent.KEYCODE_BACK && myWebView.canGoBack()) {
myWebView.goBack()
return true
}
// If it wasn't the Back key or there's no web page history, bubble up to the default
// system behavior (probably exit the activity)
return super.onKeyDown(keyCode, event)
}
private class Callback : WebViewClient() {
override fun shouldOverrideKeyEvent(view: WebView?, event: KeyEvent?): Boolean {
return false
}
}
}
I am new in Kotlin MVVM also, I tried to achieved Pagination with legacy approach and stucked in a issue with my RecyclerView, whenever I scroll it the data duplicated, I tried DiffUtils but no help.
I Logged the data in VIEWMODEL class the data is not repeating
but, when I logged in Activity where I am observing it is showing duplicate values
SEARCHRESULTACTIVITY.KT
class SearchResultActivity : AppCompatActivity() {
private lateinit var layoutManager: LinearLayoutManager
private lateinit var recyclerView: RecyclerView
private lateinit var pullAdapter: CustomAdapter
private var pageNumber = 1
private var totalItemsCount = 0
private var firstVisibleItemsCount = 0
private var visibleItemsCount = 0
private var previousTotal = 0
private var loading = true
private var fillPullList: ArrayList<RepoPull> = ArrayList()
private var userName: String = ""
private var repoName: String = ""
private var isEnd = false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
initialize()
getDataPull(userName, repoName)
loadNextData()
}
private fun initialize() {
setContentView(R.layout.activity_search_result)
recyclerView = findViewById(R.id.repoRecView)
layoutManager = LinearLayoutManager(this)
getSearchQuery()
}
private fun getSearchQuery() {
userName = intent.getStringExtra("owner").toString()
repoName = intent.getStringExtra("repo").toString()
populatePullRv()
}
private fun populatePullRv() {
recyclerView.addItemDecoration(DividerItemDecoration(this, DividerItemDecoration.VERTICAL))
recyclerView.layoutManager = layoutManager
pullAdapter = CustomAdapter(this, fillPullList)
recyclerView.adapter = pullAdapter
progressBar.visibility = View.VISIBLE
}
private fun loadNextData() {
recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy)
val mLayoutManger = recyclerView.layoutManager as LinearLayoutManager
visibleItemsCount = mLayoutManger.childCount
totalItemsCount = mLayoutManger.itemCount
firstVisibleItemsCount = mLayoutManger.findFirstVisibleItemPosition()
if (loading) {
if (totalItemsCount > previousTotal) {
previousTotal = totalItemsCount
pageNumber++
loading = false
progressBar.visibility = View.GONE
}
}
if (!loading && (firstVisibleItemsCount + visibleItemsCount) >= totalItemsCount) {
getDataPull(userName, repoName)
loading = true
Log.d("PAGE", pageNumber.toString())
}
}
})
}
private fun getDataPull(username: String?, reponame: String?) {
val myViewModel = ViewModelProviders.of(this).get(PullVM::class.java)
myViewModel.endofList.observe(this, {
if (it == true) {
isEnd = true
progressBar.visibility = View.GONE
Toast.makeText(this#SearchResultActivity, "All PR Fetched", Toast.LENGTH_SHORT)
.show()
}
})
myViewModel.status.observe(this, {
if (it == false) {
showError(getString(R.string.no_net))
}
})
myViewModel.getPullDataFromVM().observe(this, {
if (it != null) {
listRepos(it) **//DUPLICATE VALUE COMING**
} else {
showError(getString(R.string.nothing_found))
}
})
myViewModel.getPullList(username.toString(), reponame.toString(), pageNumber)
}
private fun showError(s: String) {
progressBar.visibility = View.GONE
val theView =
this#SearchResultActivity.findViewById<View>(android.R.id.content)
Snackbar.make(
theView,
s,
Snackbar.LENGTH_LONG
).show()
}
#SuppressLint("NotifyDataSetChanged")
fun listRepos(repos: List<RepoPull>) {
if (!isEnd) {
progressBar.visibility = View.GONE
fillPullList.addAll(repos)
pullAdapter.notifyDataSetChanged()
}
}}
PULLVM(View Model).kt
class PullVM : ViewModel() {
var pullList: MutableLiveData<List<RepoPull>>
var status = MutableLiveData<Boolean?>()
var endofList = MutableLiveData<Boolean?>()
init {
pullList = MutableLiveData()
}
fun getPullDataFromVM(): MutableLiveData<List<RepoPull>> {
return pullList
}
fun getPullList(ownerName: String, repoName: String, pgNo: Int) {
val retriever = GitHubRetriever
val callback = object : Callback<List<RepoPull>> {
override fun onFailure(call: Call<List<RepoPull>>, t: Throwable) {
status.value = false
}
override fun onResponse(
call: Call<List<RepoPull>>,
response: Response<List<RepoPull>>
) {
if (response.body()?.size == 0) {
endofList.value = true
}
if (response.code() == 404) {
pullList.postValue(null)
} else {
status.value = true
val repos = response.body()
if (repos != null) {
pullList.postValue(repos)
}
}
}
}
retriever.userRepos(
callback,
ownerName,
repoName,
pgNo
)
}
Try moving your viewModel instantiation and observer settings to onCreate so you don't have to create a new viewModel instance and set a new observable to your LiveDatas.
Declare myViewModel as a lateinit property of your Activity and move this part to onCreate
myViewModel = ViewModelProviders.of(this).get(PullVM::class.java)
myViewModel.endofList.observe(this, {
if (it == true) {
isEnd = true
progressBar.visibility = View.GONE
Toast.makeText(this#SearchResultActivity, "All PR Fetched", Toast.LENGTH_SHORT)
.show()
}
})
myViewModel.status.observe(this, {
if (it == false) {
showError(getString(R.string.no_net))
}
})
myViewModel.getPullDataFromVM().observe(this, {
if (it != null) {
listRepos(it) **//DUPLICATE VALUE COMING**
} else {
showError(getString(R.string.nothing_found))
}
})
And
private fun getDataPull(username: String?, reponame: String?)
should only contain
myViewModel.getPullList(username.toString(), reponame.toString(), pageNumber)
I want to set SplashScreen(fragment) in my app and because its a online shopping application I should check for internet connectivity.
I have 4 main fragment and one main activity in this app.
I used progress bar ,textview and a refresh button in splash fragment.
lets see part of code!...
val networkConnection = NetworkConnection(requireContext())
networkConnection.observe(requireActivity()) { isConnected ->
if (isConnected) {
binding.refresh.setOnClickListener {
binding.apply {
progress.visibility = View.VISIBLE
progress.animate().start()
connectivityText.visibility = View.INVISIBLE
refresh.visibility = View.INVISIBLE
go()
}
}
} else {
binding.apply {
progress.visibility = View.GONE
connectivityText.visibility = View.VISIBLE
refresh.visibility = View.VISIBLE
}
}
}
this part is for when i am not connected to the internet and I start the app.
textview appears with this text " you are not connected to Internet " and refresh button appears to refresh the fragment after connection. It works fine.
the problem is when I am connected to Internet and start the app. Lets see the code.
val s = S(requireContext())
when (s.isOnline()) {
true -> {
binding.apply {
progress.visibility = android.view.View.VISIBLE
progress.animate().start()
connectivityText.visibility = android.view.View.INVISIBLE
refresh.visibility = android.view.View.INVISIBLE
}
}
false -> {
binding.apply {
progress.visibility = View.GONE
connectivityText.visibility = View.VISIBLE
refresh.visibility = View.VISIBLE
}
}
}
"S" is a file that has a isOnline() function. i want to use below code in "if(isOnline)"statement
Handler(Looper.getMainLooper()).postDelayed({
val action =
SplashFragmentDirections.actionSplashFragmentToHomeFragment2()
findNavController().navigate(action)
CoroutineScope(Dispatchers.Main).launch {
delay(4)
}
}, 4000)
when i set this code in "if(isonline)" statement I see this error:
failed to connect to /192.168.1.36 (port 80) from /:: (port 0) and when i delete it from there
app works fine with no error .
NetworkConnectionClass:
class NetworkConnection( private val context: Context) : LiveData<Boolean>() {
private var connectivityManager: ConnectivityManager =
context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
private lateinit var networkCallback: ConnectivityManager.NetworkCallback
override fun onActive() {
super.onActive()
updateConnection()
when {
Build.VERSION.SDK_INT >= Build.VERSION_CODES.N -> {
connectivityManager.registerDefaultNetworkCallback(ConnectivityManagerCallback())
}
Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP -> {
lollipopNetworkRequest()
}
else -> {
context.registerReceiver(
networkReciever,
IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)
)
}
}
}
#RequiresApi(Build.VERSION_CODES.N)
override fun onInactive() {
super.onInactive()
}
#TargetApi(Build.VERSION_CODES.LOLLIPOP)
private fun lollipopNetworkRequest() {
val requestBuilder = NetworkRequest.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_ETHERNET)
.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
connectivityManager.registerNetworkCallback(
requestBuilder.build(),
ConnectivityManagerCallback()
)
}
private fun ConnectivityManagerCallback(): ConnectivityManager.NetworkCallback {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
networkCallback = object : ConnectivityManager.NetworkCallback() {
override fun onLost(network: Network) {
super.onLost(network)
postValue(false)
}
override fun onAvailable(network: Network) {
super.onAvailable(network)
postValue(true)
}
}
} else {
throw IllegalAccessError("ERROR")
}
return networkCallback
}
private var networkReciever = object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
updateConnection()
}
}
private fun updateConnection() {
val activeNetwork: NetworkInfo? = connectivityManager.activeNetworkInfo
if (activeNetwork?.isConnected == true) {
postValue(true)
} else {
postValue(false)
}
}
}
It took me a week and still I have no idea . help me please
any help will be appreciated.
I changed my splash fragment to an activity and also i delete it from graph then I used Thread instead of handler like this for that part where is was connected to internet
var ms: Long = 0
val splashTime = 2000
val splashActive = true
val paused = false
//use go() method here instead of this thread.check below to see go() method
Thread {
try {
while (splashActive && ms < splashTime) {
if (!paused)
ms += 100
Thread.sleep(100)
}
} catch (e: Exception) {
e.fillInStackTrace()
} finally {
if (!s.isOnline()) {
} else {
startActivity(Intent(this, MainActivity::class.java))
}
}
}.start()
I Changed that part where i was not connected to internet like this:
val networkConnection = NetworkConnection(this)
networkConnection.observe(this) { isConnected ->
if (isConnected) {
binding.refresh.setOnClickListener {
binding.apply {
progress.visibility = View.VISIBLE
progress.animate().start()
connectivityText.visibility = View.INVISIBLE
refresh.visibility = View.INVISIBLE
}
//use go() method here instead of this thread.check below to see go() method
Thread {
Thread.sleep(2000)
startActivity(Intent(this, MainActivity::class.java))
}.start()
}
} else {
binding.apply {
progress.visibility = View.GONE
connectivityText.visibility = View.VISIBLE
refresh.visibility = View.VISIBLE
}
}
}
UPDATE
put first part code where i was connected to internet to one method then use that method anywhere you want like this:
fun go() {
val s = S(this)
Thread {
try {
while (splashActive && ms < splashTime) {
if (!paused)
ms += 100
Thread.sleep(100)
}
} catch (e: Exception) {
e.fillInStackTrace()
} finally {
if (!s.isOnline()) {
} else {
startActivity(Intent(this, MainActivity::class.java))
}
}
}.start()
}
please tell me if you have better solution
I have been having this issue for a long time and have tried different suggestion on similar posts but all proved futile.
Currently, I have a recyclerview that implements double click for likes. Whenever I do that the recyclerview jumps to the top of the page.
Kindly advise on what to do to stop this.
Code
private fun setDataIntoAdapter(list: List<MovieEntity?>?) {
movieAdapter = MovieAdapter(list, object : MovieAdapter.OnMovieListener {
override fun onMovieDoubleClick(movieEntity: MovieEntity, view: View) {
val fav = view.findViewById<ImageView>(R.id.redFav)
// var favMovie = convertToFavourityEntity(movieEntity)
movieEntity.favourite = true
if (fav.visibility == View.GONE) {
fav.visibility = View.VISIBLE
CoroutineScope(Main).launch {
try {
insertAndUpdate(movieEntity)
FancyToast.makeText(
context,
"${movieEntity.title} is added to favourite",
FancyToast.LENGTH_LONG,
FancyToast.SUCCESS,
true
).show()
} catch (e: Exception) {
FancyToast.makeText(
context,
"Movie has been previously added \nto favorite",
FancyToast.LENGTH_LONG,
FancyToast.ERROR,
true
).show()
}
}
} else {
fav.visibility = View.GONE
movieEntity.favourite = false
CoroutineScope(Main).launch {
try {
deleteAndUpdate(movieEntity)
FancyToast.makeText(
context,
"${movieEntity.title} is removed from favourite",
FancyToast.LENGTH_LONG,
FancyToast.INFO,
true
).show()
} catch (e: Exception) {
// Toast.makeText(context, "Movie has been previously removed \nto favorite", Toast.LENGTH_SHORT).show()
val snackbar = Snackbar
.make(
view, "Movie has been previously removed \n" +
"to favorite", Snackbar.LENGTH_LONG
)
snackbar.show()
}
}
}
}
override fun onSingleClick(movieEntity: MovieEntity, view: View) {
gotoDetails(movieEntity)
// view.deleteIcon.setOnClickListener {
// singleDeletion(movieEntity)
// }
}
})
}
private suspend fun insertAndUpdate(movieEntity: MovieEntity) {
ServiceLocator.createLocalDataSource(context!!).movieDao?.update(movieEntity)
}
Adapter
class MovieAdapter<T>(private var movies:List<T?>?, private var listener:OnMovieListener):RecyclerView.Adapter<MovieAdapter.MovieHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MovieHolder {
val itemView = LayoutInflater.from(parent.context).inflate(R.layout.movie_recycler_items, parent, false)
return MovieAdapter.MovieHolder(itemView)
}
override fun getItemCount(): Int {
return movies!!.size
}
fun setMovie(movies: List<T?>?){
this.movies = movies
notifyDataSetChanged()
}
fun getMovieAt(position: Int):T?{
return movies?.get(position)
}
override fun onBindViewHolder(holder: MovieHolder, position: Int) {
// covert.drawCornerFlag(holder)
movies?.let{
val currentMovies = it[position]
holder.bind(it[position]!!, listener)
}
}
class MovieHolder(itemView: View): RecyclerView.ViewHolder(itemView) {
var title = itemView.findViewById<TextView>(R.id.title)
var releaseDate = itemView.findViewById<TextView>(R.id.releaseDate)
var ratingBar = itemView.findViewById<RatingBar>(R.id.ratingBar)
var imageThmbnail = itemView.findViewById<ImageView>(R.id.thumbnail)
var fav = itemView.findViewById<ImageView>(R.id.favourite)
var redFav = itemView.findViewById<ImageView>(R.id.redFav)
var rating = itemView.findViewById<TextView>(R.id.rating)
fun <T> bind(movieEntity: T, listener: OnMovieListener){
var i = 0
if(movieEntity is MovieEntity){
if(movieEntity.favourite){
redFav.visibility = View.VISIBLE
}
else{
redFav.visibility = View.GONE
}
val calendar = Calendar.getInstance()
val dateReleased = movieEntity.releaseDate?.split("-")
val year = dateReleased?.get(0)?.toInt()
val month = dateReleased?.get(1)?.toInt()
val day = dateReleased?.get(2)?.toInt()
var newDate:Date?= null
if (year != null) {
if (month != null) {
if (day != null) {
calendar.set(year, month,day)
}
}
newDate = calendar.time
}
val displayDate = newDate.toString().substring(4..7) + year.toString()
title.setText(movieEntity.title)
releaseDate.setText(displayDate)
ratingBar.numStars = 5
val ratingNum = movieEntity.rating?.toFloat()?.div(2)
rating.setText("${ratingNum!!}")
ratingBar.rating = ratingNum
Picasso.get().load(movieEntity.movieImage).into(imageThmbnail)
itemView.setOnClickListener(DoubleClick(object :DoubleClickListener{
override fun onDoubleClick(view: View?) {
Log.i("Dob", "Double clicked")
listener.onMovieDoubleClick(movieEntity, itemView)
}
override fun onSingleClick(view: View?) {
Log.i("click", "Single click")
listener.onSingleClick(movieEntity, itemView)
}
}))
}
}
}
interface OnMovieListener{
fun onMovieDoubleClick(movieEntity: MovieEntity, view:View)
fun onSingleClick(movieEntity: MovieEntity, view: View)
}
}