push string to array from another activity - android

my aplication
I have 2 activity, the first is CategoryActivity and the second is QuestionActivity.
in CategoryActivity i have a recyclerview which lists categories, and also in Category Activity, i have an array. When i click eksterior, it will go to questionActivity, and when i click submit, it will back to CategoryActivity and send data to CategotyActivity. the data sent was entered into the array, so the array will be like this: array [] = {“1”}; then i click the second item in recyclerview which is interior, then it will go to QuestionActivity again, when i click submit, it will send data to CategoryActivity and add it into the previous array, so the array will be like this : array [] = {“1”,”1”}; and so on until the items on the recyclerview run out. I have tried like this :
QuestionActivity.kt
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_result)
button_save.setOnClickListener(){
val intent = Intent(this#ResultActivity, KategoriActivity::class.java)
intent.putExtra(KategoriActivity.Companion.ARRAY, "1")
startActivity(intent)
}
}
CategoryActivity.kt
var list = arrayOf(intent.getStringExtra(ARRAY))
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_category)
Toast.makeText(this#KategoriActivity, ""+ list, Toast.LENGTH_SHORT).show()
}
companion object {
val ARRAY = "array"
}
override fun onBackPressed() {
Toast.makeText(this#KategoriActivity, ""+ list, Toast.LENGTH_SHORT).show()
if (list.size == kategoriDatas!!.size){
onBackPressed()
} else {
val builder = AlertDialog.Builder(this)
builder.setMessage("You Must Finish All The Category")
// add a button
builder.setPositiveButton("OK", null)
// create and show the alert dialog
val dialog = builder.create()
dialog.show()
}
}
and the problem is when i open category activity the app is stopped, and the log is say Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.content.Intent.getStringExtra(java.lang.String)' on a null object reference
and the data can not push to the array, please help me

You can only get the intent after the activity has been created. In order to make sure of it it's best if you place the code that's gonna get the extras from Intents inside your onCreate.
Like this:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_category)
Toast.makeText(this#KategoriActivity, ""+ list, Toast.LENGTH_SHORT).show()
var list = arrayOf(intent.getStringExtra(ARRAY))
}
If you want to have an Application class that holds information:
class MyApplication : Application(){
var list = emptyArray<String>()
override fun onCreate() {
super.onCreate()
}
}
To use it in your activity:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_category)
Toast.makeText(this#KategoriActivity, ""+ list, Toast.LENGTH_SHORT).show()
var list = (application as MyApplication).list
// you can than use it to update or retrieve values from it
}

Related

How to return data from a dialog box to the main activity in android?

I am making a list app using rooms for database. I created a dialog box to add things to the list. How do I return the data from a dialog to add items to the main activity.
AddListDialog.kt
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.dialog_add_url)
tvAddToLib.setOnClickListener{
val content = etContent.text.toString()
if (content.isEmpty()){
Toast.makeText(context, "Enter Text", Toast.LENGTH_SHORT).show()
return#setOnClickListener
}
val item = UrlList(addTime, content, readTime = null)
addDialogListener.onAddButtonClicked(item)
dismiss()
}
tvCancel.setOnClickListener {
cancel()
}
}
Main Activity.kt
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val dao = ListDao
val repository = UrlRepository(dao)
val factory = ListViewModelFactory(repository)
val viewModel = ViewModelProviders.of(this, factory).get(ListViewModel::class.java)
val adapter = ListAdapter(listOf(), viewModel)
rvListenItems.layoutManager = LinearLayoutManager(this)
rvListenItems.adapter = adapter
viewModel.getList().observe(this, Observer {
adapter.items = it
adapter.notifyDataSetChanged()
})
fabAdd.setOnClickListener {
AddUrlDialog(this, object : AddDialogListener{
override suspend fun onAddButtonClicked(item: List) {
viewModel.upsert(item)
}
}).show()
}
Adddialoglistener.kt
import com.example.listen.data.db.entities.List
interface AddDialogListener {
suspend fun onAddButtonClicked(item : List)
}
have you tried to use a new .xml layout and ContentView(layoutid) it on your main activity as a dialog ? lets make one dialog with list now.
first make your .xml layout that will contain a list, we will use as a dialog to return any actions from it in the same kotlain main class.
see pictures ^_^ i hope it will work, good luck.
step1
step2
step3
step4
step5
step6
step7
step8
i have made a horizontal list of buttons instead, i thought it would be cool !, but you can put anything in your .xml layout then as i illustrated .show()
it as dialog setting it in the contentView(layoutID) of the dialog you have initiated in anywhere ^_^, good luck.

Passing a value from a dropdown list in a fragment to another activity (Kotlin)

I am making an app (ehealth portal) in Android Studio using Kotlin language and in that app, the user should be able to book an appointment choosing date/time/doctor's name from a dropdown list, and once they push the "book a date" button a confirmation screen appears that has the values of the dropdown lists (date/time/doctor's name) passed into a confirmation text confirmation activity instance booking a dated interface.
CalendarFragment.kt
package com.example.mydoctor
import...
class CalendarFragment : Fragment() {
private lateinit var binding: FragmentCalendarBinding1
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setHasOptionsMenu(true)
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
super.onCreate(savedInstanceState)
binding = FragmentCalendarBinding1.inflate(layoutInflater)
val itemsDates = resources.getStringArray(R.array.dates)
val adapterDate = ArrayAdapter(requireContext(), list_dates, itemsDates)
binding.autocompleteTextViewDateDropdown.setAdapter(adapterDate)
val itemsTimes = resources.getStringArray(R.array.times)
val adapterTime = ArrayAdapter(requireContext(), list_times, itemsTimes)
binding.autocompleteTextViewTimeDropdown.setAdapter(adapterTime)
binding.bookADateButton.setOnClickListener {
val intent = Intent(requireContext(),ConfirmationActivity::class.java)
intent.putExtra("Confirmation","Confirmation Value")
startActivity(intent)
}
return binding.root
}
}
ConfirmationActivity.kt
package com.example.mydoctor
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
class ConfirmationActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_confirmation)
val value = intent.getStringExtra("Confirmation").toString()
Log.d("conf","Values is: ${value}")
}
}
How can I go about that? I know I have to use getExtra() or getStringExtra() but how should I actually get the value from the calendar fragment?
EDIT:
I tried changing the setOnClickListener in the CalendarFragment.kt as follows but it does not seem to work storing the value:
binding.bookADateButton.setOnClickListener {
(date_dropdown.getEditText() as AutoCompleteTextView).onItemClickListener =
OnItemClickListener {
adapterView, view, position, _ ->
val selectedValue: String? = adapterDate.getItem(position)
}
val intent = Intent(requireContext(),ConfirmationActivity::class.java)
intent.putExtra("Confirmation","Confirmation Value")
startActivity(intent)
}
You have to setup your date_dropdown listener outside of the setOnClickListener, otherwise you only start listening to date_dropdown changes after the first click is made, which is already too late.
So change the order in your code
// have a variable to track the last selected value with a larger
// scope somewhere inside your Fragment
var selectedValue: String? = null
(date_dropdown.getEditText() as AutoCompleteTextView).onItemClickListener =
OnItemClickListener { adapterView, view, position, _ ->
// this code block is called every time an item is clicked
selectedValue = adapterDate.getItem(position)
}
binding.bookADateButton.setOnClickListener {
// this code block is called every time the 'bookADateButton' is clicked
val intent = Intent(requireContext(), ConfirmationActivity::class.java)
intent.putExtra("Confirmation", selectedValue ?: "No value was selected.")
startActivity(intent)
}
There is also the setOnItemSelectedListener available, if you don't want to rely on clicks/taps.

Display text on a text view box (Android)

I am a beginner in Android. I have two layout resource files as shown above.
I want to type a word in the first one and click the button, then it is suppose to go to the 2nd layout resource file and display the word on the text view box. I keep getting an error whenever I try.
Below is the code I wrote
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setSupportActionBar(toolbar)
button.setOnClickListener {
startActivity(Intent(this, NewLayoutActivity::class.java))
}
}
for the new layout activity
class NewLayoutActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.new_layout)
textView.text = ${editText.text}
}
you should try `intent
var data2 = editText.text.toString
val intent = Intent(applicationContext,secondActivity::class.java)
intent.putExtra("name",data2)
startActivity(intent)
in the second
val data = intent.getStringExtra("name")
you should learn navigation its better and easier
pass data with intent while open new activity:
val intent = Intent(this, NewLayoutActivity::class.java)
intent.putExtra("value", "value you want to pass")
startActivity(intent)
And get in second activity as:
var bundle :Bundle ?=intent.extras
var message = bundle!!.getString("value") // if the value is type of String
change your code from this
button.setOnClickListener {
startActivity(Intent(this, NewLayoutActivity::class.java))
}
to this
val value = edit_text_id.text
button.setOnClickListener {
startActivity(Intent(this, NewLayoutActivity::class.java)
.putExtra("key", value))
}
then, get your value on second activity with this
val value = Intent().getStringExtra("key")
text_view_id.text = value

Android Kotlin Starting Activity From Utils Class Results In SavedInstanceState Being Null

Just to clarify beforehand, I have searched extensively in SO for similar question to find an answer to my question.
I will reference the following (to name a few sources) :
How to start a new activity from a non activity class in Android kotlin?
Start a new Activity from non Activity class
Basic Kotlin Tutorial
I have a MainActivity and four other different activities, let's call them A through D.
I also have a Utilities class which sets on click listeners to image buttons found in activities A through D.
These listeners then open a new activity, E.
For some reason, in the onCreate method for activity E, savedInstanceState is always null.
I have tried setting the listener from the MainActivity, but to no avail.
I have also passed the context from the MainActivity (instead of using the scroll view's), but that had not effect either
Below is a snippet of the code.
Utilities.kt
class Utilities {
companion object {
/...
fun setTooltipsAndListeners(scrollView: ScrollView) {
val buttons: ArrayList<View> = scrollView.touchables
for (button in buttons) {
val tooltipText = button.contentDescription
if (tooltipText != null) {
TooltipCompat.setTooltipText(button, tooltipText)
}
button.setOnClickListener(object : View.OnClickListener {
override fun onClick(v: View?) {
val tag: String? = v?.tag as? String
val intent = Intent(scrollView.context, ActivityE::class.java)
intent.putExtra("symbol_name", tooltipText)
intent.putExtra("symbol_image", tag)
scrollView.context.startActivity(intent)
}
})
}
}
/...
}
ActivityE.kt
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.layout_name)
setDataToUI(savedInstanceState)
}
private fun setDataToUI(savedInstanceState: Bundle?) {
if (savedInstanceState == null) {
Log.d("TAG", "savedInstanceState IS NULL")
return
}
/... Inner logic that is not relevant
}
Instead of savedInstanceState you need to use getIntent(). So your code will change like this:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.layout_name)
setDataToUI(intent)
}
private fun setDataToUI(intent: Intent?) {
if (intent.getStringExtra("symbol_name") == null) {
Log.d("TAG", "No data passed for symbol_name")
return
}
// Do the same for other strings. Or alternatively, you can pass Bundle
// data from your Utility and retrieve the bundle through the intent as well
}
savedInstanceState is used to store data when the state of the activity is changed, but you are passing data through an Intent in your utility class

Null object reference when using string resources for ListView

Why is it that whenever I try to use a simple array for a ListView, I get this error?:
Attempt to invoke virtual method 'android.content.res.Resources android.content.Context.getResources()' on a null object reference
I really don't get what I'm doing wrong here as I've tried using different contexts (base and application) but still no change in solving this issue.
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
var array = arrayOf(resources.getString(R.string.item_a),
resources.getString(R.string.item_b),
resources.getString(R.string.item_c),
resources.getString(R.string.item_d))
val adapter = ArrayAdapter(this,
R.layout.listview_item, array)
val listView:ListView = findViewById(R.id.listview_1)
listView.setAdapter(adapter)
}
override fun onItemClick(view: View, position: Int) {
if (array[position] == resources.getString(R.string.item_a)){
Toast.makeText(this, "Hi there! This is a Toast.", Toast.LENGTH_SHORT).show()
}
}
}
Two things going on here.
First, if you declare and initialize an array of string resources at the class level of your activity, you will get an error. Your activity isn't "ready" immediately when it is constructed; it needs to have super.onCreate() called before you'll be able to access resources.
Second, if you move the entire array inside onCreate() then you won't be able to access it from onItemClick() (since now it is local to onCreate).
The solution is to use a lateinit var so that you can declare your array at the class level but then initialize it inside onCreate():
class MainActivity : AppCompatActivity() {
private lateinit var array: Array<String>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
this.array = arrayOf(...)
// ...
}
override fun onItemClick(view: View, position: Int) {
if (array[position] == resources.getString(R.string.item_a)){
// ...
}
}
}

Categories

Resources