android触摸坐标有负值,android pading的四个值,为负值时,什么情况下,有效啊

在我的理解中, 设置 padding 为负值和设置为0在显示上不会有什么区别, 所以, 你想要的效果是什么?

OK, 之前没有自习考虑这个问题, 现在帮你分析一下.

首先, 从 xml 中解析 padding 值是在父类 View 中进行的, 在 View 的 构造方法中可以看到下面的代码:

public View(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {

....

int attr = a.getIndex(i);

switch (attr) {

case com.android.internal.R.styleable.View_background:

background = a.getDrawable(attr);

break;

case com.android.internal.R.styleable.View_padding:

padding = a.getDimensionPixelSize(attr, -1);

mUserPaddingLeftInitial = padding;

mUserPaddingRightInitial = padding;

leftPaddingDefined = true;

rightPaddingDefined = true;

break;

case com.android.internal.R.styleable.View_paddingLeft:

leftPadding = a.getDimensionPixelSize(attr, -1);

mUserPaddingLeftInitial = leftPadding;

leftPaddingDefined = true;

break;

case com.android.internal.R.styleable.View_paddingTop:

topPadding = a.getDimensionPixelSize(attr, -1);

break;

case com.android.internal.R.styleable.View_paddingRight:

rightPadding = a.getDimensionPixelSize(attr, -1);

mUserPaddingRightInitial = rightPadding;

rightPaddingDefined = true;

break;

case com.android.internal.R.styleable.View_paddingBottom:

bottomPadding = a.getDimensionPixelSize(attr, -1);

break;

// ...

}

....

// setBackground above will record that padding is currently provided by the background.

// If we have padding specified via xml, record that here instead and use it.

mLeftPaddingDefined = leftPaddingDefined;

mRightPaddingDefined = rightPaddingDefined;

if (padding >= 0) {

leftPadding = padding;

topPadding = padding;

rightPadding = padding;

bottomPadding = padding;

mUserPaddingLeftInitial = padding;

mUserPaddingRightInitial = padding;

}

....

internalSetPadding(

mUserPaddingLeftInitial,

topPadding >= 0 ? topPadding : mPaddingTop,

mUserPaddingRightInitial,

bottomPadding >= 0 ? bottomPadding : mPaddingBottom);

....

}

从上面的代码可以看到, 如果通过设置 android:padding 的方式, 那么只有当 padding 值大于等于0才会被赋值给上下左右的 padding. 这就解释了为什么我的实验中 padding 为负值并不会有影响. 同时在调用 internalSetPadding() 方法时, 上下 padding 值都对是否为负值做了判断, 以保证其为正值, 所以我使用你的代码中的参数, 但是将 android:paddingTop 设为负值也没有出现文字不可见的情况.

接下来, View 在自己的区域中如何进行绘制是由每一个 View 的子类自己实现的, 并不是所有的 View 子类都会有设置 paddingLeft 会使内容截断甚至隐藏的情况, 至少目前我试了以后发现只有 TextView 及其子类会. OK, 那看一下 TextView 是怎么绘制文字的:

@Override

protected void onDraw(Canvas canvas) {

....

final int compoundPaddingLeft = getCompoundPaddingLeft();

final int compoundPaddingTop = getCompoundPaddingTop();

final int compoundPaddingRight = getCompoundPaddingRight();

final int compoundPaddingBottom = getCompoundPaddingBottom();

....

canvas.save();

int extendedPaddingTop = getExtendedPaddingTop();

int extendedPaddingBottom = getExtendedPaddingBottom();

final int vspace = mBottom - mTop - compoundPaddingBottom - compoundPaddingTop;

final int maxScrollY = mLayout.getHeight() - vspace;

float clipLeft = compoundPaddingLeft + scrollX;

....

if (mShadowRadius != 0) {

clipLeft += Math.min(0, mShadowDx - mShadowRadius);

....

}

canvas.clipRect(clipLeft, clipTop, clipRight, clipBottom);

....

canvas.translate(compoundPaddingLeft, extendedPaddingTop + voffsetText);

....

mEditor.onDraw(canvas, layout, highlight, mHighlightPaint, cursorOffsetVertical);

....

canvas.restore();

}

....

public int getCompoundPaddingLeft() {

final Drawables dr = mDrawables;

if (dr == null || dr.mShowing[Drawables.LEFT] == null) {

return mPaddingLeft;

} else {

return mPaddingLeft + dr.mDrawablePadding + dr.mDrawableSizeLeft;

}

}

public int getExtendedPaddingTop() {

if (mMaxMode != LINES) {

return getCompoundPaddingTop();

}

....

}

从上面 TextView 类的 onDraw 方法中可以看到, 在

canvas.translate(compoundPaddingLeft, extendedPaddingTop + voffsetText);

这一句中, 画布 canvas 对象进行了平移, 而在这之前并没有对 compoundPaddingLeft 进行负值判定, 因此, 对 TextView 设置 android:paddingLeft 是会使内容文字被截掉的.

所以, 题主想要的"原理"其实很简单, 那就是每一个 View 子类里面的内容怎么绘制是由它的 onDraw() 方法确定的. (当然还有 draw(), dispatchDraw() 这些, 不细说.)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值