Android Imitation Sina Micro Boga # EDITTEXT implementation of the topic

Source: Internet
Author: User
<span id="Label3"></p>Demand<p><p>Product on-line, The project is almost stabilized, followed by a version of the Iteration. This week added a few new features, one of which is the title, to imitate Sina Weibo (such as) The text effect in the input box. As a whole font on both sides is the well number, and include the well number to color, delete, when the cursor to the right of the well, click Delete again, will be the contents of the package as a whole deleted, while the focus can not be changed between the characters, that is, when the color of the character, the cursor will automatically fall on both Sides.</p></p><p><p></p></p>Split problem<p><p>Seems to be a very simple and reasonable demand, casually think, this is not a string match! But the actual action, you will find a variety of problems, far from the imagination is not so simple. I do this down the feeling is that must have a clear and clear thinking, summed up, in fact, can be divided into the following steps.</p></p> <blockquote> <blockquote> <ul> <li>First of all, Sina Weibo this feature of the entrance is, click on the pound, enter into the new interface to select a string, and then automatically <strong>added</strong> to the EditText box, we want to implement such a Demo, there is no need to enter a new interface, directly to do a button, click Add can;</li> <li>then, It should be clear that in the native API provided by Android, <strong>Delete</strong> the action, only one character can be deleted at a time, and can not delete the bulk characters, can only delete a letter at a time, not a word, delete action is the key to our topic;</li> <li>After processing the addition and deletion of the string function, followed by matching rules of the string to do <strong>discoloration</strong> processing;</li> <li>Then it is the problem of handling the click string, where the cursor is located;</li> <li><strong>Refine</strong> the details that need to be supplemented and modified.</li> </ul> </blockquote> </blockquote><p><p>Through the above five steps to divide the topic into four small problems, and then go to one by one to Solve.</p></p>Add a String<p><p>This step is basically the simplest step. All we need to do is click on a button and append the string into EditText. of course, in order to make our operation more extensive applicability, the simple increase of the string is a bit too much to see, and in practice, this does not make any sense.</p></p><p><p>All we have to do is create an entity class, and this string as a value, the corresponding variable is the member variable of this entity class, we append the string to the EditText by continually adding new objects to the entity class Collection. At the same time, there is a good thing about this is that, in practice, there may be other variables that are used with strings, and the best way to handle other variables corresponding to string one by one is to remove the entity from the entity collection by adding and deleting the string.</p></p><p><p>Here's my entity Class:</p></p><pre class="brush: java; gutter: false; first-line: 1"><pre class="brush: java; gutter: false; first-line: 1">/** entity Class */public class Bookentity implements Serializable {private static final long serialversionuid = 1l;private String Bookid;private String bookname; Public bookentity (String bookname, int bookId) {super (); this.bookname = Bookname;this.bookid = bookId;} Public String getbookid () {return bookId;} public void Setbookid (String bookId) {this.bookid = bookId;} Public String getbookname () {return bookname;} public void Setbookname (String Bookname) {this.bookname = bookname;}}</pre></pre><p><p>To add a character action:</p></p><pre class="brush: java; gutter: false; first-line: 1"><pre class="brush: java; gutter: false; first-line: 1">/** performs an operation that increases the string */private Button button;private arraylist<bookentity> mlist = new Arraylist<bookentity> (); Private EditText EditText; View view = Inflater.inflate (r.layout.fragment_main, container, false); editText = (editText) View.findviewbyid ( r.id.edit_text); button = (button) View.findviewbyid (r.id.bt); buttont.setonclicklistener (new onclicklistener () {@ overridepublic void OnClick (View v) {int nextint = new Random (). nextint (100); String str = "#测试测试" + nextint + "#"; edittext.settext (edittext.gettext ()); edittext.append (str); edittext.setselection ( Edittext.gettext (). toString (). length ()); mlist.add (new bookentity (str, nextint));});</pre></pre><p><p>So we're done with adding string operations.</p></p>Delete a string that matches a condition<p><p>The delete operation is the key to this small program. When doing the delete operation, we need to figure out the following questions: when to delete? Where to start the deletion? Where is the end of the deletion? Where should the cursor position be after the delete is finished? Next one to Solve.</p></p> <ol> The <ol> <li> Delete operation should of course be executed when you press the DELETE key of the soft keyboard, here is a detail, in the Android click keyboard button events, in fact, is separate processing, press the keyboard will start the action, the keyboard will also trigger action; </li> <li> If the filter is not met (" # "+bookentity.getbookname () +" # "), Delete one character at a time, and if eligible, Delete all strings with left and right numbers at once, </li> <li> and the cursor should remain at the very end. </li> </ol> </ol><pre class="brush: java; gutter: false; first-line: 1">/** Listen for delete button, perform delete action */edittext.setonkeylistener (new onkeylistener () {@Overridepublic boolean onKey (View v, int keycode, KeyEvent Event) {if (keycode = = Keyevent.keycode_del && event.getaction () = = Keyevent.action_down) {//when The key is deleted and is pressed The action is performed when int selectionstart = edittext.getselectionstart (), int lastpos = 0;for (int i = 0; i < mlist.size (); I++) {//looping through the entire All characters of an input box if ((lastpos = Edittext.gettext (). toString (). indexOf (mlist.get (i). getbookname (), lastpos))!! =-1) {if ( selectionstart! = 0 && selectionstart >= lastpos && selectionstart <= (lastpos + mlist.get (i). getBoo Kname (). length ()) {String sss = edittext.gettext (). toString (); edittext.settext (sss.substring (0, LASTPOS) + Sss.substring (lastpos + mlist.get (i). getbookname (). length ()); String substitution, Delete the qualifying string Mlist.remove (i); Delete the corresponding entity edittext.setselection (lastpos); Set cursor position return true;}} else {lastpos + = ("#" + mlist.get (i). getbookname () + "#"). length ();}} Return false;}});</pre>Handling discoloration Issues<p><p>discoloration, so that the matching strings of color highlighting, more like the icing on the cake, to the user more intuitive perception, but the entire small program to achieve the most complex part. Due to some of the reasons for Android itself, whether it is increased or deleted, or lock screen and other events, will cause the interface redraw problem, so its core is to set the listening state of the <strong>character Change</strong> , when the character changes, the color of the remaining characters Changes.</p></p><p><p>For the specific implementation, we need a textwatcher implementation class, and then new comes out an object, as a parameter to the control EditText set Addtextchangedlistener listener.</p></p><pre class="brush: java; gutter: false; first-line: 1">Class Mytextwatcher implements Textwatcher {@Overridepublic synchronized void aftertextchanged (Editable S) { AddNewArticleUI.this.etWriteDynamic.removeTextChangedListener (watcher); Text_change_listener_flag = 0;int Findpos = 0;int Copypos = 0; String stext = s.tostring (); list<integer> spanindexes = new arraylist<integer> (); s.clear (); for (int i = 0; i < booklist.size (); I++) {s Tring Tempbookname = "#" + booklist.get (i). getbookname () + "#"; If (findpos = Stext.indexof (tempbookname, findpos))!! =-1) {spanindexes.add (findpos);//bookname start index, key value is even, starting from 0 spanindexes.add (findpos + tempbookname.length ());//bookname The end index, The key value is odd, starting with 1}}if (spanindexes! = null && spanindexes.size ()! = 0) {for (int i = 0; i < spanindexes.size (); I++) {if (i% 2 = = 0) {s.append (stext.substring (copypos, spanindexes.get (i)));} else {spanned htmltext = html.fromhtml ("&L T;font color= ' Blue ' > ' + stext.substring (copypos, spanindexes.get (i)) + "</font>"); s.append (htmltext);} Copypos = SpanindExes.get (i);} S.append (stext.substring (copypos));} else {s.append (stext);}} @Overridepublic void beforetextchanged (charsequence s, int start, int count, int after) {} @Overridepublic void Ontextchang Ed (charsequence s, int start, int before, int Count) {}}</pre><p><p>It is important to note that in the Addtextchangedlistener aftertextchange method, the Editable can not be manipulated to set the value of the control, and it cannot be monitored in the Global settings TextChanged, otherwise it is bound to be called by the loop Stackoverflow. In other words, we can only call before the text changes, but also to send screen unlock screen broadcast, when the screen is unlocked to Call.</p></p><pre class="brush: java; gutter: false; first-line: 1"><pre class="brush: java; gutter: false; first-line: 1">private int text_change_listener_flag = 0;/** listen for text changes and reset the color */if (text_change_listener_flag = = 0) { Edittext.addtextchangedlistener (watcher); Text_change_listener_flag = 1;}</pre></pre><p><p>Here is the broadcast of Shing (this code is from the Network)</p></p><pre class="brush: java; gutter: false; first-line: 1">public class Screenlistener {private Context mcontext;private screenbroadcastreceiver mscreenreceiver;private Screenstatelistener mscreenstatelistener;public screenlistener (context Context) {mcontext = Context;mscreenreceiver = New Screenbroadcastreceiver ();} /** * Screen Status broadcast receiver */private class Screenbroadcastreceiver extends Broadcastreceiver {private String action = null; @Overr idepublic void onreceive (context context, Intent Intent) {action = intent.getaction (); if (intent.action_screen_ On.equals (action)) {//open Screen mscreenstatelistener.onscreenon ();} else if (Intent.ACTION_SCREEN_OFF.equals (action)) {// Lock Screen Mscreenstatelistener.onscreenoff ();} else if (Intent.ACTION_USER_PRESENT.equals (ACTION)) {//unlock mscreenstatelistener.onuserpresent ();}}} /** * Start listening to screen status * * @param listener */public void begin (screenstatelistener Listener) {mscreenstatelistener = Listener ; Registerlistener (); Getscreenstate ();} /** * Get screen status */private void getscreenstate () {powermanager manager = (powermanager) McontExt.getsystemservice (context.power_service), if (manager.isscreenon ()) {if (mscreenstatelistener! = null) { Mscreenstatelistener.onscreenon ();}} else {if (mscreenstatelistener! = Null) {mscreenstatelistener.onscreenoff ();}}} /** * Stop screen status monitoring */public void Unregisterlistener () {mcontext.unregisterreceiver (mscreenreceiver);} /** * Start screen status broadcast receiver */private void Registerlistener () {intentfilter filter = new Intentfilter (); filter.addaction ( intent.action_screen_on); filter.addaction (intent.action_screen_off); filter.addaction (Intent.ACTION_USER_ PRESENT); Mcontext.registerreceiver (mscreenreceiver, filter);} Public interface Screenstatelistener {//return to caller screen state information public void Onscreenon ();p ublic void Onscreenoff ();p ublic void Onuserpresent ();}}</pre><p><p>Register a broadcast</p></p><pre class="brush: java; gutter: false; first-line: 1"><pre class="brush: java; gutter: false; first-line: 1">Screenlistener Screenlistener = new Screenlistener (this); screenlistener.begin (new screenstatelistener () { @ Override public void onuserpresent () { log.e ("onuserpresent", "onuserpresent"); } @Override public void Onscreenon () { log.e ("onscreenon", "onscreenon"); if (text_change_listener_flag = = 0) {edittext.addtextchangedlistener (watcher); Text_change_listener_flag = 1;} } @Override public void Onscreenoff () { log.e ("onscreenoff", "onscreenoff");} );</pre></pre><p><p>finally, don't forget to unregister the Broadcast.</p></p>Set cursor position<p><p>finally, when the finger touches the matching character, set the position of the cursor, in fact, the same as the above delete processing logic, just do not need to replace the string, the logic of the judgment is the Same.</p></p><pre class="brush: java; gutter: false; first-line: 1"><pre class="brush: java; gutter: false; first-line: 1">Dittext.setonclicklistener (new onclicklistener () {@Overridepublic void OnClick (View v) {log.i ("TAG", ((EditText) v). Getselectionstart () + ""); int selectionstart = ((EditText) v). getselectionstart (); int lastpos = 0;for (int i = 0; I < mlist.size (); I++) {if (lastpos = edittext.gettext (). toString (). indexOf (mlist.get (i). getbookname (), lastpos))! =-1) {if ( SelectionStart >= lastpos && selectionstart <= (lastpos + mlist.get (i). getbookname (). length ())) { Edittext.setselection (lastpos + mlist.get (i). getbookname (). length ());}} else {lastpos + = ("#" + mlist.get (i). getbookname () + "#"). length ();}}});</pre></pre><p><p>At this point, a similar to the Sina micro-blog input box of the small program is Completed. of course, compared to Sina weibo, here is one less step to delete the first check is matched to the string, this feature, the implementation of Sina Weibo is, Click delete, First select the string, then click delete, the deletion of the String. Specific situation, no longer repeat. More technical Articles please always focus on love to develop the app source forum</p></p><p><p>Android Imitation Sina Micro Boga # EDITTEXT implementation of the topic</p></p></span>

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.