android - Text alignment in Html.java and custom tagHandlers -
i'm stumped, confused , frustrated! although can see in html.java api style , text-align should usable tags <p>
, <div>
etc. failing work <p align="center">
or <p style="text-align: center">
, many other variants.
what correct form use html.java through taghandler in fromhtml() method?
the received knowledge text alignment not possible preset taghandlers in html.java, but, if so, why there code therein looks capable of handling along other css style parameters?
why doesn't custom taghandler using text alignment work? read on more details of test app...
not being able central alignment of text, , other styles font size, multiple font faces ttf files, background colour, have made own htmltextview based on textview custom taghandler class. given 1 or 2 minor irritations, of tags fine custom alignment tags, left, centre, right work in special conditions (that don't understand), otherwise. don't work or crash app! alignment tag handle. has same structure other custom tag handlers behaves weirdly! however, honest, none of them work 100%. notable oddity having use text character @ start of html text before using tag invoke custom font!!
the basic form of tag handlers same , confess are not conceived me! found taghandler template after many hours searching on web. grateful whoever posted memory , organisational ability such can't remember or where, if recognise code yours please let me know. link (which here) have in code: stackoverflow: android: how use html.taghandler? @dandre allison
private void processalignment(layout.alignment align, boolean opening, editable output) { int len = output.length(); if (opening) { output.setspan(new alignmentspan.standard(align), len, len, spannable.span_mark_mark); } else { object obj = getlast(output, alignmentspan.standard.class); int = output.getspanstart(obj); output.removespan(obj); if (where != len) { output.setspan(new alignmentspan.standard(align), where, len, spannable.span_exclusive_exclusive); } } }
i think problem end tag not getting connected correct start tag.
private object getlast(editable text, class kind) { object[] objs = text.getspans(0, text.length(), kind); if (objs.length == 0) { return null; } else { (int = objs.length - 1; >= 0; --i) { if (text.getspanflags(objs[i]) == spannable.span_mark_mark) { return objs[i]; } } return null; } }
this total class , not right. largest component lack of understanding! perhaps can me understand better...
public class htmltextview extends appcompattextview { static typeface mlogo; static typeface mgamz; static typeface mchalk; static typeface msouvenir; int gs_paintflags = filter_bitmap_flag | anti_alias_flag | subpixel_text_flag | hinting_on; public htmltextview(context context) { super(context); initialise(); } public htmltextview(context context, @nullable attributeset attrs) { super(context, attrs); initialise(); } public htmltextview(context context, @nullable attributeset attrs, int defstyleattr) { super(context, attrs, defstyleattr); initialise(); } private void initialise() { mlogo = typeface.createfromasset(theassetmanager, "fonts/logo.ttf"); mgamz = typeface.createfromasset(theassetmanager, "fonts/gamz one.ttf"); mchalk = typeface.createfromasset(theassetmanager, "fonts/swapfix.ttf"); msouvenir = typeface.createfromasset(theassetmanager, "fonts/souvenir regular.ttf"); setpaintflags(gs_paintflags); } public void setdefaulttypefacesouvenir() { settypeface(msouvenir); } public void setdefaulttypefacegamz() { settypeface(mgamz); } public void setdefaulttypefacechalk() { settypeface(mchalk); } /*public mytextview(context context, @nullable attributeset attrs, int defstyleattr, int defstyleres) { super(context, attrs, defstyleattr, defstyleres); }*/ public void sethtml(string htmltext) { if (build.version.sdk_int >= build.version_codes.n) { // nougat api 24 settext(html.fromhtml(htmltext, html.from_html_mode_legacy, null, new typefacetaghandler())); } else { settext(html.fromhtml(htmltext, null, new typefacetaghandler())); } } @override protected void dispatchdraw(canvas canvas) { super.dispatchdraw(canvas); } @override protected void ondraw(canvas canvas) { super.ondraw(canvas); } @override public bitmap getdrawingcache(boolean autoscale) { return super.getdrawingcache(autoscale); } @override public void draw(canvas canvas) { super.draw(canvas); } // http://stackoverflow.com/questions/4044509/android-how-to-use-the-html-taghandler private static class typefacetaghandler implements html.taghandler { private void processalignment(layout.alignment align, boolean opening, editable output) { int len = output.length(); if (opening) { output.setspan(new alignmentspan.standard(align), len, len, spannable.span_mark_mark); } else { object obj = getlast(output, alignmentspan.standard.class); int = output.getspanstart(obj); output.removespan(obj); if (where != len) { output.setspan(new alignmentspan.standard(align), where, len, spannable.span_exclusive_exclusive); } } } private void processtypefacetag(typeface tf, boolean opening, editable output) { int len = output.length(); if (opening) { output.setspan(new customtypefacespan("", tf), len, len, spannable.span_mark_mark); } else { object obj = getlast(output, customtypefacespan.class); int = output.getspanstart(obj); output.removespan(obj); if (where != len) { output.setspan(new customtypefacespan("", tf), where, len, spannable.span_exclusive_exclusive); } } } private void processscaletag(float scalefactor, boolean opening, editable output) { int len = output.length(); if (opening) { output.setspan(new relativesizespan(scalefactor), len, len, spannable.span_mark_mark); } else { object obj = getlast(output, relativesizespan.class); int = output.getspanstart(obj); output.removespan(obj); if (where != len) { output.setspan(new relativesizespan(scalefactor), where, len, spannable.span_exclusive_exclusive); } } } private void processbox(int colour, boolean opening, editable output) { int len = output.length(); if (opening) { output.setspan(new backgroundcolorspan(colour), len, len, spannable.span_mark_mark); } else { object obj = getlast(output, backgroundcolorspan.class); int = output.getspanstart(obj); output.removespan(obj); if (where != len) { output.setspan(new backgroundcolorspan(colour), where, len, spannable.span_exclusive_exclusive); } } } private void processtextcolour(int colour, boolean opening, editable output) { int len = output.length(); if (opening) { output.setspan(new foregroundcolorspan(colour), len, len, spannable.span_mark_mark); } else { object obj = getlast(output, foregroundcolorspan.class); int = output.getspanstart(obj); output.removespan(obj); if (where != len) { output.setspan(new foregroundcolorspan(colour), where, len, spannable.span_exclusive_exclusive); } } } final hashmap<string, string> attributes = new hashmap<>(); @override public void handletag(boolean opening, string tag, editable output, xmlreader xmlreader) { string attr = ""; //if (!opening) attributes.clear(); processattributes(xmlreader); if ("txt".equalsignorecase(tag)) { attr = attributes.get("clr"); system.out.println("clr attr: " + attr + ", opening: " + opening); if (attr == null || attr.isempty() || "black".equalsignorecase(attr) || attr.charat(0) == 'k') { system.out.println("did black, opening: " + opening); processtextcolour(parsecolor("#000000"), opening, output); } else { if (attr.equalsignorecase("g")) { processtextcolour(parsecolor("#b2b3b3"), opening, output); } else { system.out.println("did colour, opening: " + opening); processtextcolour(parsecolor(attr), opening, output); } } return; } if ("box".equalsignorecase(tag)) { processbox(parsecolor("#d7d6d5"), opening, output); return; } if ("scl".equalsignorecase(tag)) { attr = attributes.get("fac"); system.out.println("scl attr: " + attr); if (attr != null && !attr.isempty()) { processscaletag(parsefloat(attr), opening, output); } return; } if ("left".equalsignorecase(tag)) { processalignment(layout.alignment.align_normal, opening, output); return; } if ("centre".equalsignorecase(tag)) { processalignment(layout.alignment.align_center, opening, output); return; } if ("right".equalsignorecase(tag)) { processalignment(layout.alignment.align_opposite, opening, output); return; } if ("logo".equalsignorecase(tag)) { processtypefacetag(mlogo, opening, output); return; } if ("gamz".equalsignorecase(tag)) { processtypefacetag(mgamz, opening, output); return; } if ("chalk".equalsignorecase(tag)) { system.out.println("chalk " + (opening ? "opening" : "closing")); processtypefacetag(mchalk, opening, output); return; } } private object getlast(editable text, class kind) { object[] objs = text.getspans(0, text.length(), kind); if (objs.length == 0) { return null; } else { (int = objs.length - 1; >= 0; --i) { if (text.getspanflags(objs[i]) == spannable.span_mark_mark) { return objs[i]; } } return null; } } private void processattributes(final xmlreader xmlreader) { try { field elementfield = xmlreader.getclass().getdeclaredfield("thenewelement"); elementfield.setaccessible(true); object element = elementfield.get(xmlreader); field attsfield = element.getclass().getdeclaredfield("theatts"); attsfield.setaccessible(true); object atts = attsfield.get(element); field datafield = atts.getclass().getdeclaredfield("data"); datafield.setaccessible(true); string[] data = (string[])datafield.get(atts); field lengthfield = atts.getclass().getdeclaredfield("length"); lengthfield.setaccessible(true); int len = (integer)lengthfield.get(atts); /** * msh: supported attributes , add hash map. * tight things can :) * data index "just" keys , values stored. */ for(int = 0; < len; i++) attributes.put(data[i * 5 + 1], data[i * 5 + 4]); } catch (exception e) { log.d(tag, "exception: " + e); } } } private static class customtypefacespan extends typefacespan { private final typeface newtype; public customtypefacespan(string family, typeface type) { super(family); newtype = type; } @override public void updatedrawstate(textpaint ds) { applycustomtypeface(ds, newtype); } @override public void updatemeasurestate(textpaint paint) { applycustomtypeface(paint, newtype); } private void applycustomtypeface(paint paint, typeface tf) { int oldstyle; typeface old = paint.gettypeface(); if (old == null) { oldstyle = 0; } else { oldstyle = old.getstyle(); } int fake = oldstyle & ~tf.getstyle(); if ((fake & typeface.bold) != 0) { paint.setfakeboldtext(true); } if ((fake & typeface.italic) != 0) { paint.settextskewx(-0.25f); } paint.settypeface(tf); } }
}
the htmltextview created activity with:
protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); theassetmanager = getassets(); htmltextview tv = new htmltextview(this); tv.setdefaulttypefacesouvenir(); tv.settextcolor(black); tv.setbackgroundcolor(0xfff0f0f0); tv.setpadding(4, 4, 4, 4); tv.settextsize(30); tv.setmovementmethod(new scrollingmovementmethod()); tv.sethtml(getstring(r.string.htmljumblies)); //tv.sethtml(getstring(r.string.htmltest)); relativelayout rl = (relativelayout) findviewbyid(r.id.rl); rl.addview(tv); }
and htmljumblies defined in strings.xml below. particular version crash app if first <centre>
, </centre>
tags removed lines 7 , 9, the jumblies appear centralised? confusing , frustrating! keep them , remove <centre>
, </centre>
tags enfolding the jumblies , nothing happens. line in header not centrally aligned!
<string name="htmljumblies"> <![cdata[&doublelongrightarrow;<logo><scl fac="1.1"><font color="#e5053a">gamz</font></scl></logo> <chalk><scl fac="1.8"> swap </scl></chalk> <scl fac="1.00">set <b>1</b>, game <b>1</b></scl> <br> <centre> <gamz><font color="#e5053a"><scl fac="1.50">a</scl></font><scl fac="0.90">(9)</scl></gamz>, <gamz><font color="#00a3dd"><scl fac="1.50">e</scl></font><scl fac="0.90">(8)</scl></gamz>, <gamz><font color="#fba311"><scl fac="1.50">i</scl></font><scl fac="0.90">(8)</scl></gamz>, <gamz><font color="#bc5e1e"><scl fac="1.50">o</scl></font><scl fac="0.90">(8)</scl></gamz>, <gamz><font color="#bf30b5"><scl fac="1.50">u</scl></font><scl fac="0.90">(9)</scl></gamz> </centre> <br> example of custom <b>htmltextview</b> drawn html format text custom tags use custom fonts, colouring typeface sizing , highlight boxes. default font <b><i>souvenir</i></b>, 3 other fonts used:<br> <font color="#e5053a"><b><logo><scl fac="1.1">gamz</scl></logo></b></font> <font color="#000080"><gamz><scl fac="0.8"><box>letter</box> <box>fonts</box><sc></gamz></font> , <chalk><scl fac="1.8">swapfix</scl></chalk>, <chalk><scl fac="0.9">staccato 555</scl></chalk>, used in words <chalk><scl fac="1.2">swap</scl></chalk> , <chalk><scl fac="1.2">fix</scl></chalk> on <font color="#e5053a"><b><logo><scl fac="1.1">gamz</scl></logo></b></font> boxes. <br> <centre> <scl fac="2"><box><b> <u>the jumblies</u> </b></box></scl><br> <font color="#0000ff"> went sea in sieve, did,<br> in sieve went sea:<br> in spite of friends say,<br> on winter\'s morn, on stormy day,<br> in sieve went sea!<br> , when sieve turned round , round,<br> , every 1 cried, \'you\'ll drowned!\'<br> called aloud, \'our sieve ain\'t big,<br> don\'t care button! don\'t care fig!<br> in sieve we\'ll go sea!\'<br> far , few, far , few,<br> lands jumblies live;<br> heads green, , hands blue,<br> , went sea in sieve.<br> <br> sailed away in sieve, did,<br> in sieve sailed fast,<br> beautiful pea-green veil<br> tied riband way of sail,<br> small tobacco-pipe mast;<br> , every 1 said, saw them go,<br> \'o won\'t upset, know!<br> sky dark, , voyage long,<br> , happen may, it\'s extremely wrong<br> in sieve sail fast!\'<br> far , few, far , few,<br> lands jumblies live;<br> heads green, , hands blue,<br> , went sea in sieve.<br> <br> water came in, did,<br> water came in;<br> keep them dry, wrapped feet<br> in pinky paper folded neat,<br> , fastened down pin.<br> , passed night in crockery-jar,<br> , each of them said, \'how wise are!<br> though sky dark, , voyage long,<br> yet never can think rash or wrong,<br> while round in our sieve spin!\'<br> far , few, far , few,<br> lands jumblies live;<br> heads green, , hands blue,<br> , went sea in sieve.<br> <br> , night long sailed away;<br> , when sun went down,<br> whistled , warbled moony song<br> echoing sound of coppery gong,<br> in shade of mountains brown.<br> \'o timballo! how happy are,<br> when live in sieve , crockery-jar,<br> , night long in moonlight pale,<br> sail away pea-green sail,<br> in shade of mountains brown!\'<br> far , few, far , few,<br> lands jumblies live;<br> heads green, , hands blue,<br> , went sea in sieve.<br> <br> sailed western sea, did,<br> land covered trees,<br> , bought owl, , useful cart,<br> , pound of rice, , cranberry tart,<br> , hive of silvery bees.<br> , bought pig, , green jack-daws,<br> , lovely monkey lollipop paws,<br> , forty bottles of ring-bo-ree,<br> , no end of stilton cheese.<br> far , few, far , few,<br> lands jumblies live;<br> heads green, , hands blue,<br> , went sea in sieve.<br> <br> , in twenty years came back,<br> in twenty years or more,<br> , every 1 said, \'how tall they\'ve grown!<br> they\'ve been lakes, , torrible zone,<br> , hills of chankly bore!\'<br> , drank health, , gave them feast<br> of dumplings made of beautiful yeast;<br> , every 1 said, \'if live,<br> go sea in sieve,---<br> hills of chankly bore!\'<br> far , few, far , few,<br> lands jumblies live;<br> heads green, , hands blue,<br> , went sea in sieve.</centre></font> ]]> </string>
Comments
Post a Comment