android通过反射获取光标位置

/**
 * @return the coordinate of cursor. x=float[0]; y=float[1];
 */
private float[] getCursorCoordinate (){
 /*
   *以下通过反射获取光标cursor的坐标。
   * 首先观察到TextViewinvalidateCursorPath()方法,它是光标闪动时重绘的方法。
   * 方法的最后有个invalidate(bounds.left + horizontalPadding, bounds.top + verticalPadding,
               bounds.right + horizontalPadding, bounds.bottom + verticalPadding);
   *即光标重绘的区域,由此可得到光标的坐标
   * 具体的坐标在TextView.mEditor.mCursorDrawable里,获得Drawable之后用getBounds()得到Rect
   * 之后还要获得偏移量修正,通过以下三个方法获得:
   * getVerticalOffset(),getCompoundPaddingLeft(),getExtendedPaddingTop()
   *
  */

    int xOffset = 0;
    int yOffset = 0;
    Class<?> clazz = EditText.class;
    clazz = clazz.getSuperclass();
    try {
        Field editor = clazz.getDeclaredField("mEditor");
        editor.setAccessible(true);
        Object mEditor = editor.get(mEditText);
        Class<?> editorClazz = Class.forName("android.widget.Editor");
        Field drawables = editorClazz.getDeclaredField("mCursorDrawable");
        drawables.setAccessible(true);
        Drawable[] drawable= (Drawable[]) drawables.get(mEditor);

        Method getVerticalOffset = clazz.getDeclaredMethod("getVerticalOffset",boolean.class);
        Method getCompoundPaddingLeft = clazz.getDeclaredMethod("getCompoundPaddingLeft");
        Method getExtendedPaddingTop = clazz.getDeclaredMethod("getExtendedPaddingTop");
        getVerticalOffset.setAccessible(true);
        getCompoundPaddingLeft.setAccessible(true);
        getExtendedPaddingTop.setAccessible(true);
        if (drawable != null){
            Rect bounds = drawable[0].getBounds();
            Log.d(TAG,bounds.toString());
            xOffset = (int) getCompoundPaddingLeft.invoke(mEditText) + bounds.left;
            yOffset = (int) getExtendedPaddingTop.invoke(mEditText) + (int)getVerticalOffset.invoke(mEditText, false)+bounds.bottom;
        }
    } catch (NoSuchMethodException e) {
        e.printStackTrace();
    } catch (InvocationTargetException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    } catch (NoSuchFieldException e) {
        e.printStackTrace();
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }
    float x = mEditText.getX() + xOffset;
    float y = mEditText.getY() + yOffset;

    return new float[]{ x , y};
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值