I have simple task. In recyclerView when I click on any button I would like to start camera, take photo and then capture this photo. However I'm not able to find any solution for this. What I tried in RecyclerAdapter.kt:
inner class ViewHolder(itemView: View):RecyclerView.ViewHolder(itemView) {
var textView1: TextView = itemView.findViewById(R.id.firma_textView1)
init {
textView1.setOnClickListener {
capturePhoto(context, activity)
}
}
}
fun capturePhoto(context: Context, activity: Activity) {
if (getCameraPermission(context)) {
val cameraIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
startActivityForResult(activity, cameraIntent, FirstFragment.CAMERA_REQUEST_CODE, null)
} else {
ActivityCompat.requestPermissions(activity, arrayOf(Manifest.permission.CAMERA), FirstFragment.CAMERA_REQUEST_CODE)
}
}
private fun getCameraPermission (context: Context):Boolean {
return ContextCompat.checkSelfPermission(context, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED
}
With this code I could start camera, take picture, but in RecyclerAdapter there is no way how to capture taken image.
Normal way how to capture image in Fragment is this:
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
var buttonCapturePhoto = view.findViewById<Button>(R.id.button)
buttonCapturePhoto.setOnClickListener {
capturePhoto()
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == CAMERA_REQUEST_CODE) {
print("photo captured")
}
}
private fun capturePhoto() {
if (getCameraPermission(requireContext())) {
val cameraIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
startActivityForResult(cameraIntent, CAMERA_REQUEST_CODE)
} else {
ActivityCompat.requestPermissions(requireActivity(), arrayOf(Manifest.permission.CAMERA), CAMERA_REQUEST_CODE)
}
}
private fun getCameraPermission (context: Context):Boolean {
return ContextCompat.checkSelfPermission(context, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED
}
I also found this article at Android Developer page - https://developer.android.com/training/basics/intents/result
They suggest to create class MyLifecycleObserver and use it in Fragment, but I'm not able to use this code in RecycleAdapter
lateinit var observer : MyLifecycleObserver
override fun onCreate(savedInstanceState: Bundle?) {
// ...
observer = MyLifecycleObserver(requireActivity().activityResultRegistry)
lifecycle.addObserver(observer)
}
I get error at activityResultRegistry and at lifecycle
I also created for testing this git repository: https://github.com/Katzzer/recyclerViewPhotoCaptureKotlinAndroid
You should pass your click event to fragment/activity
Create custom interface inside your adapter
Pass it into adapter constructor
// pass listener into constructor
class RecyclerAdapter(
val list:List<YourItemClass>,
val listener: OnItemClickListener) : ... {
// create a custom listener
interface OnItemClickListener{
fun onItemClick(view:View, position:Int)
}
inner class ViewHolder(itemView: View):RecyclerView.ViewHolder(itemView) {
// create function bind instead of using init block
fun bind(item:YourItemClass){
val textView1: TextView = itemView.findViewById(R.id.firma_textView1)
// if you want to change image in your ImageView , you could also pass
// your ImageView too
val imgView: ImageView = itemView.findViewById(R.id.imgView)
textView1.setOnClickListener { view ->
// this is just an example , but you get the idea
// listen click event and pass view and position
listener.onItemClick(view, adapterPosition)
// or
listener.onItemClick(imgView, adapterPosition)
}
}
}
...
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val item = list[position]
// bind here
holder.bind(item)
}
...
}
Initialized your adapter in Fragment/Activity
Listen to click event in Fragment/Activity
...
adapter = RecyclerAdapter(list, object : RecyclerAdapter.OnItemClickListener{
override fun onItemClick(view:View, position:Int){
// Listen your click event here
capturePhoto().also { result ->
// do something
// dont forget to call notifyItem if you want to update an item in
// RecyclerView
adapter.notifyItemChanged(position)
}
}
}
recyclerView.adapter = adapter
...
Create your capturePhoto function in Fragment\Activity
Related
I have a rotating carousel (using carouselrecyclerview) to rotate a list of images around.
The user can call a second activity and then search the images, and then return the selected image’s ID back to the MainActivity.kt.
The MainActivity.kt receives the result (using intent) in the onActivityResult.
I then need to call scrollToPosition (from the carouselLayoutManager) to move the carousel to the position that was selected in the second activity.
As the call to the carouselLayoutManager is within the onCreate, I can’t call it from the onActivityResult? I have tried moving the onActivityResult to within the onCreate, but then the onActivityResult is not called when returning from the second activity.
So, how can I call the code which is within the onCreate from the onActivityResult please?
Any help really appreciated as I’m struggling on this.
MainActivity.kt
...
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val carouselRecyclerview = findViewById<CarouselRecyclerview>(R.id.recycler)
val list = ArrayList<DataModel>()
// Load the images of the Veg
for (mycount in 0..41) {
list.add(DataModel(VegName[mycount].image, VegName[mycount].name))
}
val adapter = DataAdapter(list)
carouselRecyclerview.adapter = adapter
val carouselLayoutManager = carouselRecyclerview.getCarouselLayoutManager()
carouselLayoutManager.scrollToPosition(1)
carouselRecyclerview.setItemSelectListener(object : CarouselLayoutManager.OnSelected {
override fun onItemSelected(position: Int) {
var ShowIt = findViewById(R.id.textVegName) as TextView
//Cente item
ShowIt.text = list[position].text
}
})
Searchbutton.setOnClickListener {
val intent = Intent(this, SearchActivity::class.java)
startActivityForResult(intent, SEARCH_ACTIVITY_REQUEST_CODE)
}
// Move the carousel to the position received - THIS ISN'T CALLED?
fun setthelocation(SetThisPlace: Int ) {
carouselLayoutManager.scrollToPosition(SetThisPlace)
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == SEARCH_ACTIVITY_REQUEST_CODE) {
if (resultCode == RESULT_OK) {
val returnedfrom = VegName.find{ it.name == data?.getStringExtra("result") }
if (returnedfrom==null)
Toast.makeText(applicationContext, "Did not find the result returned!", Toast.LENGTH_LONG).show()
else {
Toast.makeText(applicationContext, "Got = " + returnedfrom.id, Toast.LENGTH_LONG).show()
//Need to call eiter setthelocation() or carouselLayoutManager.scrollToPosition???
return
}
}
}
}
As the call to the carouselLayoutManager is within the onCreate, I can’t call it from the onActivityResult?
I think you're confusing terms. There is no "call to the carouselLayoutManager" - that's a variable to assign to an object, not a function you call.
I have tried moving the onActivityResult to within the onCreate, but then the onActivityResult is not called when returning from the second activity.
onActivityResult is a base-class method that is invoked for you when you use startActivityForResult and close the opened activity. If you "move it to within the onCreate" all you're doing is calling the base class implementation (which does nothing).
So, how can I call the code which is within the onCreate from the onActivityResult please?
The easiest solution would be to hold on to the layout manager as a variable you can use in either onCreate or onActivityResult:
// Class-level property you can use in either function
private lateinit var carouselLayoutManager: LayoutManager
override fun onCreate(...) {
// Replace local val with class-level property
// Instead of this:
// val carouselLayoutManager = carouselRecyclerview.getCarouselLayoutManager()
// Do this: initialize member property to use here and in onActivityResult
carouselLayoutManager = carouselRecyclerview.getCarouselLayoutManager()
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == SEARCH_ACTIVITY_REQUEST_CODE) {
if (resultCode == RESULT_OK) {
val returnedfrom = VegName.find{ it.name == data?.getStringExtra("result") }
if (returnedfrom==null)
Toast.makeText(applicationContext, "Did not find the result returned!", Toast.LENGTH_LONG).show()
else {
Toast.makeText(applicationContext, "Got = " + returnedfrom.id, Toast.LENGTH_LONG).show()
//Need to call eiter setthelocation() or carouselLayoutManager.scrollToPosition???
// Now you can call this since it's a member property
carouselLayoutManager.scrollToPosition(...)
return
}
}
}
}
hm, for this I would recommend you to use the NavComponent and send your data through fragments or registering for activity but I don't want to confuse you and I will try to give you a solution for this problem.
I think the easiest way to solve this (in this context) would be to launch the intent as you are doing:
MainActivity.kt ->
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val carouselRecyclerview = findViewById<CarouselRecyclerview>(R.id.recycler)
val list = ArrayList<DataModel>()
// Load the images of the Veg
for (mycount in 0..41) {
list.add(DataModel(VegName[mycount].image, VegName[mycount].name))
}
val adapter = DataAdapter(list)
carouselRecyclerview.adapter = adapter
val carouselLayoutManager = carouselRecyclerview.getCarouselLayoutManager()
carouselLayoutManager.scrollToPosition(1)
carouselRecyclerview.setItemSelectListener(object : CarouselLayoutManager.OnSelected {
override fun onItemSelected(position: Int) {
var ShowIt = findViewById(R.id.textVegName) as TextView
//Cente item
ShowIt.text = list[position].text
}
})
Searchbutton.setOnClickListener {
val intent = Intent(this, SearchActivity::class.java)
startActivity(intent)
}
fun setTheLocation(SetThisPlace: Int ) {
carouselLayoutManager.scrollToPosition(SetThisPlace)
}
// onNewIntent would receive the intent needed to execute your logic.
// I wouldn't use onActivityResult because, IMO, It is dirty code and it is deprecated.
override fun onNewIntent(intent: Intent?) {
super.onNewIntent(intent)
if (intent?.hasExtra("position") == true) {
setTheLocation(intent.getIntExtra("position"))
}
}
SearchActivity.kt ->
override fun onCreate(savedInstanceState: Bundle?) {
...
.... your code ...
exampleOfSendingBackFunction()
}
//Here you will send back the position to MainActivity.kt clearing all flags.
fun exampleOfSendingBackFunction() {
val intent = Intent(this, MainActivity::class.java).apply {
flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP
putExtras(
"position" to yourPositionVariable
)
}
startActivity(intent)
}
I hope it helps :D
Trying to get a button to open another activity in android studio using kotlin. I am user a recycles view to do so. I have view card and want to edit the data in the card so I am user onClick to get the page to respond but that does seem to work I tried researching it but nothing come up that I can make sense of. Here is the code.
Thank you for all your help I appreciate it
This is the adapter class:
```class EventAdapter(var mListener: onItemClickListener, var context: Context, val items: ArrayList<EventModelk>):
RecyclerView.Adapter<EventAdapter.ViewHolder>() {
interface onItemClickListener {
fun onItemClick(position: Int)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val itemview = LayoutInflater.from(context).inflate(
R.layout.eventitems,
parent,
false,
)
return ViewHolder(itemview, mListener)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val item = items[position]
holder.setEmail.text = item.eEmail
holder.setNotes.text = item.nNotes
holder.setData.text = item.dDate
holder.setTime.text = item.tTime
if (item.repeat == 1) {
holder.setReap.isChecked = true
// holder.setReap.text = item.repeat.toString()
}
if (position % 2 == 0) {
holder.main.setBackgroundColor(
ContextCompat.getColor(
context,
R.color.colorLightGray
)
)
} else {
holder.main.setBackgroundColor(ContextCompat.getColor(context, R.color.colorWhite))
}
holder.pushimg.setOnClickListener {
if (context is UpdateDataInfo) {
(context as UpdateDataInfo).updateEvent(item)
}
}
// interface onItemClickListener{
// fun onItemClick(position: Int)
}
override fun getItemCount(): Int {
return items.size
}
class ViewHolder(view: View,onItemClickListener: onItemClickListener): RecyclerView.ViewHolder(view),onItemClickListener {
val main: CardView = view.IIMain
val setData: TextView = view.set_date
val setTime: TextView = view.set_time
val setEmail: TextView = view.Tv_email
val setNotes: TextView = view.set_note
val setReap: CheckBox =view.is_repeat
val pushimg: ImageView = view.img_edit
val onItemClickListener = onItemClickListener
override fun onItemClick(position: Int) {
onItemClickListener.onItemClick(absoluteAdapterPosition)
}
}
}```
This is my code for getting the click to go to another activity:
class CurrentSch : AppCompatActivity(), EventAdapter.onItemClickListener {
//private var change =imageView2?.isClickable
var STORAGE_LOCAL =true
val eventlist = ArrayList<EventModelk>()
#RequiresApi(Build.VERSION_CODES.N)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.currentsch)
btnNewApp2.setOnClickListener {
val intent = Intent(this, NewPlan::class.java)
startActivity(intent)
}
seeAllEventInPlan()
}
//private var change =imageView2?.isClickable
private fun getEventist(): ArrayList<EventModelk>{
val eventdatabase = EventDatabasek(this)
return eventdatabase.veiwEvent()
}
fun seeAllEventInPlan() = if(getEventist().size >0){
ryc_eventLists.visibility = View.VISIBLE
viewnotview.visibility = View.GONE
ryc_eventLists.layoutManager = LinearLayoutManager(this)
val eventAdapter = EventAdapter(this,this, getEventist())
ryc_eventLists.adapter = eventAdapter
}else{
ryc_eventLists.visibility = View.GONE
viewnotview.visibility = View.VISIBLE
}
override fun onItemClick(position: Int) {
val item = eventlist[position]
img_edit.setOnClickListener {
val intent = Intent(this, UpdateDataInfo::class.java)
intent.putExtra("Events", position)
startActivity(intent)
}
}
}
Inside the onBindViewHolder function, simply call mListener.onItemClick(position) for example if you wanted to open another Activity on click of setData, then you can write below code in onBindViewHolder
holder.setData.setOnClickListener { mListener.onItemClick(position) }
according to your above code , you have made callbacks where you calling thee adapter you will get callback there and you will open a activity there .. .. but you can simple open your new activity from adapter like this ..
holder.itemView.setOnClickListener(View.OnClickListener {
val intent = Intent (context,SomeActivity::class.java)
context.startactivity(intent)
})
I marked the parts that were added (added to code) after the moment
when the application was working, the data was successfully downloaded
from the database. I may be mistakenly trying to pass this information
to another screen. I tried to find a video that connects to the
database and forwards that data of recicler on another screen, but
without success, or they are in Java, which I understand less.
MySecondActivity
class BookDescription : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_book_description)
var books = intent.getSerializableExtra("noti") as Book //added to code
Glide.with(this).load(books.imageUrl).into(bookImg2)// added to code
nameTxt2.text = books.name //added to code
autorTxt2.text = books.writer //added to code
}
}
MainActivity
class MainActivity : AppCompatActivity() {
private lateinit var adapter : Adapter
private val viewModel by lazy { ViewModelProviders.of(this).get(MainViewModel::class.java)}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setUpRecyclerView()
}
private fun setUpRecyclerView(){
adapter = Adapter(this){
startBookDescription()
}
recycle.layoutManager = GridLayoutManager(this, 2)
recycle.adapter = adapter
observerData()
}
fun observerData(){
viewModel.fetchUserData().observe(this,Observer{
adapter.setListdata(it)
adapter.notifyDataSetChanged()
})
}
private fun startBookDescription(){
val intent = Intent (this, BookDescription::class.java )
startActivity(intent)
}
}
Class Adapter with inner class Holder
class Adapter(private val context: Context,
private val onItemCliked: () -> Unit ) : RecyclerView.Adapter<Adapter.Holder>() {
private var datalist = mutableListOf<Book>()
fun setListdata(data: MutableList<Book>){
datalist = data
}
inner class Holder(itemView : View) : RecyclerView.ViewHolder(itemView){
fun bindView(book: Book, onItemClicked: () -> Unit){
Glide.with(context).load(book.imageUrl).into(itemView.bookImg)
itemView.nameTxt.text = book.name
itemView.autorTxt.text= book.writer
itemView.setOnClickListener { onItemClicked.invoke() }
itemView.bookImg.setOnClickListener(View.OnClickListener { //added
val intent = Intent(context, BookDescription::class.java)//added to code
intent.putExtra("noti", book)//added to code
context.startActivity(intent)//added to code
})
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Holder {
val view = LayoutInflater.from(context).inflate(R.layout.book_format, parent,
false )
return Holder(view)
}
override fun onBindViewHolder(holder: Holder, position: Int) {
val book = datalist[position]
holder.bindView(book, onItemCliked)
}
override fun getItemCount(): Int {
return if (datalist.size> 0){
datalist.size
}else{
0
}
}
}
The problem is here:
intent.putExtra("noti", book)
The book variable is of type Book, which is apparently neither a Parcelable or Serializable class. You must implement one of these two interfaces in the Book class in order to add it to an Intent or Bundle.
Assuming Book is made up of simple data types (String, Int, etc), then you can use the #Parcelize annotation to easily implement Parcelable. More here: https://developer.android.com/kotlin/parcelize
In your bindView() method, you have this block of code:
val intent = Intent(context, BookDescription::class.java)//added to code
intent.putExtra("noti", book)//added to code
context.startActivity(intent)//added to code
})
However, you don't actually do anything with this Intent; you start your activity from another place:
private fun startBookDescription(){
val intent = Intent (this, BookDescription::class.java )
startActivity(intent)
}
You will have to pass the Book instance to this method (via invoke(book)). This will require a corresponding type change to the click listener parameter of your adapter.
Users can show their photo on the imageView button. Codes are given below.
The problem is, savedInstanceState returns null since photo on the imageView is obtained in the onActivityResult function.
Therefore, if users click on btnRegistration and come back to this app again, they lose photo on the imageView.
Could you please help, how to edit these codes to solve this problem
private var iv_crop: ImageView = null
public var tmpResultUri: Uri?=null
public override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (requestCode == CropImage.CROP_IMAGE_ACTIVITY_REQUEST_CODE) {
val cimg = CropImage.getActivityResult(data)
iv_crop.setImageURI(cimg.uri)
val resultUri = cimg.uri
tmpResultUri = resultUri
}}
#RequiresApi(Build.VERSION_CODES.O)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (savedInstanceState != null) {
var strResultUri: String?= null
strResultUri = savedInstanceState.getString(strResultUri)
// var drawable: BitmapDrawable = iv_crop.getDrawable() as BitmapDrawable
//var bitmapImgCropped = drawable.getBitmap()
}
else {
iv_crop.setOnClickListener {
CropImage.activity().start(this) // <== Starts a new activity here.
}
}
btnRegistration?.setOnClickListener {
val intent = Intent()
intent.setClassName( "com.mylab.myApp","com.mylab.myApp.MainActivity")
startActivity(intent) // <== Starts a new activity here.
finish()}
}
override fun onSaveInstanceState(outState:Bundle ) {
outState.run{
outState.putString(tmpResultUri.toString(), tmpResultUri.toString())
}
super.onSaveInstanceState(outState)
}
override fun onRestoreInstanceState(savedInstanceState: Bundle?) {
super.onRestoreInstanceState(savedInstanceState!!)
savedInstanceState.run {
val strtmpResultUri = getString(tmpResultUri.toString())
}
}
You need to store your image URI using a static key. Something like this.
companion object {
private const val ARG_IMAGE_URI = "imageuri"
}
Then when you save and retrieve your URI, use this value as your key and not the uri.
override fun onSaveInstanceState(outState:Bundle ) {
outState.putString(ARG_IMAGE_URI, tmpResultUri.toString())
super.onSaveInstanceState(outState)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (savedInstanceState != null) {
val strResultUri: String?= savedInstanceState.getString(ARG_IMAGE_URI)
}
}
My MainActivity implements the Observer class. I also have a class called ObservedObject that extends the Observable class.
Here is my custom Observable , called ObservedObject:
class ObservedObject(var value: Boolean) : Observable() {
init {
value = false
}
fun setVal(vals: Boolean) {
value = vals
setChanged()
notifyObservers()
}
fun printVal() {
Log.i("Value" , "" + value)
}
}
Here is my Application called SpeechApp which contains my ObservedObject (an Observable actually):
class SpeechApp: Application() {
var isDictionaryRead = ObservedObject(false)
override fun onCreate() {
super.onCreate()
wordslist = ArrayList()
Thread {
execute()
}.start()
}
fun execute() {
while (/* Condition */) {
//Log.i("Read" , line)
/*Does Something Here*/
}
isDictionaryRead.setVal(true)
}
}
In my MainActivity, I mainly have a dialog, that should be displayed after I have got the output after Speech Recognition. It will display as long as the value of isDictionaryRead doesn't change to true:
class MainActivity(private val REQ_CODE_SPEECH_INPUT: Int = 100) : AppCompatActivity() , Observer{
override fun update(o: Observable?, arg: Any?) {
(o as ObservedObject).printVal()
dialog.hide()
}
private lateinit var app : SpeechApp
private lateinit var dialog: MaterialDialog
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
dialog = MaterialDialog.Builder(this)
.title("Please Wait")
.content("Loading from the Dictionary")
.progress(true , 0)
.build()
app = application as SpeechApp
app.isDictionaryRead.addObserver(this)
}
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
menuInflater.inflate(R.menu.menu_speech, menu)
return true
}
override fun onOptionsItemSelected(item: MenuItem?): Boolean {
val id = item?.itemId
when(id) {
R.id.menu_option_speech -> {
invokeSpeech()
}
}
return super.onOptionsItemSelected(item)
}
private fun invokeSpeech() {
/* Does Something, Works Fine */
try {
startActivityForResult(intent , REQ_CODE_SPEECH_INPUT)
}
catch (ex: ActivityNotFoundException) {
/* Does Something */
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
when (requestCode) {
REQ_CODE_SPEECH_INPUT -> {
if (resultCode == Activity.RESULT_OK && null != data) {
dialog.show()
}
}
}
super.onActivityResult(requestCode, resultCode, data)
}
}
Now the problem is, when the SpeechApp sets the value of isDictionaryRead to true, I expect it to call the MainActivity update() method, wherein I have given the code to hide the dialog. That particular code is not working, and my dialog box doesn't go away. Where am I going wrong?
PS. I've pushed my code to Github now, just in case anyone could help me where I am going wrong.
The only thing I can think of that would cause this problem is that the execute() thread that was started in SpeechApp.onCreate finished execution and called isDictionaryRead.setVal(true) before the activity could call app.isDictionaryRead.addObserver(this). As a result, notifyObservers is called before the activity even starts observing, and as a result it is not notified. Here's my proposed solution: Start the execute thread in the activity's onCreate method after adding it as an observer.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
dialog = MaterialDialog.Builder(this)
.title("Please Wait")
.content("Loading from the Dictionary")
.progress(true , 0)
.build()
app = application as SpeechApp
app.isDictionaryRead.addObserver(this)
app.asyncReadDictionary()
}
Then remove the thread call from SpeechApp.onCreate and use this instead
// in SpeechApp
fun asyncReadDictionary() {
if (!isDictionaryRead.value) {
Thread { execute() }.start()
}
}
private fun execute() {
while (/* Condition */) {
//Log.i("Read" , line)
/*Does Something Here*/
}
isDictionaryRead.value = true
}
Also, reimplement ObservableObject as follows
class ObservedObject : Observable() {
var value: Boolean = false
set(newValue) {
field = newValue
setChanged()
notifyObservers()
}
fun printVal() {
Log.i("Value" , "" + value)
}
}