I am using "findAll" on a webview, it works correctly, but do not know how I can retrieve the number of matches for if greater than 0 to show a button in that case.
Refer this
Returns
: the number of occurances of the String "find" that were found
So if you use
int count = mWebView.findAll(searchString);
then count will hold occurrence of a searchString text in webview.
Hope this helps.
Since findAll has this nasty bug returning 0 even if it matches and the function is deprecated:
findAllAsync Seems to be the way to go.
Its a little more work though since you need to implement a WebView.FindListener
The results returned through that are also structured a bit differently and more difficult to handle.
webView.setFindListener(yourFindListener);
webView.findAllAsync("some string")
What also can be tricky is delaying the search until the site is fully rendered which is another tricky topic on its own. (depending on the page and its JS usage)
Related
How do I implement this condition as shown in this image.
That's just in 2..4, i.e. in the integer range from 2 to 4, including the 4.
The ≤ is just some hint text provided by the IDE, similar to how you can see argument names in function calls - it's not part of the code, it's not really there. They added it to make it clearer what the .. operator does (vs until)
This might be because they're introducing a new operator, ..< which seems intended to replace until, or maybe they've been there a while! You can turn them on and off here in the settings:
I am trying to extract the X and Y component using a regular expression from the following data:
{"SearchResults":[{"PageCount":"0"},
{"SEARCHVAL":"530106","CATEGORY":"Building",
"X":"103.8907","Y":"1.3537"}]}
This is the pattern I tried to no avail:
Pattern p1 = Pattern.compile("\\\"X:\\\"([0-9.]*)\\\",\\\"Y\\\":\"([0-9.]*)\\\"");
Matcher m1 = p1.match(result);
if( m1.matches() ){
print("match found");
}
I have also tried the following without any luck:
Pattern.compile("\"X:\"([0-9.]*)\",\"Y\":\"([0-9.]*)\"");
This should be easy, but yet I have been stuck here for the past 2 hours.
If you want regex to parse it, then you can use:
"X":"(\d+(?:\.\d+)?)","Y":"(\d+(?:\.\d+)?)"
Regex Demo
You are missing a quote(") after X in your regex. Though I recommend not to use your regex because it will also match 1.1.2.3
In JAVA:
\"X\":\"(\\d+(?:\\.\\d+)?)\",\"Y\":\"(\\d+(?:\\.\\d+)?)\"
This RegEx will work:
"X":"([0-9.]*)","Y":"([0-9.]*)"
The 1st Capture Group contains the X value, and the 2nd Capture Group contains the Y value
Live Demo on Regex101
Which means your Pattern.compile should be:
Pattern.compile("\"X\":\"([0-9.]*)\",\"Y\":\"([0-9.]*)\"");
Note that you may need to add .* at the start of the RegEx for it to work.
for others that are stuck with the same problem, the reason why .* is needed at the front/end is because i used the wrong method call.
according to http://developer.android.com/reference/java/util/regex/Matcher.html#matches()
public boolean matches ()
Added in API level 1 Tries to match the Pattern against the entire
region (or the entire input, if no region has been set).
It needs to match the entire region.
to do any match, i would need to use find() instead.
public boolean find ()
Added in API level 1 Moves to the next occurrence of the pattern in
the input. If a previous match was successful, the method continues
the search from the first character following that match in the input.
Otherwise it searches either from the region start (if one has been
set), or from position 0.
hope this is useful to others.
String.matches() provides more insights to matches() method http://developer.android.com/reference/java/lang/String.html
public boolean matches (String regularExpression)
This method returns true only if the regular
expression matches the entire input string. A common mistake is to
assume that this method behaves like contains(CharSequence); if you
want to match anywhere within the input string, you need to add .* to
the beginning and end of your regular expression. See matches(String,
CharSequence).
I have been creating Spinner controls (Combo boxes/Drop downs) in one of my apps, and was surprised to find out how difficult it was to achieve all of the following features:
User facing Strings are externalized, taking advantage of strings.xml internationalisation (I18N) feature of Android.
Spinner selections operate using a System view, which facilitates not having to work with or map Strings to meaningful values (yuck).
User view to System view mapping should be easy, automated and minimal (i.e not hand rolled for every component).
Others have attempted solutions to this, but universally as far as I could see they suffer from one or many of the following problems:
UI code is creeping into their enum class which doesn’t belong there (messy), nearly all existing solutions suffered from this.
Hardcoded User facing Strings in their enum classes. Because these are not externalized you cannot do I18N using the stock Android features.
Authors typically make the Fragment or Activity an OnItemSelectedListener which perpetuates a common problem of inheritance for convenience, where composition is more appropriate.
I have developed my own solution which does this: http://www.androidanalyse.com/android-spinner-externalize-user-strings-mapped-to-system-enum/
My question is, have I missed something? This seems like something that should not have been this hard (which makes me feel like I'm possibly reinventing the wheel).
Below is some example code showing my solution in-use (which is available Apache 2 license from the link above).
String none = getString(R.string.none);
String light = getString(R.string.light);
String medium = getString(R.string.medium);
String strong = getString(R.string.strong);
SpinnerUtil.createNewSpinner(view, R.id.wind, Arrays.asList(none, light, medium, strong), WindLevel.values(),
new SpinnerItemSelectedListener<WindLevel>() {
public void onItemSelected(Spinner item, WindLevel value) {
// Take whatever action you wish to here.
}});
I would just use ArrayAdapter<WindLevel>. Yes, you created a custom typed listener, but the regular event listener gets the position and can call getItem() on the ArrayAdapter<WindLevel> to get a WindLevel properly typed.
IMHO, the vast majority of Spinner widgets will be populated with material read in from a database, the Internet, or some other dynamic data source, rather than populated by some sort of enum with display values coming from static strings that can be internationalized ahead of time.
This is not to say that your code is useless: if you find it useful, then it was worth writing. And I am sure that there are apps out there that contain your targeted pattern (i.e., a Spinner backed by an enum or equivalent where the display values are known in advance and can be internationalized) who might find your solution useful as well. Every developer who writes enough code cooks up these sorts of helper classes and the like that help map an OS or framework model into something that better fits the developer's own mental model. So long as you are not perceiving any performance issues, it's all good.
Also, note that OnItemSelectedListener is an interface; implementing that interface on an existing class is not inheritance.
I believe the reason nobody answered you is :
What problem are you trying to solve ? Spinners existed prior to your well designed attempt.
Why reinvent them in exactly the same way they exist in Android ?
http://developer.android.com/guide/topics/ui/controls/spinner.html
It is a beautiful wheel indeed you designed, but still, it is just a wheel :)
UPDATE :
I think I begin to understand what you did. This is interesting. I'm not sure why you did not go to the pattern implemented by the ListPreference with its entries and entryvalues.
In fact, I'm not sure I understand why the Android team did not go that route either.
In any case, it is worth proposing your idea to the Android framework. It is after all open source.
I'm parsing some XML with a ContentHandler, and I can get attributes within tags fine, but I don't see how to get the actual values. For example, take this simple xml:
<code>
< thing id="12345" key="abcde" >
< description > Some text is here < /description >
< otherdata > I don't actually care about or want this text < /otherdata >
< /thing >
</code>
(Apologies for the formatting there...)
So, in my StartElement() I can get the id and key values fine with att.getValue("id") for example. But how do I get the text between the description tags?
Based on reading the docs it look like I need to use the characters() method, but this will presumably occur for all other tags in the xml (the real example is more complex than the above, and I don't need all of it) - how do I relate the character array back to a specific tag? All it gives me is a start and a length but from that I don't know which element it relates to.
I'm obviously missing something obvious here but none of the docs or examples I find seem to help - most examples just show the whole doc being squirted out to a console, which is fine but doesn't help with my scenario.
You can put Flag value whenever you parse description inside the startElement(), and make it false inside the endElement(). In between this, you can have value of description inside the characters() method.
use
_data.sectionId = atts.getValue("id");
refer this link for detailed example
http://www.jondev.net/articles/Android_XML_SAX_Parser_Example
SAX is a very low-level API for parsing, and the price you pay for this is that you have to manage context and state within your application code. Nearly all SAX applications will maintain a stack of element names, so that when text arrives, you know what element it belongs to by peek()ing at the stack.
SAX seems to be becoming very popular on Android, and I'm not sure whether that's because there's nothing else available or because the efficiency is needed. But the fact is, SAX is a very difficult interface to program to, and for high performance you pay a heavy price in usability.
I want to know is there any method or any link or tutorial to perform redo undo operation in Android edittext. If any one knows than please let me know.
Quick note on the Antti-Brax/Divers(Kidinov) solution. It works great, except if you try to use it with a TextView post-API 23, you'll run into problems, because guess-what, Google actually added a hidden UndoManager (android.content.UndoManager) and didn't document it or make it obvious it was there. But if you have a hard/bluetooth keyboard in Marshmallow or Nougat and hit ^Z or SHIFT-^Z, you'll get undo/redo.
The problem comes if you're already using Antti-Brax's class with an EditText, and you also hook it to ^Z and shift-^Z, you'll run into problems with anyone using a hard keyboard. Namely the ^Z will trigger BOTH the native and Antti-Brax's undo, leading to two undos simultaneously, which isn't good. And after a few of them, you'll probably get a Spannable out of bounds crash.
A possible solution I found is to subclass the TextView/TextEdit/whatever and intercept the undo/redo calls from the TextView so they don't run as follows:
#Override
public boolean onTextContextMenuItem(int id) {
int ID_UNDO, ID_REDO;
try {
ID_UNDO = android.R.id.undo;
ID_REDO = android.R.id.redo;
} catch (Resources.NotFoundException e) {
ID_UNDO = 16908338; // 0x1020032
ID_REDO = 16908339; // 0x1020033
}
return !((id == ID_UNDO) || (id == ID_REDO)) && super.onTextContextMenuItem(id);
}
Those magic id numbers were found here, and are used only as a backup if the android.R.id.undo values aren't found. (it also might be reasonable to assume that if the values aren't there the feature isn't there, but anyway...)
This is not the best solution because both undo trackers are still there and both are running in the background. But at least you won't trigger both of them simultaneously with ^Z. It's the best I could think to do until this gets officially documented and the getUndoManager() methods of TextView is no longer hidden...
Why they made a feature you can't turn off (or even know if it was there or not) "live" in released Android I can't say.
I just opened an issue on Android's issue tracker if anyone wants to follow this.
There is an implementation of undo/redo for Android EditText in
http://credentiality-android-scripting.googlecode.com/hg/android/ScriptingLayerForAndroid/src/com/googlecode/android_scripting/activity/ScriptEditor.java
The code works but does not handle configuration changes properly. I am working on a fix and will post here when it is complete.
My Google search was :-
android edittext onTextChanged undo
I know this is an old question, but as there is no accepted answer, and this is an issue I've tackled myself from many angles, I'd like to add my solution in case it helps anyone. My answer is probably most relevant to large (1,000words+) volumes of text editing apps that require this feature.
The simplest way to resolve this problem is to make periodic copies of all text on screen, save it to an array and call setText() every time the Undo method is called. This makes for a reliable system, but it isn't ideal for large (i.e. 1,000words+) text editing apps. This is because it:
Is wasteful. It could be that only one word changes in a two thousand word document, so that's one thousand, nine hundred and ninety nine words needlessly committed to memory.
Can lead to performance issues, as some low-tier hardware struggles with rendering large amounts of text. On some of my test devices, this method can lead to freezes of a few seconds whenever Undo is called.
The solution I currently use is comparatively complex, but I've published the results in a library here.
Essentially, this library saves a copy of text as soon as a user begins typing, and then another copy of text once they've stopped typing for a set amount of time (in my case, two seconds). The two text strings are then compared, and the altered section of text returned, the indexes where the alterations occured, and details on whether or not the change was an addition of new text, a deletion, or a replacement of old text with new text.
The net result is that only the necessary text is saved, and when Undo is called, there is only a local delete(), replace() or insert() call, which makes for much faster operations on large text fields.
Here is the undo/redo implementation that was linked to from Gary Phillips' answer extracted into a reusable and universal undo/redo plugin for any widget that descends from a TextView. I added some code for persisting the undo history.
http://code.google.com/p/android/issues/detail?id=6458#c123
Hope this helps.
To preserve EditText Styling with regards to undo:
You can create an ArrayList<EditText> or ArrayList<String> (String containing html text) to store your last 10 (for example) actions. So ArrayList [0] would contain html text from your first action and ArrayList [9] would contain html text from your very last action. Each time the user taps "undo" in your app, you would apply ArrayList [size()-1] to your EditText and then remove ArrayList [size()-1] from your Array.