Android - Class Html - fromHtml - How does it work? - android

I'm using Html.fromHtml to get the contents of a description tag (in a feed XML) and it works fine
Description tag:
<description><![CDATA[<div class="K2FeedIntroText"><p><img style="margin: 10px; float: left;" alt="block curta" src="http://loc.grupolusofona.pt/images/stories/destaques/block%20curta.jpg" height="110" width="120" />Quatro Horas Descalço é o nome da curta-metragem, realizada por Ico Costa, que se estreia mundialmente no 7.º Festival Internacional de Cinema de Roma, nos dias 12 e 13 de novembro, em competição no Cinema XXI.</p>
]]>
But as I go look into the documentation it says:
Returns displayable styled text from the provided HTML string. Any <img> tags in the HTML will display as a generic replacement image which your program can then go through and replace with real images.
So my question is: how can i do what it says there "which your program can then go through and replace with the real image" ?
I know how to get the img url via RegEx using a Pattern, i just wanted to know how can i use the class to "go through and replace it with the image"
Please say something if i was unclear and ill try to explain it better.
EDIT:
Well, i'm trying to implement this in a simple rss reader (and trying to keep it as simple as possible code-wise)
I'm using a DOM Parser and i'm using a map = HashMap<String, Spanned> to store the values of each child node, along with a KEY:
map.put(KEY_DESC, Html.fromHtml(parser.getValue(e, KEY_DESC)));
In the comments of the answer i found a useful link from which i created a new Class (URLImageParser) and tried to use it like so:
map.put(KEY_DESC, htmlSpan);
Where htmlSpan would be the result of:
this.textView = (TextView)this.findViewById(R.id.textview);
URLImageParser p = new URLImageParser(textView, this);
Spanned htmlSpan = Html.fromHtml(html, p, null);
textView.setText(htmlSpan);
I also created a android:visibility="gone" TextView just in case it needed to store the values in a TextView (maybe i interpreted it wrong)
My original thought was that htmlSpan was of the type Spanned so it would fit in my HashMap just fine.
For uploading to ListView i'm using a SimpleAdapter like so:
ListAdapter adapter = new SimpleAdapter(this, menuItems, R.layout.linhafeed,
new String[] { KEY_TITLE, KEY_DESC, KEY_PUBDATE, KEY_LINK },
new int[] { R.id.title, R.id.desc, R.id.pub, R.id.link });
Where menuItems is ArrayList<HashMap<String,Spanned>>
Something i got wrong here ?

Html.fromHtml(...) will replace any <img ... /> tag with an ImageSpan and a special 'object replacement character' (\uFFFC).
To get the actual image to show up, it looks like there are two options:
implement an ImageGetter that returns the image to display as a Drawable. If I recall correctly, this won't allow you to offload the image loading to a different thread, because it expects the result to be returned right away. Hence, this should suffice for local resources (and probably also any assets in a device's local storage, provided there are no potentially long-running operations required; i.e. scaling, cropping, applying effects etc).
do a second pass over the Spanned result and replace any \uFFFC occurrences. You should be able to get the source (url) of the image from every ImageSpan using the getSource() method. Unfortunately, it doesn't look there are any setters to update the Drawable once loaded, so I'm guessing you may need to replace the ImageSpan with a new one, passing in the loaded image in the constructor.
A third alternative, which may be a bit more heavy-weight than above, is to use a WebView rather than a TextView. That way you don't have to deal with any of the image loading yourself, as it's built into the widget.

Related

Format a string with html elements in react native

I am trying to create a component to display some generic product info. The string is formatted by a CRM so it has HTML elements in it "<BR>, <b> </b> etc.
eg:
"<BR>Łosoś to<b> szlachetna ryba,</b> można z niej przyrządzać przepyszne dania główne, genialne przystawki, a także niezwykle smaczne pasztety i farsze. Doskonale nadaje się do<b> pieczenia, smażenia, duszenia i grillowania. <BR><BR>Trym D:</b> Usunięty kręgosłup, ości brzuszne, tylne płetwy, kość obojczyka, tłuszcz na płetwie brzusznej usunięty częściowo, usunięte ości, ścięty ogon, usunięta otrzewna.<BR>"
I want to format the string so it renders properly in react native.
I tried using ramda's replace and it worked for adding new lines /n however I do not think this will work for making the text bold.
is there some library that will format strings with html elements into a react native friendly format?

Android/iOS keyboard: stickers API

I was searching for a way to create a custom keyboard to add custom emoji and stickers.
So far I've figured out that emoji are just unicode characters and in order to add custom emoji one should supply a custom font with the dedicated emoji mapped to a predefined unicode character inside the font. This font should be available across users of the app in order for the custom emoji to display correctly.
The question arises when it comes to stickers (those big images available to add for example in Facebook comments). I can't find any useful information on how they work and what is the interface to embed them in the custom keyboard and to paste further to a text. There are apps available on Google Play and AppStore that does it (like "Go Keyboard" app for example)
Can anyone point me in the right direction?
So the question is:
How to embed stickers into a text to share further to 3rd-party apps? My main idea is to understand if there is a common standard or API for stickers (like for emoji)? Or the only way to use stickers is to use/build a custom chat API with a backend server which means only apps that use the same service will reliably decode the shared text to display stickers correctly?
I've been working in an iOS project to prove this concept of using emojis and stickers in chat conversations.
You can check it out in my GitHub repository and contribute if you want (review and improvement are welcome).
What I done was, use the NSTextAttachment to attach an image within an UITextView, using the NSAttributedString object type.
To show a image as an emoji, within in an UITextView:
// initialize object with the content of textView
NSMutableAttributedString *attributeString = [[NSMutableAttributedString alloc] initWithAttributedString:textview.attributedText];
// initialize selected image to be used as emoji
NSTextAttachment *textAttachment = [[NSTextAttachment alloc] init];
textAttachment.image = [UIImage imageNamed:#"MicheyMouse"];
textAttachment.image = [UIImage imageWithCGImage:textAttachment.image.CGImage scale:25 orientation:UIImageOrientationUp];
NSAttributedString *attrStringWithImage = [NSAttributedString attributedStringWithAttachment:textAttachment];
[attributeString appendAttributedString:attrStringWithImage];
// blank space after the image
NSAttributedString *blank = [[NSAttributedString alloc] initWithString:#" "];
[attributeString appendAttributedString:blank];
textview.attributedText = attributeString;
And if you wanna use the image as a sticker, follow this lines:
NSTextAttachment *textAttachment = [[NSTextAttachment alloc] init];
textAttachment.image = [UIImage imageNamed:sticker];
textAttachment.image = [UIImage imageWithCGImage:textAttachment.image.CGImage scale:12 orientation:UIImageOrientationUp]; // --> change de scale, to change image size (or create the image in size that you want)
NSAttributedString *attrStringWithImage = [NSAttributedString attributedStringWithAttachment:textAttachment];
cell.textLabel.attributedText = attrStringWithImage
In this example, I attached the image as a sticker directly in a cell (you can do this cell as a chat ballon).
In other words, in the first code lines, I basically showed the image in an UITextView, and in the second I put the image directly in chat lines.
I had to do my own sticker/emoji keyboard and I also made some work to handle the switching between emoji keyboard and typing keyboard.
This is the GitHub repository for the project example: https://github.com/cairano/CIStickerFacilities

Html.fromHtml(String).toString(); gives css in starting String

protected String getEntryContent(String entryContent) {
Log.d(getClass().getName(), "getEntryContent()");
String mWebViewContent;
mWebView.loadDataWithBaseURL(baseUrl,
entryContent, mimeType,
encoding, null);
mWebViewContent =Html.fromHtml(entryContent).toString();
return mWebViewContent;
}
Output:
h2 {font-size:1.2em;font-weight:normal;} a {color:#6688cc;} ol {padding- left:1.5em;} blockquote {margin-left:0em;} .interProject, .noprint {display:none;} li, blockquote {margin-top:0.5em;margin-bottom:0.5em;}
quarterly (not comparable) Occurring once every quarter year (three months).
quarterly rent payments
This gives me starting line as a CSS.
How can i remove that?
You probably passed the inline CSS in your string. From the javadoc of HTML.fromHtml it nowhere states that it can handle inline css, therefore it propably handles it like normal text
Returns displayable styled text from the provided HTML string. Any tags in the HTML will use the specified ImageGetter to request a representation of the image (use null if you don't want this) and the specified TagHandler to handle unknown tags (specify null if you don't want this).
You have to remove the css manually yourself. See this answer on how to do that: Removing css information from HTML in java
You can use this:
CharSequence mSequence = Html.fromHtml("<b>Hello</b> Android");
textView.setText(mSequence);
You can also convert it into String as:
String mString = mSequence.toString();

Android handle HTML links and typed links in a TextView

I am trying to handle both HTML and typed links in TextViews and I am unable to find a combination of the built in tools to do this. I can make one or the other work but not both.
Given the following formats
http://google.com
Google!
Using .setMovementMethod(LinkMovementMethod.getInstance()) I can make the anchor tag turn into a link and open a webpage on click. Using .setAutoLinkMask(Linkify.ALL) I can make the typed link work as expected. The problem is setAutoLinkMask disables the setMovementMethod functionality and removes the highlighting it creates on the html link as well as its clicking functionality.
I tried searching for others with this issue and I believe I am being blocked by a lack of proper terms for this situation. Has anyone else come across a solution to handle both cases seamlessly?
This is what I have currently, only the typed link is linked in the TextView, the anchor just displays the text it wraps.
mTextViewBio.setText(Html.fromHtml(htmlstring));
mTextViewBio.setAutoLinkMask(Linkify.ALL);
mTextViewBio.setMovementMethod(LinkMovementMethod.getInstance());
mTextViewBio.setLinksClickable(true);
TextView output:
http://google.com
Google!
Problem is that when Linify.addLinks() is called first thing what this method does is removing all spans. When you use Html.fromHtml() Spanned is return, so when Linkify parse text again firstly remove "html links". I wrote a simply class LinkifyExtra. It has one extra method
public class LinkifyExtra extends Linkify {
public static Spanned addLinksHtmlAware(String htmlString) {
// gather links from html
Spanned spann = Html.fromHtml(htmlString);
URLSpan[] old = spann.getSpans(0, spann.length(), URLSpan.class);
List<Pair<Integer, Integer>> htmlLinks = new ArrayList<Pair<Integer, Integer>>();
for (URLSpan span : old) {
htmlLinks.add(new Pair<Integer, Integer>(spann.getSpanStart(span),
spann.getSpanEnd(span)));
}
// linkify spanned, html link will be lost
Linkify.addLinks((Spannable) spann, Linkify.ALL);
// add html links back
for (int i = 0; i < old.length; i++) {
((Spannable) spann).setSpan(old[i], htmlLinks.get(i).first,
htmlLinks.get(i).second, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
return spann;
}
}
and use it like that
String htmlstring = "http://google.com Google!";
textView = (TextView)findViewById(R.id.textView1);
textView.setText(LinkifyExtra.addLinksHtmlAware(htmlstring));
textView.setMovementMethod(LinkMovementMethod.getInstance());
textView.setLinksClickable(true);
And it works. But you can't use mTextViewBio.setAutoLinkMask(Linkify.ALL);because it triggers addLinks() and remove "html links". Depends of what you want to do in bigger picture, this method may need some changes. I skip checking if spans are overlapping because I suppose it can't happen but if I am wrong you can simply copy this method.

How to select any option of select tag using android web driver

I am writing test cases for a website for android device. In which I need to select an option from the drop down list of the page. But it seems that android web driver does not provide any solution regarding it.
I tried the Select API but it is not working.
Code snippet
Select loginType = new Select(this.driver.findElement(By.xpath(LOGIN_TYPE_CHOICE)));
loginType.selectByValue("smartphone");
driver.findElement(By.id(LOGIN_BUTTON)).click();
Looking for some workaround.
I'm using c# to run selenium tests against android, firefox Chrome and IE and I enounterd the same problem with the android driver.
This worked for me : (it should work in java if you refactor the code according to the Java conventions)
string jsToBeExecuted="document.getElementById('<insert dropdown Id here>').selectedIndex=<insert index here>";
IJavaScriptExecutor jsExecutor = (IJavaScriptExecutor)this.Driver;
jsExecutor.ExecuteScript(jsToBeExecuted);
Note that no changes will be rendered on screen ! ! !
Upon submitting the element with the selected index will be used.
It is up to you if you want to add some tweaks to it to select the elements by text or whatever you like.
I have the following assumption from my expirience of automation web applications with selenium.
as I know selenium is uncapable of interacting direcrly with dropdown options as they considered to be invisible (inactive).
The way it always works - is to use js for this.
First of all locate element properly with css selector properly and verify it with firepath (addon to firebug in ffox)
So you got css sselector:
String css=....;
public void jsClickByCss(String cssLocator){
JavascriptExecutor js = (JavascriptExecutor) driver;
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("var x = $(\'"+cssLocator+"\');");
stringBuilder.append("x.click();");
js.executeScript(stringBuilder.toString());
}
jsClickByCss(css);
You can also try another approach using Builder, advanced user interactions API:
The idea is quite simple. First of all you should make dropdown roll down so element you want to click on become visible , wait with driver.manage.timeout and then select needed dropdown element and click.
WebElement mnuElement;
WebElement submnuElement;
mnEle = driver.findElement(By.Id("mnEle")).click();
sbEle = driver.findElement(By.Id("sbEle")).click();
Actions builder = new Actions(driver);
// Move cursor to the Main Menu Element
builder.MoveToElement(mnEle).perform();
// Giving 5 Secs for submenu to be displayed
Thread.sleep(5000L);
// Clicking on the Hidden SubMenu
driver.findElement(By.Id("sbEle")).click();
You can read some additional info here
Hope this works for you)
here is solution for Ruby:
To select value from list needs to execute javascript, here is example:
HTML:
<select id="select_id">
<option id="option_id_1" value="value_1" name="OPTION1"> OPTION1 </option>
<option id="option_id_2" value="value_2" name="OPTION2"> OPTION2 </option>
Updated:
much easier way:
$('#select_id').val(value_1)
Code:
find elements by id attribute:
browser.execute_script("$('#select_id').val($('#option_id_1').val())")
find elements by name attribute:
browser.execute_script("$('#select_id').val($('option[name=OPTION2]').val())")
Works perfectly for me.

Categories

Resources