Buggy code:
public abstract class SelectableFragment extends Fragment implements View . OnTouchListener , OnToolbarAction { @ Bind ( id . main_edit ) protected SelectableEditText editText ; @ Bind ( id . main_container ) protected RelativeLayout container ; protected List < Integer > mainIndexList = new ArrayList < > ( ) ; @ Nullable @ Override public View onCreateView ( LayoutInflater inflater , ViewGroup container , Bundle savedInstanceState ) { } protected abstract String [ ] getStringArrayResourse ( ) { } @ Override public void onResume ( ) { } @ Override public void OnToolbarAction ( int action ) { } protected void init ( ) { } protected void free ( ) { } protected int posDownX ; protected int posDownY ; protected float initScrollY ; protected long downTime ; protected long tabTime = 0 ; protected int MAX_SCROLLABLE_Y_POSITION = - 1 ; protected float posDownRawY ; protected float posDownRawX ; protected int defaultTop = - 1 ; @ Override public boolean onTouch ( View v , MotionEvent event ) { int [ ] location = new int [ 2 ] ; if ( ( ! ( editText . isTextSelectable ( ) ) ) && ( editText . hasSelection ( ) ) ) free ( ) ; if ( ( defaultTop ) < 0 ) { defaultTop = ( ( int ) ( editText . getY ( ) ) ) ; } Timber . d ( "touch<seq2seq4repair_space>:<seq2seq4repair_space>%s<seq2seq4repair_space>%s<seq2seq4repair_space>%s<seq2seq4repair_space>%s" , editText . isTextSelectable ( ) , editText . hasSelection ( ) , editText . getSelectionStart ( ) , editText . getSelectionEnd ( ) ) ; if ( ( event . getAction ( ) ) == ( MotionEvent . ACTION_DOWN ) ) { this . downTime = event . getEventTime ( ) ; this . posDownX = ( ( int ) ( event . getX ( ) ) ) ; this . posDownY = ( ( int ) ( event . getY ( ) ) ) + ( editText . getScrollY ( ) ) ; this . posDownRawX = event . getRawX ( ) ; this . posDownRawY = event . getRawY ( ) ; this . initScrollY = editText . getScrollY ( ) ; MAX_SCROLLABLE_Y_POSITION = ( TextOffsetHelper . getViewTotalHeight ( this . editText ) ) - ( editText . getHeight ( ) ) ; } float diff = Math . abs ( ( ( ( ( ( posDownX ) - ( event . getX ( ) ) ) + ( posDownY ) ) - ( event . getY ( ) ) ) - ( editText . getScrollY ( ) ) ) ) ; float diffRaw = ( ( float ) ( Math . sqrt ( Math . abs ( ( ( Math . pow ( ( ( posDownRawX ) - ( event . getRawX ( ) ) ) , 2 ) ) + ( Math . pow ( ( ( posDownRawY ) - ( event . getRawY ( ) ) ) , 2 ) ) ) ) ) ) ) ; float diffRawY = ( posDownRawY ) - ( event . getRawY ( ) ) ; if ( ( event . getAction ( ) ) == ( MotionEvent . ACTION_MOVE ) ) { if ( ( ( int ) ( diffRawY + ( initScrollY ) ) ) > ( MAX_SCROLLABLE_Y_POSITION ) ) { this . editText . scrollTo ( 0 , Math . max ( MAX_SCROLLABLE_Y_POSITION , 0 ) ) ; } else if ( ( ( int ) ( diffRawY + ( initScrollY ) ) ) < 0 ) { this . editText . scrollTo ( 0 , 0 ) ; } else { this . editText . scrollTo ( 0 , ( ( int ) ( diffRawY + ( initScrollY ) ) ) ) ; } } if ( editText . hasSelection ( ) ) { if ( ( event . getAction ( ) ) == ( MotionEvent . ACTION_DOWN ) ) { } else if ( ( ( event . getAction ( ) ) == ( MotionEvent . ACTION_UP ) ) && ( diffRaw < 20 ) ) { if ( ( ( event . getEventTime ( ) ) - ( downTime ) ) < 150 ) { <START_BUG> TextOffsetHelper . getPositionLineOffset ( location , this . editText , posDownX , ( ( int ) ( ( posDownRawY ) + ( initScrollY ) ) ) ) ; <END_BUG> if ( ( ( tabTime ) != 0 ) && ( ( ( event . getEventTime ( ) ) - ( tabTime ) ) < 200 ) ) { tabTime = 0 ; this . free ( ) ; } else { tabTime = event . getEventTime ( ) ; float centerOfSelection = ( editText . getSelectionStart ( ) ) + ( ( ( editText . getSelectionEnd ( ) ) - ( editText . getSelectionStart ( ) ) ) // 2 ) ; if ( ( location [ 1 ] ) < ( editText . getSelectionStart ( ) ) ) { this . touchOuter ( true , location [ 1 ] ) ; } else if ( ( location [ 1 ] ) > ( editText . getSelectionEnd ( ) ) ) { this . touchOuter ( false , location [ 1 ] ) ; } else if ( ( location [ 1 ] ) <= centerOfSelection ) { this . touchInner ( true , location [ 1 ] ) ; } else if ( ( location [ 1 ] ) > centerOfSelection ) { this . touchInner ( false , location [ 1 ] ) ; } } return true ; } } return true ; } else { if ( ( event . getAction ( ) ) == ( MotionEvent . ACTION_DOWN ) ) { editText . setFocusable ( true ) ; } if ( ( ( ( event . getEventTime ( ) ) - ( downTime ) ) > 150 ) || ( diffRaw > 20 ) ) { free ( ) ; }

Fix:
TextOffsetHelper . getPositionLineOffset ( location , this . editText , posDownX , ( ( int ) ( ( posDownY ) + ( initScrollY ) ) ) ) ;