Get the text of a dynamically created textfield in android studio (Kotlin) - android

So I'm trying to figure out how I would get the text from a dynamically created EditText field.
This is the code for the dynamic Text fields
private fun AddToDoItem() {
val EditText = EditText(this)
EditText.gravity = Gravity.TOP
EditText.gravity = Gravity.CENTER
EditText.tag = "ExtraField" + i
LinearLayout?.addView(EditText)
i++
}
And this is the code where I want to get the Textfields text
Finish.setOnClickListener {
var x = 0
val userId = mAuth.currentUser!!.uid
val mcDatabase = FirebaseDatabase.getInstance().getReference()
mcDatabase.child("Users").child(userId).child(ToDoName.text.toString()).push()
while (x < i) {
val currentUserDb = mDatabaseReference!!.child(userId).child(ToDoName.text.toString())
currentUserDb.child(i.toString()).setValue("ExtraField" + x.text) //HERE IS WHERE I WANT TO SET THE TEXT
x++
Toast.makeText(this, "Finished.", Toast.LENGTH_LONG).show()
}
}
Where its commented like "//HERE IS WHERE I WANT TO SET THE TEXT" is where I want the .text string.
(It's in the while loop)

There are two ways to handle this:
You are adding the EditText's to a LinearLayout therefore you can iterate over its children - as described here and therefore replacing the while loop.
The second way would be to add the EditText's to a List<EditText> and iterate over it, replacing the while loop.
The first solution would probably be cleaner, but both of them work in a very similar fashion.
Hope this helps you!

Related

Adding two numbers from EditText fields

fun add(num1: EditText, num2: EditText){
try {
num1.toString().toInt()
num2.toString().toInt()
answer.setText((num1 + num2).toString())
} catch (e: NumberFormatException) {
answer.text = "Input Error"
}
}
I'm trying to make an integer calculator and have a problem.
answer.setText((num1 + num2).toString())
Here the addition symbol is highlighted in red. The text of the error is huge. What could be the problem?
Use getText() method of EditText to get the value from a EditText.
Change your code like the below
val value1 = num1.getText().toString().toInt()
val value2 = num1.getText().toString().toInt()
answer.setText((value1 + value2).toString())
Rafiul and Tenfour04 answer above is correct.. You need to take value from edittext before converting it to string. what you do at you code is convert the whole edittext to string not the value. And I think you need a variable to contain value from edittext. So it will look like this:
var a = num1.getText().toString().toInt()
var b = num2.getText().toString().toInt()
answer.setText((a + b).toString())
num1 and num 2 are EditTexts and you are adding the EditTexts.. this is the main mistake.
From your end you are type casting the values of EditTexts but not getting the values of editText and not saving in the separate variables.
Just get & save the values in separate variables: as #Bobby suggested:
var a = num1.getText().toString().toInt()
var b = num2.getText().toString().toInt()
And then perform addition.
answer.setText((a + b).toString())

Is there any way to create a textview with different color or with different styles in kotlin

I was learning DataStore in android development and in my project user will write a name in first activity.
and when user clicks button goes to second activity and my problem starts here:
but i want to show it like these photos:
or like this photo
I mean i want to make name colorful,but not in order,randomly
what i have tried:
i tried to take my name string to foreach but i could not change char colors my opinion was in foreach loop give any random color to every char but i could not.
then i tried SpannableStringBuilder and i get the result and these are my codes:
var random = Random()
var number1 = random.nextInt(value?.length?.minus(1) !! )
var number2 = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
random.ints(number1,value?.length !!).findFirst().asInt
} else {
TODO("VERSION.SDK_INT < N")
}
val spannableString = SpannableStringBuilder(value)
spannableString.setSpan(ForegroundColorSpan(Color.RED),
number1,number2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
textViewName.text = spannableString
i use just red color now but if i can make it randomly,i can make with other colors.
i hope you understand my problem and thanks for helping.
Since you have already figured out how to apply span to a specific character, for random colors you can simply make a list of colors as follows
val colorList = arrayListOf(Color.RED, Color.BLUE, Color.GREEN, Color.BLACK)
and so on and while you are assigning the span you can simply go like this
val randomColor = colorList.random()
colorList.remove(randomColor)
spannableString.setSpan(ForegroundColorSpan(randomColor),
number1,number2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)

Find button by ID in Kotlin

I have a user interface with multiple buttons. They have the IDs "button1", "button2", ...
I want to set an OnClickListener for all of them in a for loop. I dont want to type a line like button1.setOnClickListener for every button.
I have found one solution that works in java here: Android: Using findViewById() with a string / in a loop
And I tried to adapt it in Kotlin.
var buttons = ArrayList<Button>()
for (i in 1..7) {
var idString = "Button%i"
var buttonID = getResources().getIdentifier(idString, "id", packageName)
buttons.add( findViewWithTag(buttonID))
buttons[i].setOnClickListener(buttonclicked)
}
This throws an "Unresolved Reference" error. How can I access all buttons without typing a line for each of them?
Thanks in advance to all of you.
You call findViewWithTag() instead of findViewById() in your code.
Also you are not doing string interpolation correctly by var idString = "Button%i".
Change to this:
val buttons = ArrayList<Button>()
for (i in 1..7) {
val idString = "Button$i"
val buttonID = resources.getIdentifier(idString, "id", packageName)
buttons.add(findViewById(buttonID))
buttons[i].setOnClickListener(buttonclicked)
}

How to detect line breaks in TextView

In my Android App I've created 8 TextViews stacked on top of each other. Now I want to load in some plain text into those TextView-Lines. At the moment my Strings have a ";" as delimiter to indicate a line break, however it would be much more convenient if I would detect a linebreak automatically instead of using the hardcoded semicolon approach.
This is my String at the moment:
myString = "" +
"This seems to be some sort of spaceship,;" +
"the designs on the walls appear to be of;" +
"earth origin. It looks very clean here.;"
And in my other class I load in this string into the 8 TextViews, which I've loaded into an ArrayList, using the ";" as a delimiter.
public fun fillLines(myString: String) {
// How To Make Line Breaks Automatic??
for(i: Int in str until myString.split(";").size) {
if(i > textViewArray.size - 1) {
break
}
textViewArray[i].text = myString.split(";")[i]
textViewArray[i].alpha = 1.0f
}
}
Is there any way I can get the same result as shown above but without hardcoding the delimiter as ";" but instead somehow automatically detect the line break which would occur inside the TextView and then use this as a delimiter to advance through all 8 TextView "Lines".
The reason I need 8 TextViews Stacked On top of each other as individual "text lines" is because of an animation technique I want to use.
Line-breaking gets fairly complicated, so my recommendation would be that you allow a TextView to perform the measuring and layout to determine the line breaks. You could have an invisible TextView with the same style as your other views, and attach it to the layout so that it has the same width as your individual TextView instances. From there, add a layout change listener, and you can then retrieve the individual lines from the TextView Layout:
myTextView.text = // your text string here
myTextView.addOnLayoutChangeListener { view, _, _, _, _, _, _, _, _ ->
(view as? TextView)?.layout?.let { layout ->
// Here you'll have the individual broken lines:
val lines = (0 until layout.lineCount).map {
layout.text.subSequence(layout.getLineStart(it), layout.getLineVisibleEnd(it)
}
}
}
That said, this comes with the caveat that you'll lose out on hyphenation provided by the TextView, so you may wish to disable hyphenation entirely in your case.
You could fill text view with html. Below example.
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
tvDocument.setText(Html.fromHtml(bodyData,Html.FROM_HTML_MODE_LEGACY));
} else {
tvDocument.setText(Html.fromHtml(bodyData));
}
If your delimiter ; it is possible call method replaceAll(";", "<br>");
Ok I got it working now:
First you must add these properties for the textviews:
android:singleLine="true"
android:ellipsize="none"
Then you can do this:
public fun fillStorylines() {
val linecap = 46
var finalLine: String
var restChars = ""
val index = 9999
val text1: String = "" +
"This seems to be some sort of spaceship, " +
"the designs on the walls appear to be of " +
"earth origin. It looks very clean here. "
for(j: Int in 0..index) {
try {
finalLine = ""
val lines: List<String> = (restChars + text1.chunked(linecap)[j]).split(" ")
for (i: Int in 0 until lines.size - 1) {
finalLine += lines[i] + " "
}
textViewArray[j].text = finalLine
textViewArray[j].alpha = 1.0f
restChars = lines[lines.size - 1]
} catch (ex: Exception) {
break
}
}
}
If anyone knows a more elegant way to solve this please go ahead, your feedback is appreciated :)

Is Android java getResource.getIdentfier exist in IOS Swift?

My application has so many data. So There are so many textfield. Therefore I want to manage textView in iOS swift in the same way.
area1Layer = new TextView[25];
for(int k = 0; k < layer1; k++){// 층수 SET
area1Layer[k] = (TextView)findViewById(getResources().getIdentifier("layer"+(k+1),"id","kr.soen.areacard"));
area1Layer[k].setText(Integer.toString(k + 1) + "0" +ho1);
}
I assume that you want to identify the respective UITextField/UITextView seperately. This can be done by assigning different tags to the respective textfields/textviews.
let textField1: UITextField = UITextField()
textField1.tag = 1
let textField2: UITextField = UITextField()
textField2.tag = 2
and in the UITextFieldDelegate method,
func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
if textField.tag == 1 {
//Type your code here
}
if textField.tag == 2 {
//Type your code here
}
}
Also you could assign outlets to each textfield/textview, and use the outlets to check.
#IBOutlet weak var textField1: UITextField!
#IBOutlet weak var textField2: UITextField!
and in the UITextFieldDelegate method,
func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
if textField == textField1 {
//Type your code here
}
if textField == textField2 {
//Type your code here
}
}
The same can be done in the case of UITextView as well.
I believe that you want to identify each UITextField or UITextView separately and accordingly manipulate them. You can do it in the following way:
let textView1: UITextView = UITextView()
textView1.tag = 1
let textView2: UITextView = UITextView()
textView2.tag = 2
self.view.addSubview(textView1)
self.view.addSubview(textView2)
For identifying between different view objects, you can use .tag property in iOS by setting .tag in the above way.
To get different UITextView added to the self.view as a subView in swift, you can do the following:
if let textViewObject: AnyObject = self.view.viewWithTag(2) {
// first check is to identify if there is a given view with the tag
if let textView: UITextView = textViewObject as? UITextView {
}
}
The main difference is iOS uses an number based tag while Android uses a text key. You can accomplish the same thing with both. In iOS store all your labels in a collection and modify per tag. The collection type and syntax specifics for setting the tag depend on the way you wright your views.
After setting the tag via interface builder or view.tag = myTag; you can do something like:
for (int x=0; x<strings.count; x++){
UITextView *view = [self.view viewWithTag:x];
view.text = strings[x];
}

Categories

Resources