please mention the issue in my code. I've used a seekbar. On click of that it crashes straight away. i've used reset button also below the seekbar and I kept onstart tracking touch and onstop tracking touch empty.
val initialTextViewTranslationY = textView_progress.translationY
seekBar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
TODO("Not yet implemented")
textView_progress.text = progress.toString()
val translationdistance = (initialTextViewTranslationY + progress * resources.getDimension(R.dimen.text_anim_step) * -1)
textView_progress.animate().translationY(translationdistance)
if (!fromUser)
textView_progress.animate().setDuration(500).rotationBy(360f).translationY(initialTextViewTranslationY)
}
override fun onStartTrackingTouch(seekBar: SeekBar?) {
TODO("Not yet implemented")
}
override fun onStopTrackingTouch(seekBar: SeekBar?) {
TODO("Not yet implemented")
}
})
It generates the logcat as follows.
at android.widget.SeekBar.onStartTrackingTouch(SeekBar.java:113)
at android.widget.AbsSeekBar.startDrag(AbsSeekBar.java:1299)
at android.widget.AbsSeekBar.onTouchEvent(AbsSeekBar.java:1238)
at android.view.View.dispatchTouchEvent(View.java:10936)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2842)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2469)
at com.android.internal.policy.DecorView.superDispatchTouchEvent(DecorView.java:623)
at com.android.internal.policy.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1909)
at android.app.Activity.dispatchTouchEvent(Activity.java:3247)
at androidx.appcompat.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:69)
at com.android.internal.policy.DecorView.dispatchTouchEvent(DecorView.java:585)
at android.view.View.dispatchPointerEvent(View.java:11165)
at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:5227)
at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:5076)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4580)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4633)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4599)
at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:4736)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4607)
at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:4793)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4580)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4633)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4599)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4607)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4580)
at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:7210)
at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:7142)
at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:7103)
at android.os.MessageQueue.nativePollOnce(Native Method)
at android.os.MessageQueue.next(MessageQueue.java:323)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:6816)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1563)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1451)
You have to remove the TODO(...) invocations.
It's a Kotlin function that throws an exception at runtime:
source:
/**
* Always throws [NotImplementedError] stating that operation is not implemented.
*
* #param reason a string explaining why the implementation is missing.
*/
#kotlin.internal.InlineOnly
public inline fun TODO(reason: String): Nothing = throw NotImplementedError("An operation is not implemented: $reason")
Related
I am making recyclerview in kotlin in android studio. I'm trying to set up an event listener that puts a button in the recyclerview and outputs a toast message. Even if this#[activity name] is entered instead of this in context, a toast message is not displayed. What went wrong?
The error code is as follows.
Unresolved reference: #UpdateActivity
class UpdateActivity : AppCompatActivity() {
private val vBinding by lazy {ActivityUpdateBinding.inflate(layoutInflater)}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(vBinding.root)
var recyclerViewAdapter = CustomAdapter()
recyclerViewAdapter.listData = arrayListOf<String>("a", "b", "c")
vBinding.uploadedRecyclerView.adapter = recyclerViewAdapter
vBinding.uploadedRecyclerView.layoutManager = LinearLayoutManager(this)
} // onCreate End
class CustomAdapter:RecyclerView.Adapter<CustomAdapter.Holder>(){
var listData = arrayListOf<String>()
class Holder(val vBinding:UploadedRecyclerBinding):RecyclerView.ViewHolder(vBinding.root){
fun setData(name:String){
vBinding.name.text = name
vBinding.getBtn.setOnClickListener {
**Toast.makeText(this#UpdateActivity, "test", Toast.LENGTH_SHORT).show()**
// ↑A compilation error occurs here.**
}
}
} // Holder end
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Holder {
val vBinding = UploadedRecyclerBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return Holder(vBinding)
}
override fun onBindViewHolder(holder: Holder, position: Int) {
val name = listData[position]
holder.setData(name)
}
override fun getItemCount(): Int {
return listData.size
}
} // CustomAdapter end
} // UpdateActivity end
you could try put context into constructor of adapter when you create it, and use this context to show a toast. something like this:
class CustomAdapter(
private val mContext: Context
):RecyclerView.Adapter<CustomAdapter.Holder>(){
and in holder class:
Toast.makeText(mContext, "test", Toast.LENGTH_SHORT).show()
finally, when you create adapter in activity:
var recyclerViewAdapter = CustomAdapter(this)
Normally, we'll create adapter class in another file, so use this#UpdateActivity in adapter is bad idea
Instead of using the local context in Toast, always use applicationContext when showing it. So, you should replace that creation of Toast message as,
Toast.makeText(applicationContext, "test", Toast.LENGTH_SHORT).show()
I'm working on a news app and I want my layout to become invisible when a user saves an article. Can anyone please tell me the right way to write this code?
2 things to note:
-when I run the app,the layout is visible in the "saved fragment"
but then when I add "hideSavedMessage" right next to the code that updates the recyclerView and I run the app, the layout becomes invisible.
I want the layout to be invisible only when the user saves an article.
PS: I know how the visible and invisible mode works. I have used it before. My major problem is not knowing the right place to write the code. And by layout, I mean the text view and image view that appears on the screen. I would appreciate any contributions. Thank you.
Here's my code
class SavedFragment : Fragment(R.layout.fragment_saved) {
lateinit var viewModel: NewsViewModel
lateinit var newsAdapter: SavedAdapter
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewModel = (activity as NewsActivity).viewModel
setupRecyclerView()
newsAdapter.setOnItemClickListener {
val bundle = Bundle().apply {
putSerializable("article", it)
}
findNavController().navigate(
R.id.action_savedFragment_to_savedArticleFragment,
bundle
)
}
val itemTouchHelperCallback = object : ItemTouchHelper.SimpleCallback(
ItemTouchHelper.UP or ItemTouchHelper.DOWN,
ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT
) {
override fun onMove(
recyclerView: RecyclerView,
viewHolder: RecyclerView.ViewHolder,
target: RecyclerView.ViewHolder
): Boolean {
return true
}
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
val position =
viewHolder.adapterPosition//get position of item we deleted so that we swipe to left or right
val article =
newsAdapter.differ.currentList[position]//from news adapter at the index of the position
viewModel.deleteArticle(article)
Snackbar.make(view, "Successfully deleted article", Snackbar.LENGTH_LONG)
.apply {
setAction("Undo") {
viewModel.saveArticle(article); hideSavedMessage()
}
show()
}
val isAtLastItem = position <= 0
val shouldUpdateLayout = isAtLastItem
if (shouldUpdateLayout) {
showSavedMessage()
}
}
}
ItemTouchHelper(itemTouchHelperCallback).apply {
attachToRecyclerView(rvSavedNews)
}
viewModel.getSavedNews().observe(viewLifecycleOwner, Observer { articles ->
newsAdapter.differ.submitList(articles)
})
}
private fun setupRecyclerView() {
newsAdapter = SavedAdapter()
rvSavedNews.apply {
adapter = newsAdapter
layoutManager = LinearLayoutManager(activity)
}
}
private fun hideSavedMessage() {
savedMessage.visibility = View.INVISIBLE
isArticleAdded = false
}
private fun showSavedMessage() {
savedMessage.visibility = View.VISIBLE
}
}
The problem is that code inside observer runs even at the beginning - when you run your app, right? If I understand your problem, you just have to manage to make the fun hideSavedMessage() not be running for the first time. You could for example instantiate a boolean in onCreate() and set it to false. Then, inside the observer, you could run the hideSavedMessage() only if that boolean is true - you would set it as true at the end of the observer. I hope you understand.
class DialFragment: DialogFragment() {
private lateinit var image001: ImageView
private val caller = object: FingerprintManager.AuthenticationCallback() {
override fun onAuthenticationError(errorCode: Int, errString: CharSequence?) {
super.onAuthenticationError(errorCode, errString)
listener.onDialClick(errString.toString(), "2")
dismiss()
}
override fun onAuthenticationSucceeded(result: FingerprintManager.AuthenticationResult?) {
super.onAuthenticationSucceeded(result)
listener.onDialClick("yes","1")
var avp = image001.drawable as AnimatedVectorDrawable
avp.start()
dismiss()
}
override fun onAuthenticationFailed() {
super.onAuthenticationFailed()
listener.onDialClick("no","3")
dismiss()
}
The animation called by avp.start() is not beeing shown, the dialog fragment directly dismisses after succesfull authentification. if i omit the dismiss()-Call below then it works properly. My question is why is this and how to fix it? And yes, i know FingerprintManager-API is deprecated, i am running this for test purposes.
dismiss() immediately ends the life of your DialogFragment, so it will have no more opportunity to show you any animations in the Fragment. You should dismiss after a delay (however long the animation is).
override fun onAuthenticationSucceeded(result: FingerprintManager.AuthenticationResult?) {
super.onAuthenticationSucceeded(result)
listener.onDialClick("yes","1")
var avp = image001.drawable as AnimatedVectorDrawable
avp.start()
activity?.runOnUiThread(300L) { // put however long your animation takes
dismiss()
}
}
Simple kotlin app under android studio that makes a loadURL to a local address:-
The function often fails, probably due to local net latency with:
Web Page not available
The web page at http://192.168.1.144/apikey/webcam could not be loaded because:
net: ERR_ADDRESS_UNREACHABLE
I have
android:usesCleartextTraffic="true"
<uses-permission android:name="android.permission.INTERNET"/>
in the manifest, and the loadurl often is fine
In order to capture the error and provide a message an
onReceivedError()
action is used.
It never fires
Is the syntax of the onReceivedError correct? It refers to WebView rather than my instance myWebview (which causes a reference error), and I've moved the scope around to no effect.
The Android Studio comment says that the function is never used. A big hint, but I can't see which scope to place it in.
Or is this type of error one of those not caught by OnReceivedError. If so, how which function would?
Ideally I'd like to increase the 'wait' time of the LoadUrl function so that the lazy local IP can respond.
I've copied this from other examples.
I'd really welcome some help please
Here is my class code:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
// Create the NotificationChannel
val name = getString(R.string.channel_name)
val descriptionText = getString(R.string.channel_description)
val importance = NotificationManager.IMPORTANCE_DEFAULT
val CHANNEL_ID = "only_channel"
val mChannel = NotificationChannel(CHANNEL_ID, name, importance)
mChannel.description = descriptionText
// Register the channel with the system; you can't change the importance
// or other notification behaviors after this
val notificationManager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager
notificationManager.createNotificationChannel(mChannel)
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
// Create channel to show notifications.
val channelId = getString(R.string.default_notification_channel_id)
val channelName = getString(R.string.default_notification_channel_name)
val notificationManager = getSystemService(NotificationManager::class.java)
notificationManager?.createNotificationChannel(NotificationChannel(channelId,
channelName, NotificationManager.IMPORTANCE_HIGH))
}
val myWebView: WebView = findViewById(R.id.webview)
/*myWebView.loadUrl("https://amazon.co.uk")*/
myWebView.webViewClient = WebViewClient()
myWebView.setWebViewClient(object : WebViewClient() {
fun onReceivedError(view: WebView , errorCode: Int, description: String, failingUrl: String, getContext: Context) {
Log.i("WEB_VIEW_TEST", "error code:$errorCode")
Toast.makeText(getContext, "Webcam not reachable",Toast.LENGTH_SHORT ).show()
}
})
WebView.setWebContentsDebuggingEnabled(true)
/*5 March 2021*/
myWebView.clearCache(true)
myWebView.loadUrl("http://192.168.1.144/apikey/webcam")
val disable_button: Button = findViewById(R.id.disable)
disable_button.setOnClickListener {
myWebView.loadUrl("http://192.168.1.144/apikey/disable")
}
fun onReceivedError(
view: WebView,
request: WebResourceRequest,
error: WebResourceError
) {
Toast.makeText(this, "Webcam not reachable", Toast.LENGTH_SHORT).show()
}
}
}
I need to know the size of a Button (or any other view).
But none of the procedures in lifecycle (onCreate, onStart, OnResume) seem to know it, as the Button seems not yet to be initialized!
...
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
private var servOffset: Int=0 // Value depends on Layout/Orientation and Device
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
btPunkte.setOnClickListener { doPunkt(true) }
servOffset = btPR1.width/2 // 'btPR1' is a Button in 'Layout activity_main.*'
//ToDo: Doesn't work! = remains 0
}
override fun onResume() {
super.onResume()
// ToDo: unsolved! When do I get the size??
// onStart (or onResume) are invoked correctly, but don't know the value!
// ?? Button doesn't yet exist in Livecycle?!
servOffset = btPR1.width/2 // //ToDo: Still doesn't work!
anzeigeAktualisieren()
}
private fun anzeigeAktualisieren() {
// If ... move Button
btPR1.x += servOffset //ToDo: unsolved offset remains 0 ?!
}
private fun doPunkt(links:Boolean) {
anzeigeAktualisieren()
...
}
...
}
I did find "When are views drawn", and several other threads, but they didn't help me solve my problem.
You can try using viewTreeObserver.
val vto = button.viewTreeObserver
vto.addOnGlobalLayoutListener {
Log.e("Show me width", button.width.toString())
}
It is working, but it can and WILL be called several times!!!
Other option is to use Handler and postDelayed
Handler().postDelayed({
Log.e("Show me width2", button.width.toString())
}, 1000)
Yes, this is very bad practice, but it can save you in stupid situation :)
Good luck!