I am trying to interact with dynamically generated buttons. I want to update text and background color for those player clicked and for those who is near by horizontal or vertical axis at the moment of a click.
What I've tried. I've found an id property of a button in XML which led me to idea that I can make a text key to refer to a programmatically generated button. But when I've tried to assign an id - IDE was expecting a number (Int), not a string. Since buttons form a square array - I decided to encode each button via 4 digit number where first 2 digits stand for a row number and other two stand for a column number. Though when I tried to use findViewById IDE told me that it was expecting a special id data type, not a number.
That's how it looks for now:
for (i in 1..size) {
for (j in 1..size){
val button = Button(this)
button.id = i*100 + j
constraintLayout.addView(button)
}
}
What idea or method could I look at?
If you created it dynamically you can save it in a variable (or an array) for later use.
val myButtons = ArrayList<Button>()
for (i in 1..size) {
for (j in 1..size){
val button = Button(this)
myButtons.add(button)
constraintLayout.addView(button)
}
}
if you have a layout with dynamically created views and you know their order you can get them with getChildAt(index).
Alternatively you can assign ids saved in xml like this.
Related
I am trying to create a small game with the following components:
9 cells - in a GridView
some words (that have to be introduced in the table, each on a cell)
TextToSpeech - on each cell
Each single cell contains one single word and the user has to choose one of the words displayed below in order to complete the cell (2 words are supposed to be in a cell).
Everything works perfectly, the only problem is that the TextToSpeech is being activated once the user chooses the right word, but I would want it to be one step forward. That means, once the user chooses the right word for ONE cell, the TextToSpeech should be automatically activated for the NEXT cell, so once the user has chosen the right word, he should hear the next word from the next cell.
These cells don't have ids, they are in the MainActivity, like this:
private fun setData() {
dataBeanArrayList = ArrayList<CellDataBean>()
val cellDataBean = CellDataBean()
//we store in the var cellDataBean both texts
//according to the class CellDataBean
cellDataBean.text_one = "Hello"
cellDataBean.text_two = "World"
dataBeanArrayList!!.add(cellDataBean)
val cellDataBean1 = CellDataBean()
cellDataBean1.text_one = "Okay"
cellDataBean1.text_two = "Not bad"
If I implement a new text view (which is not preferable), the TextToSpeech only works like I want for the first cell, once you press on this:
starttv.setOnClickListener {
if (count == 0) {
isstart = true
val text: String = dataBeanArrayList[count].text_1
textToSpeech!!.speak(text, TextToSpeech.QUEUE_FLUSH, null)
dataBeanArrayList[count].isSelected = true
cellAdapter!!.notifyDataSetChanged()
}
}
I am trying to implement something like: (where 'mainbacklay' is the ID from the cell)
when(vh.mainbacklay)[position]==0{
// here the text to speech should be enabled for the text from the second cell with the position 1
}
So when the position 2 from the cell is activated, the text to speech should be enabled for the text with the third position and so on.
Could someone help me figure this out, please?
Thank you.
I don't have a clear picture of exactly how your app operates, but I think you want something like this:
fun setAnswer(cellNumber: Int, text: String) {
// Update the data with the selected text etc
// Announce the text for cellNumber+1, or a fallback when there is no next cell
val message = dataBeans.getOrNull(cellNumber + 1)?.text_1 ?: "You're done!"
textToSpeech.speak(message, TextToSpeech.QUEUE_FLUSH, null)
}
and then whenever your event (a click or whatever) happens for cell n, you call that function. It takes care of handling that event, managing the overall state, and doing anything that needs to happen as a result (like announcing the next cell's contents, or moving to an endgame screen, etc.
Basically you don't want your individual cells / TextViews / ViewHolders managing that overall state and interacting with each other and each other's data. Just hand it off to a central function or component that manages what's going on, and tells the UI what to display. Makes it a lot easier!
Hope that helps, I can only be general without seeing exactly what you're doing
I have a TextView match parented for whole screen, and a text appended on it.
For example, the Raven poem:
Once upon a midnight dreary, while I pondered, weak and weary,
Over many a quaint and curious volume of forgotten lore,
While I nodded, nearly napping, suddenly there came a tapping,
As of some one gently rapping, rapping at my chamber door.
"'Tis some visiter," I muttered, "tapping at my chamber door—
Only this, and nothing more." etc etc etc...
I can't see it all on my phone screen.
So the question:
How can I get the index of the last visible character of the text?
How can I see it
If you want index then use,
val poem = "hello"
val lastCharacterIndex = poem.toCharArray().size - 1
If you want the Character at that index then use,
val character = poem.toCharArray()[index]
But I think you want to make your text view scrollable so that you can see the whole poem. Then you can use ScrollView as parent tag in XML then wrap the text view inside it.
Many many thanks for Mike M here the answer:
fun TextView.getLastVisibleCharacter(): Int {
val layoutBottom = height + scrollY - totalPaddingTop - totalPaddingBottom
val bottomLine = layout.getLineForVertical(layoutBottom)
val lastWhollyVisibleLineNumber =
if (layout.getLineBottom(bottomLine) > layoutBottom) bottomLine - 1
else bottomLine
return layout.getLineVisibleEnd(lastWhollyVisibleLineNumber) - 1
}
I need to put currency at the start of text and this text should be divide thousands by dots. Now I am using MaskedTextChangedListener from this library, so my code is following:
val listener = MaskedTextChangedListener(
"[000].[000].[000]",
true,monthlyInstallment.editText!!, null,null)
listener.rightToLeft = true
monthlyInstallment.editText?.addTextChangedListener(listener)
Here you can see that I added mask and used rightToLeft value in order to divide amount by dots. The problem is that if I will put currency to the start of mask like $[000].[000].[000], the currency appears only after I will fill all the mask, whereas I need to appear it when I will start typing.
Also I tried to put logic for adding currency in other TextChangeListener. My code is following
if(!monthlyInstallment.editText?.text.toString().startsWith("$ ")){
monthlyInstallment.editText?.setText("$ " + monthlyInstallment.editText?.text.toString())
Logger.msg("check " + monthlyInstallment.editText?.text.toString().length)
}
monthlyInstallment.editText?.setSelection(monthlyInstallment.editText?.text.toString().length)
Here problem is that my cursor is set somewhere, but not at the end of text. By the way, this code is placed into afterTextChangedListener method.
So can someone help me with one of the problem?
I ask this question in case we are working in Black box testing.
I have researched about Robotium for few day. I learn by myself from Internet.
I also wrote some simple testcase and run it successfully. But when I search the index element (ex: an Edittext, I have to try index by index form 0 to x and get my expect index id).
Can we have another way to get form name, I have the ID name (txtEd1, btnLogin...), which we can access it form R class in White box testing, but i just ask about Black box in this case.
So can we have another way to get element by id or how can we get exact index number of an element in the activity.
I also used Hierarchy Viewer from DDMS and SDK tool to get index ID but it didn't work.
TextView tw = (TextView) solo.getText(<index>); << how can get exact index number?
you can try another way to loop on your views and find the right one.
First, you need to get all the views, and then loop on them like below:
views = solo.getCurrentViews();
for (int i = 0; i < views.size(); i++) {
if (views.get(i).getClass().getName().equals("android.widget.TextView")) {
tw = (TextView) views.get(i); //DO-YOUR-CHECK-BLABLABLA
}
}
I'm currently using atmosphere framework. With this framework you can select an element by: resource-id, index, content description, text, etc. by creating a selector. Also you can select an element by Css/xPath query. For example:
...
UiElementSelector selector = new UiElementSelector();
selector.addSelectionAttribute(CssAttribute.INDEX, "your index");
screen.waitForElementExists(selector, WAIT_FOR_ELEMENT_EXISTS_TIMEOUT);
UiElement targetElement = screen.getElements(selector).get(0);
...
You may find more good examples here.
In my Application I want to Add and Remove View (like Button, or Textview, Checkbox ) by Coding (Programming ).
In Details:
I have One EditText and One Add Button. User Enter Anything in EditText and Press the Add Button then this one is added in bellow LinearLayout, and whether User click on his/her added Button it will going to next LinearLayout.
I get sucess upto this.
but when user click the button in second LinearLayout then it will come back on first Linearlayout. I am getting error Here, i don't know where I made a Mistake.
And I also facing Problem about how can I Store this all. Like User Add 5 Button and closed the application and whenever he/she came back to application I need whatever he/she previously added.
Here is what i done.
http://dynamicandroidview.blogspot.com/2011/12/how-to-add-view-in-android-by-coding.html
Try to create a database table with minimum 2 columns in your case it will be id and buttonText.
Now when user clicks on the add button it will save text to the database and will create the button dynamically below any buttons which are already created before or as a new button.
Now in your onCreate method get the count of text thats stored in database.Some thing like the following code:
DB getData = DB.getInstance();
getData.open(this);
ArrayList<TextHolder> getList = new ArrayList<TextHolder>();
getList = getData.getAllTextFromGeT();
getData.close();
x = genList.size();
Here x will be the number/count of elements that are already stored in the database.Now you can another int say i and using this i and x in the for loop you can create buttons dynamically.
Inside the loop you can do something like the following to get text for all the buttons that are being created:
TextHolder firstOne = getList.get(i);
String text = firstOne.getText();
You will also need class with getters and setters method in order to convert DB elements into objects.Like in the above code getText() is our getter method which is getting elements from database and returning it here.
here text will be the text of the button.
So every-time users starts the application he will see all the buttons that he created when he ran the application before and newly added button will appear on the spot and also will be stored in the database for future retrieval.
Remember we are just storing text of the button and assigning it unique id which helps us to create the buttons.Hope this helps