我不知道ViewTreeObserver.addOnPreDrawListener()
,我在一个测试项目中尝试过。
使用您的代码,它看起来像这样:
public void onCreate() {
setContentView(R.layout.main);
final TextView tv = (TextView)findViewById(R.id.image_test);
final LayerDrawable ld = (LayerDrawable)tv.getBackground();
final ViewTreeObserver obs = tv.getViewTreeObserver();
obs.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw () {
Log.d(TAG, "onPreDraw tv height is " + tv.getHeight()); // bad for performance, remove on production
int height = tv.getHeight();
int topInset = height / 2;
ld.setLayerInset(1, 0, topInset, 0, 0);
tv.setBackgroundDrawable(ld);
return true;
}
});
}
在我的测试项目onPreDraw()
中被调用了两次,我认为在你的情况下它可能会导致无限循环。
您可以尝试setBackgroundDrawable()
仅在TextView
更改高度时调用:
private int mLastTvHeight = 0;
public void onCreate() {
setContentView(R.layout.main);
final TextView tv = (TextView)findViewById(R.id.image_test);
final LayerDrawable ld = (LayerDrawable)tv.getBackground();
final ViewTreeObserver obs = mTv.getViewTreeObserver();
obs.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw () {
Log.d(TAG, "onPreDraw tv height is " + tv.getHeight()); // bad for performance, remove on production
int height = tv.getHeight();
if (height != mLastTvHeight) {
mLastTvHeight = height;
int topInset = height / 2;
ld.setLayerInset(1, 0, topInset, 0, 0);
tv.setBackgroundDrawable(ld);
}
return true;
}
});
}
但这对于您要实现的目标来说听起来有点复杂,而且对性能也不是很好。
由 kcoppock 编辑
这就是我最终从这段代码中所做的事情。Gautier的回答让我明白了这一点,所以我宁愿接受这个修改后的答案,也不愿自己回答。我最终改用 ViewTreeObserver 的 addOnGlobalLayoutListener() 方法,就像这样(在 onCreate() 中):
final TextView tv = (TextView)findViewById(R.id.image_test);
ViewTreeObserver vto = tv.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
LayerDrawable ld = (LayerDrawable)tv.getBackground();
ld.setLayerInset(1, 0, tv.getHeight() / 2, 0, 0);
}
});
似乎工作完美;我检查了 LogCat 并没有看到任何异常活动。希望就是这样!谢谢!