为了账号安全,请及时绑定邮箱和手机立即绑定

我什么时候可以先测量视图?

我什么时候可以先测量视图?

郎朗坤 2019-08-12 14:38:09
我什么时候可以先测量视图?所以我在尝试设置视图的背景可绘制时会有点混乱。该代码依赖于知道视线的高度,所以我不能把它onCreate()或onResume(),因为getHeight()返回0 onResume()似乎是最接近我可以得到虽然。我应该在哪里放置如下所示的代码,以便在显示给用户时背景发生变化?    TextView tv = (TextView)findViewById(R.id.image_test);     LayerDrawable ld = (LayerDrawable)tv.getBackground();     int height = tv.getHeight(); //when to call this so as not to get 0?     int topInset = height / 2;     ld.setLayerInset(1, 0, topInset, 0, 0);     tv.setBackgroundDrawable(ld);
查看完整描述

3 回答

?
POPMUISE

TA贡献1765条经验 获得超5个赞

我不知道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编辑

这是我最终通过此代码完成的工作。戈蒂埃的回答让我达到了这一点,所以我宁愿接受这个答案而不是自己回答。我最终使用了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并没有看到任何异常活动。希望就是这样!谢谢!


查看完整回答
反对 回复 2019-08-12
?
HUWWW

TA贡献1874条经验 获得超12个赞

通过使用全局侦听器,您可能会遇到无限循环。

我通过电话来解决这个问题

whateverlayout.getViewTreeObserver().removeGlobalOnLayoutListener(this);

在侦听器中的onGlobalLayout方法内部。


查看完整回答
反对 回复 2019-08-12
  • 3 回答
  • 0 关注
  • 460 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信