Layout a view after resizing

I'm creating a grid that displays values that change very often. Because of this, I'm using a TextView that autoresizes when its content changes (Auto Scale TextView Text to Fit within Bounds). The resize takes place, but the view doesn't layout properly

调整大小后的布局

The thing is, when I examine the activity with HierarchyViewer the layout displays as I want.

hierarchyviewer之后的布局

My guess is that HierarchyViewer invokes requestLayout() or invalidate() on the view, but I've tried that with no success. This code is invoked in the main activity with no effect.

new Handler().postDelayed(new Runnable() {            
            @Override
            public void run() {
              getWindow().getDecorView().requestLayout();
              getWindow().getDecorView().invalidate();
            }
          }, 5000);

I've also tried invalidating the view after resizing.

The TextView has gravity set to Center, and if no resize takes place, it looks ok.

Any hint will be welcome, thanks in advance!


I solved it by overriding onLayout in one of the TextView's parent and using a Handler created in the constructor

public class CellView extends LinearLayout{
   public CellView(Context context) {
     super(context);

     mHandler = new Handler();

     View.inflate(context, R.layout.cellview, this);
  }

 @Override
  protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
    if(changed){
      mHandler.post(new Runnable() {          
        @Override
        public void run() {
          requestLayout();
        }
      });
    }

   super.onLayout(changed, left, top, right, bottom);
  }

I had tried calling requestLayout inside TextView's onLayout, tho it didn't work, I'm not sure why. It might be because the value was updated through an Observer, but the onTextChanged listener should happen in the UI Thread. I hope it serves someone else


The way requestLayout() works is that when called on a view, it will schedule a layout pass on itself and all of it's children. This is desirable whenever a view has shifted or resized do to margin, padding, or content changes.

The documentation on the method getDecorView() isn't very clear on what exactly it gives you. However, per the documentation on the website:

Note that calling this function for the first time "locks in" various window characteristics as described in setContentView(View, android.view.ViewGroup.LayoutParams).

This leaves me to believe that there's something special about the view that getDecorView() retrieves. What you are probably doing is making the layout of the view permanent thus never changing when you make a requestLayout() pass.

This is apparently the proper way to get the root view of your entire activity.

However, for efficiency reasons, I recommend calling requestLayout() on the lowest child you possibly can. Like I said before, it schedules a layout pass on a view and it's children. If you do a layout pass on the top-most view, you're essientially rebuilding everything which includes the views that stay in place.


您可能需要使用runOnUiThread在UI线程中运行计时器代码,如此处所述。

链接地址: http://www.djcxy.com/p/64706.html

上一篇: Chrome扩展程序History API

下一篇: 调整大小后布局视图