Adding mask and thousand delimeter to EditText - android

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?

Related

Phone number format for EditText

I am using library input-mask-android to format the text as user is typing.
I have an array of phone number masks. By default, the very first mask in the array is selected. The user can choose a different mask using the Spinner. But when the user selects a mask using the Spinner, it does not work as he would like.
Suppose the array of masks contains two masks: ["+12 - ###", "+34 - ###"]. If the user selects the second mask, then the following will appear when typing into the EditText:
Entered 5 will:
+34-512.
That is, after entering it will automatically put the key characters of the previous mask.
My code in Kotlin:
val listener: MaskedTextChangedListener = installOn(
etPhoneNumber!!,
maskT,
affineFormats, AffinityCalculationStrategy.PREFIX,
object : ValueListener {
override fun onTextChanged(
maskFilled: Boolean,
extractedValue: String,
formattedValue: String
) {
logValueListener(maskFilled, extractedValue, formattedValue)
Log.e("CHANGE FORMAT:", affineFormats.toString())
}
}
)
maskT - is the selected mask
affineFormats - dynamic array where the last mask is stored.
Any suggestions would be greatly appreciated.
input-mask-android library author here.
The installOn method won't suit your needs. You've got to manually initialise a MaskedTextChangedListener, then call an addTextChangedListener method on your EditText. On mask select, you've got to make sure the previous listener is removed (by calling a removeTextChangedListener on your EditText).
The installOn method does not consider there could be other TextWatcher instances attached to your EditText. Thus, all of those installed listeners are trying to take over the text, adding their own "+12" and "+34" prefixes simultaneously.

How to refer to a dynamically generated button?

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.

How to select all text in a text field in monkeyrunner?

Actually I want to delete all text in a text field, and I am using a loop calling device.press('KEYCODE_DEL') to achieve this.
But there are two disadvantages:
Not efficient enough, especially when I don't know how many
characters in the text field so I need set a large enough loop
Need to move the cursor to the end before deleting
So I am trying to accomplish this by two steps:
select all text
press delete button
I found an similar question here which is not solved yet.
And there is an answer for how to select all text, but I think it has the same issues as my loop delete way.
I did several tests, and found a way close to it:
device.press('KEYCODE_MENU', 'MonkeyDevice.DOWN', '')
device.press('KEYCODE_A')
device.press('KEYCODE_MENU', 'MonkeyDevice.UP', '')
I thought these three steps accomplish a MENU+A operation. But it did not work every time. I executed this code for 20 times(in a loop) and found it only took effect for about 5-8 times.
Besides, I found these three steps will move the cursor to the first place most of the time.
Did anyone know why is this operation not reliable? Or any other suggestions to select all text?
Appreciate for any suggestions!
AndroidViewClient's EditText has a method for that:
def setText(self, text):
"""
This function makes sure that any previously entered text is deleted before
setting the value of the field.
"""
if self.text() == text:
return
self.touch()
guardrail = 0
maxSize = len(self.text()) + 1
while maxSize > guardrail:
guardrail += 1
self.device.press('KEYCODE_DEL', adbclient.DOWN_AND_UP)
self.device.press('KEYCODE_FORWARD_DEL', adbclient.DOWN_AND_UP)
self.type(text, alreadyTouched=True)
Using AndroidViewClient its pretty easy. Try this code-
editText= vc.findViewByIdOrRaise(EDITTEXT ID in quotes)
(x,y) = editText.getXY()
editText.device.drag((x,y), (x,y), 2000, 1)
vc.dump()
device.press('KEYCODE_DEL')

How can I have a multiple line Label in a PieChart in AChartEngine?

I have a pie chart using AChartEngine that I'm very happy with. I've chosen to style it without a Legend and with Labels (the text connected to its corresponding Pie wedge with a little line) formatted like "Example Data Point - 25%"
I get this Label string via:
mSeries.add(name + " - " + Double.toString(value), value);
But often the name is too long so the value doesn't display. I get "...". Since the value is important, I want to put it on a new line so it will always show.
I'm picturing Labels that look something like:
Short Name
10%
Too Long of A Na...
25%
Also fine:
Too Long of A
Name
25%
Or:
Too Long of A
Name - 25%
If I could wrap long names to new lines, that would be even better! But I really am mostly concerned with getting the Value to always display.
I tried to add a new line with \n or System.getProperty("line.separator") but the PieChart still renders the Label as one line. The \n is not getting displayed as text, it's like it's not even there. According to other Questions, this supposedly works on other Chart types, but no one is claiming it works for Pies, which it doesn't seem to based on my efforts.
I've also played with other rendering options built into AChartEngine. Such as 'setDisplayValues(true)', which puts the values right over the pie wedges. I don't like how that looks, as my pie has some tiny wedges, so the values get rendered on top of each other.
Any insight on how I can make the Labels on AChartEngine PieChart multi-line (or any other way to force the value to display) would be very appreciated! Thank you so much to anyone who can help!
It's not what I really wanted, but since a few months have gone by, I've come up with an alternative. For posterity, I will leave it here as an answer to my own question but not accept it in case someone out there does someday share a real solution.
Since I couldn't find a way to ensure that the labels on my pie chart always showed percent values, I have the info Toast when a wedge is clicked. Here is the simple enough code:
private void addPieClickListeners(final GraphicalView mChartView){
mChartView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
SeriesSelection seriesSelection = mChartView.getCurrentSeriesAndPoint();
if (seriesSelection == null) {
// Do Nothing, Possible Toast:
// Toast.makeText(context,"No chart element was clicked",Toast.LENGTH_SHORT).show();
}
else {
Toast.makeText(context,
Integer.toString((int)Math.round(seriesSelection.getValue())) +
"% " +
mSeries.getCategory(seriesSelection.getPointIndex()),
Toast.LENGTH_SHORT).show();
}
}
});
I call this method, along with my other functions to set up my Pie Chart, in onCreateView(), since this is in a Fragment.
Cheers.

Add text to the beginning of a new line, if the text is automatically wrap

At the outset, I would like to apologize for my English :).
I have a String with long text. I display it in a TextView. If the text is automatically wrapped to new line, I want to add "\t" at the beginning of the new line. I don't know how do it. Any ideas?
E.g.
String text = "1. abcdefghij\n\tklmnopqrstuvwxyz";
Display:
1. abcdefghij
klmnopqrstuvwxyz
But if:
String text = "1. abcdefghij\n\tklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
Display:
1. abcdefghij
klmnopqrstuvwxyzABCDEF
GHIJKLMNOPQRSTUVWXYZ
I want:
1. abcdefghij
klmnopqrstuvwxyzABCDEF
GHIJKLMNOPQRSTUVWXYZ
You can count the lines of your TextView and if there are more than 1 insert a "\t".
In this post it's shown how to count the lines although is not an obvious question.
You also need to take into account if the tab is already inserted, because could be inserted more than one \b.

Categories

Resources