package com.example.va_embedding
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.view.View
import android.widget.MediaController
import android.widget.ProgressBar
import android.widget.SeekBar
import android.widget.VideoView
import android.widget.SeekBar.OnSeekBarChangeListener
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val venom = findViewById<VideoView>(R.id.venomvideo)
venom.setVideoPath("android.resource://" + packageName + "/" + R.raw.venom)
val mediaC = MediaController(this)
mediaC.setAnchorView(venom)
venom.setMediaController(mediaC)
val vc = findViewById<SeekBar>(R.id.seekBar2)
vc.setOnSeekBarChangeListener(SeekBar.OnSeekBarChangeListener(){
#Override
onProgressChanged(SeekBar seekBar2, Int: i, boolean : b)
Log.i(:"Seekbar changed", i = Integer.toString())
})
venom.start()
}
}
XML Layout
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<VideoView
android:id="#+id/venomvideo"
android:layout_width="333dp"
android:layout_height="568dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0" />
<SeekBar
android:id="#+id/seekBar2"
android:layout_width="249dp"
android:layout_height="73dp"
android:layout_marginStart="70dp"
android:layout_marginEnd="70dp"
android:layout_marginBottom="50dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Objective: To get an Audio SeekBar in the app
Issue: I am getting an error saying Interface do not have constructors. I am also facing an issue when I am trying to add OnSeekBarChangeListener() method.
I am using Android Studio 3.6.1.
My SDK version is 28
Kindly help
SeekBar.OnSeekBarChangeListener is an interface not a class, you can not call the constructor SeekBar.OnSeekBarChangeListener().
So instead use the below code:
vc.setOnSeekBarChangeListener(object: SeekBar.OnSeekBarChangeListener{
#Override
override fun onProgressChanged(
seekBar: SeekBar?, progress: Int,
fromUser: Boolean
){
Log.i(:"Seekbar changed", i = Integer.toString())
}
})
Related
XML File
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<app.rive.runtime.kotlin.RiveAnimationView
android:id="#+id/animationView"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_marginLeft="10dp"
android:layout_marginBottom="10dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:riveResource="#raw/loading_bar" />
</androidx.constraintlayout.widget.ConstraintLayout>
Kotlin file
package com.example.basicriveapp
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import androidx.startup.AppInitializer
import app.rive.runtime.kotlin.RiveAnimationView
import app.rive.runtime.kotlin.RiveInitializer
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
AppInitializer.getInstance(this)
.initializeComponent(RiveInitializer::class.java);
var animationView = findViewById<RiveAnimationView>(R.id.animationView);
animationView.pause();
}
}
Since I am trying to pause the Animation, it is not working and Can you please explain how to use play() and stop() methods with RiveAnimationView
You need to specify the animation name you want to play/pause inside the parentheses:
animationView.pause("animation name");
animationView.play("animation name");
You can get the animation name from the rive editor under the panel called "Animations"
I thought android had a diff mechanism to avoid redraw whole View tree when I invoke View::invalidate. Through checking the source code of View::invalidate, I find the invalidate
will propagate to ViewRootImpl and invoke ViewRootImpl::performTraversals. This method then draw whole view tree(except hardware acceleration enabled).
I try to find the code that View/ViewGroup can skip draw accroding dirty region, But I failed.Seems like erevry view will invoke onDraw
Below case, why does #id/frame_layout invoke onDraw when I change child #id/front backgroud color? Should't it refresh view locally?
layou.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:theme="#style/Theme.AppCompat.NoActionBar"
tools:context=".MainActivity">
<FrameLayout
android:id="#+id/frame_container"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintBottom_toBottomOf="#id/btn"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="#+id/layout_back"
android:background="#color/black"
android:layout_width="100dp"
android:layout_height="100dp"
/>
<FrameLayout
android:id="#+id/layout_front"
android:background="#color/white"
android:layout_width="100dp"
android:layout_height="100dp"
/>
</FrameLayout>
<com.google.android.material.button.MaterialButton
android:id="#+id/btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="switch color"
app:layout_constraintBottom_toBottomOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
package com.flybutter.demo
import android.graphics.Color
import android.os.*
import android.util.Log
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import android.widget.Toast
import androidx.lifecycle.LifecycleObserver
import com.bumptech.glide.Glide
import com.flybutter.demo.databinding.ActivityMainBinding
private const val TAG = "MainActivity"
class MainActivity : AppCompatActivity() {
lateinit var binding: ActivityMainBinding
var c = false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
binding.frameLayout.viewTreeObserver.addOnDrawListener {
Log.d(TAG, "onCreate: container ondraw")
}
binding.layoutFront.viewTreeObserver.addOnDrawListener {
Log.d(TAG, "onCreate: front on draw")
}
binding.layoutFront.viewTreeObserver.addOnDrawListener {
Log.d(TAG, "onCreate: back on draw")
Log.d(TAG,">>>>>>>>>>>>>>>>>>>")
}
binding.btn.setOnClickListener {
binding.layoutFront.setBackgroundColor( if (c) Color.WHITE else Color.GRAY)
c = !c
}
setContentView(binding.root)
}
}
I faced an error that actually mustn't occur, because I do exactly the same thing in my project in another screen, and it works there, but doesn't want to work in another screen.
The problem is the following: from an Activity in a result of some action I open up a DialogFragment which contains an image and other views in its layout file. Now I can't understand why, but it works in the first case (you'll see below) but doesn't work in the second...
First case:
Layout XML file (dialog_character_selector.xml):
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<variable
name="dialogViewModel"
type="neptun.jxy1vz.cluedo.ui.menu.character_selector.CharacterSelectorViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<Spinner
android:id="#+id/spinnerCharacter"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="#+id/ivCharacterCard"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_margin="20dp"
android:src="#drawable/szereplo_hatlap"
app:layout_constraintBottom_toTopOf="#+id/btnStart"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHeight_percent="0.7"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/spinnerCharacter" />
<Button
android:id="#+id/btnStart"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/start"
android:layout_marginBottom="10dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:onClick="#{()->dialogViewModel.startGame()}"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
The DialogFragment's Kotlin source code (CharacterSelectorDialog.kt):
package neptun.jxy1vz.cluedo.ui.menu.character_selector
import android.animation.AnimatorInflater
import android.animation.AnimatorSet
import android.app.Dialog
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.widget.AdapterView
import android.widget.ArrayAdapter
import androidx.appcompat.app.AlertDialog
import androidx.core.animation.doOnEnd
import androidx.databinding.DataBindingUtil
import androidx.fragment.app.DialogFragment
import neptun.jxy1vz.cluedo.R
import neptun.jxy1vz.cluedo.databinding.DialogCharacterSelectorBinding
class CharacterSelectorDialog : DialogFragment(), AdapterView.OnItemSelectedListener {
private lateinit var dialogCharacterSelectorBinding: DialogCharacterSelectorBinding
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
dialogCharacterSelectorBinding = DataBindingUtil.inflate(
LayoutInflater.from(context),
R.layout.dialog_character_selector,
null,
false
)
dialogCharacterSelectorBinding.spinnerCharacter.adapter = ArrayAdapter<String>(
context!!,
android.R.layout.simple_spinner_dropdown_item,
resources.getStringArray(R.array.characters)
)
dialogCharacterSelectorBinding.spinnerCharacter.onItemSelectedListener = this
//I do this due to a card flipping animation, it's not important, not part of my problem
val scale = resources.displayMetrics.density
dialogCharacterSelectorBinding.ivCharacterCard.cameraDistance = 8000 * scale
dialogCharacterSelectorBinding.dialogViewModel = CharacterSelectorViewModel(context!!)
return AlertDialog.Builder(context!!, R.style.Theme_AppCompat_Light_Dialog).setView(dialogCharacterSelectorBinding.root).setTitle(resources.getString(R.string.dialog_character_title)).create()
}
override fun onNothingSelected(parent: AdapterView<*>?) {
dialogCharacterSelectorBinding.ivCharacterCard.setImageResource(R.drawable.szereplo_hatlap)
}
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
dialogCharacterSelectorBinding.ivCharacterCard.setImageResource(R.drawable.szereplo_hatlap)
(AnimatorInflater.loadAnimator(context, R.animator.card_flip) as AnimatorSet).apply {
setTarget(dialogCharacterSelectorBinding.ivCharacterCard)
start()
doOnEnd {
dialogCharacterSelectorBinding.dialogViewModel!!.setPlayer(position)
val img = when (position) {
0 -> R.drawable.szereplo_ginny
1 -> R.drawable.szereplo_harry
2 -> R.drawable.szereplo_hermione
3 -> R.drawable.szereplo_ron
4 -> R.drawable.szereplo_luna
else -> R.drawable.szereplo_neville
}
dialogCharacterSelectorBinding.ivCharacterCard.setImageResource(img)
}
}
}
}
Second case:
Layout XML file (dialog_helper_card.xml):
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<variable
name="helperCardDialogViewModel"
type="neptun.jxy1vz.cluedo.ui.dice.card_dialog.helper.HelperCardViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/ivHelperCard"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_margin="20dp"
android:src="#drawable/mento_hatlap"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
I think in the main parts it's just the same as the previous one.
Kotlin source file (HelperCardDialog.kt):
package neptun.jxy1vz.cluedo.ui.dice.card_dialog.helper
import android.animation.AnimatorInflater
import android.animation.AnimatorSet
import android.os.Bundle
import android.view.LayoutInflater
import androidx.appcompat.app.AlertDialog
import androidx.core.animation.doOnEnd
import androidx.databinding.DataBindingUtil
import androidx.fragment.app.DialogFragment
import neptun.jxy1vz.cluedo.R
import neptun.jxy1vz.cluedo.databinding.DialogHelperCardBinding
class HelperCardDialog(private val cardResource: Int) : DialogFragment() {
override fun onCreateDialog(savedInstanceState: Bundle?): AlertDialog {
val dialogHelperCardBinding = DataBindingUtil.inflate<DialogHelperCardBinding>(LayoutInflater.from(context), R.layout.dialog_helper_card, null, false)
dialogHelperCardBinding.helperCardDialogViewModel = HelperCardViewModel()
(AnimatorInflater.loadAnimator(context, R.animator.card_flip) as AnimatorSet).apply {
setTarget(dialogHelperCardBinding.ivHelperCard)
start()
doOnEnd {
dialogHelperCardBinding.ivHelperCard.setImageResource(cardResource)
}
}
return AlertDialog.Builder(context!!, R.style.Theme_AppCompat_Dialog).setTitle(resources.getString(R.string.got_helper_card)).setNeutralButton(resources.getString(R.string.ok)
) { dialog, _ ->
dialog.dismiss()
}.create()
}
}
That's it. These are my most important files in my problem. Sorry for the lot of code...
I hope you will see where the problem is and tell me what's the solution for it.
Finally I found the error in my code. I left the setView() function call from the second AlertDialog.Builder().
The correct code snippet is:
return AlertDialog.Builder(context!!, R.style.Theme_AppCompat_Dialog)
.setView(dialogHelperCardBinding.root)
.setTitle(resources.getString(R.string.got_helper_card)).setNeutralButton(
resources.getString(R.string.ok)
) { dialog, _ ->
dialog.dismiss()
}.create()
I am using YoutubeplayerApi in my android app
what I have done is that there is a youtubeplayerView and a recycler view below the player
I want to implement the functionality that once a user click on the item view of recycler view the youtubeplayer should play that particular video but I am not able to implement that
any help would be appreciated
activity_music.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".UI.MusicActivity">
<com.google.android.youtube.player.YouTubePlayerView
android:layout_width="450dp"
android:layout_height="384dp"
android:id="#+id/youtube_player"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginTop="24dp"
/>
<android.support.v7.widget.RecyclerView
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:id="#+id/songs_recycler_view"
app:layout_constraintTop_toBottomOf="#+id/youtube_player"/>
</android.support.constraint.ConstraintLayout>
MusicActivity.kt
package com.example.ashish.batmn.UI
import android.content.Intent
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.support.v7.widget.LinearLayoutManager
import android.support.v7.widget.RecyclerView
import android.widget.Toast
import com.example.ashish.batmn.Adapters.SongsAdapter
import com.example.ashish.batmn.Config
import com.example.ashish.batmn.Models.Songs
import com.example.ashish.batmn.R
import com.google.android.youtube.player.YouTubeBaseActivity
import com.google.android.youtube.player.YouTubeInitializationResult
import com.google.android.youtube.player.YouTubePlayer
import com.google.android.youtube.player.YouTubeStandalonePlayer
import kotlinx.android.synthetic.main.activity_music.*
class MusicActivity : YouTubeBaseActivity(), YouTubePlayer.OnInitializedListener {
val songsList = listOf<Songs>(
Songs("Girls Like You","cBVGlBWQzuc","${Config.IMAGE_BASE_URL}cBVGlBWQzuc${Config.IMAGE_PIC_END}"),
Songs("The National - Fake Empire","KehwyWmXr3U","${Config.IMAGE_BASE_URL}KehwyWmXr3U${Config.IMAGE_PIC_END}"),
Songs("Halka Halka","nZhLM-FeV9A","${Config.IMAGE_BASE_URL}nZhLM-FeV9A${Config.IMAGE_PIC_END}"),
Songs("Camila Cabello - Real Friends","66rxB7_zzs8","${Config.IMAGE_BASE_URL}66rxB7_zzs8${Config.IMAGE_PIC_END}"),
Songs("Darya","wHHCO29mqiA","${Config.IMAGE_BASE_URL}wHHCO29mqiA${Config.IMAGE_PIC_END}"),
Songs("Naina Da Kya Kasoor","BJWTzYPWINw","${Config.IMAGE_BASE_URL}BJWTzYPWINw${Config.IMAGE_PIC_END}")
)
override fun onInitializationSuccess(provider: YouTubePlayer.Provider?, player: YouTubePlayer?, wasRestored: Boolean) {
if (!wasRestored){
player!!.cueVideo(Config.VIDEO_CODE)
player.setPlayerStyle(YouTubePlayer.PlayerStyle.DEFAULT)
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if(requestCode == 1){
getYoutubePlayerProvider().initialize(Config.VIDEO_CODE,this)
}
}
override fun onInitializationFailure(p0: YouTubePlayer.Provider?, errorResult: YouTubeInitializationResult?) {
if (errorResult!!.isUserRecoverableError){
errorResult.getErrorDialog(this,1).show()
}
else{
Toast.makeText(this,"Some unforseen error has occured",Toast.LENGTH_SHORT).show()
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_music)
youtube_player.initialize(Config.API_KEY,this)
val songAdapter = SongsAdapter(songsList,this){
// what should be added in here?
}
songs_recycler_view.layoutManager = LinearLayoutManager(this,LinearLayoutManager.VERTICAL,false)
songs_recycler_view.adapter = songAdapter
}
fun getYoutubePlayerProvider():YouTubePlayer.Provider{
return youtube_player
}
}
Songs.kt // Model class
package com.example.ashish.batmn.Models
class Songs(val mSongName:String, val mVideoCode:String,val mSongPic:String) {
}
First of all in onInitializationSuccess set player instance to a global field. Then Add a onClickListener to listview. After that in onClick method call player.setCue() method with the video id that you want to play. And at the last play the video with player.play().
I am using the new kotlin extension for view binding but I am having this annoying warning red underline message custom_button.setOnClickListener{} stating "Overload resolution ambiguity.."
I am trying to use my custom button class which extends Button class.
My activity class
package com.example.myapplication
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
custom_button.setOnClickListener { }
}
}
Custom button class
package com.example.myapplication
import android.content.Context
import android.widget.Button
class CustomButton(context: Context?) : Button(context)
XML
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<com.example.myapplication.CustomButton
android:id="#+id/custom_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>