All those who have used edittext know that edittext has a feature. When long-pressed in it, a contextmenu will appear, providing functions such as selecting text, copying, and cutting. Sometimes, we will think that if this contextmenu is not displayed, it would be nice to select text directly on The View. I believe many people have such ideas. Unfortunately, me too. So I studied the edittext and textview code and solved the problem.
Many documents on the Internet say that to select a text segment, you only need to use selection. getselectionstart () and selection. getselectionend () to determine the header and tail of the selected text, and then add the color. I dare say that this code has not been verified, and it has been sent to the Internet. Then a lot of people Reprinted with each other, causing many people to be misled,Cup !!
Okay. Let's analyze the solution.
Textview is a base class of many views. For example, buttons and edittext are inherited from them, so there are few codes in edittext. Let's take a look at the source code of edittext. There is an override getdefaulteditable method to check whether the name is editable. This method returns true directly. There is also a getdefamovmovementmethod method, which returns arrowkeymovementmethod. getinstance (). By viewing the source code of arrowkeymovementmethod, it is basically determined that this method is the "culprit" of the contextmenu and trackball monitoring ".
Next, we will make a view to build our own edittext.
My name is textpage, which inherits edittext and overwrites getdefaulteditable and getdefamovmovementmethod.
@Override public boolean getDefaultEditable() { return false ; } @Override protected MovementMethod getDefaultMovementMethod() { return null ; }
Now, I tested it and found that the long-pressed message did not respond. As expected, the getdefamovmovementmethod method controls the contextmenu.
Take a look at the arrowkeymovementmethod code, which provides the processing of keyevent, trackball event ontrackballevent, and touch event ontouchevent. Where are these events called? Let's take a look at the ontouchevent, ontrackballevent, and onkeyevent methods in textview. In these event callbacks, these methods in arrowkeymovementmethod are called.
Another question is, where is the contextmenu triggered? If you have used contextmenu, you know that you need to use contextmenu in view. You need to overwrite an oncreatecontextmenu method, and then create various options of contextmenu in view. Find oncreatecontextmenu in textview, which defines options such as selection, copy, and paste.
Now that we have found this, we can further analyze how the choice is achieved.
Oncreatecontextmenu is only used to create a menu. What is triggered after the menu is clicked? Oncreatecontextmenu defines a menuhandler object and passes it as a parameter to setonmenuitemclicklistener. Find menuhandler and find onmenuitemclick in it to return the ontextcontextmenuitem function. Find ontextcontextmenuitem, OMG, finally, find the function triggered by clicking menu. However, there seems to be no key things in it, and the selected part is not here. In this case, it should be in the above mentioned events.
Focus on the ontouchevent method of arrowkeymovementmethod. Find an important method getlayout (), then obtain a layout object, and know the offset position of the current string through the X and Y coordinates.
Then the problem can be solved perfectly. You can click anywhere and drag it. After the release, the text in the middle will be selected, so beauul ul!
Import android. content. context; import android. graphics. color; import android. text. layout; import android. text. selection; import android. view. contextmenu; import android. view. gravity; import android. view. motionevent; import android. widget. edittext;/*** @ author chroya */public class textpage extends edittext {private int off; // The Offset Value of the string public textpage (context) {super (context ); initialize ();} private void initialize () {setgravity (gravity. top); setbackgroundcolor (color. white) ;}@ override protected void oncreatecontextmenu (contextmenu menu) {// The context menu is displayed to prevent long-pressed requests.} @ override public Boolean getdefaulteditable () {return false ;}@ override public Boolean ontouchevent (motionevent event) {int action = event. getaction (); layout = getlayout (); int line = 0; Switch (Action) {Case motionevent. action_down: line = layout. getlineforvertical (getscrolly () + (INT) event. gety (); off = layout. getoffsetforhorizontal (line, (INT) event. getx (); selection. setselection (geteditabletext (), off); break; Case motionevent. action_move: Case motionevent. action_up: line = layout. getlineforvertical (getscrolly () + (INT) event. gety (); int curoff = layout. getoffsetforhorizontal (line, (INT) event. getx (); selection. setselection (geteditabletext (), off, curoff); break;} return true ;}}
Author: homebei2
Link: http://blog.csdn.net/homebei2/archive/2011/01/12/6130417.aspx