Android:需要在扩展Activity的类中使用onSizeChanged for View.getWidth/Height()

KWT*_*KWT 17 android

我想使用getWidth()/ getHeight()来获取XML-Layout的宽度/高度.我读过我必须在方法onSizeChanged()中这样做,否则我会得到0(Android:获取屏幕分辨率/像素作为整数值).

但是我想在已经扩展Activity的类中做到这一点.所以我认为不可能让同一个类扩展View.

public class MyClass extends Activity {

    public void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.main);  
        ViewGroup xml_layout = (ViewGroup) findViewById(R.id.layout_id);  
        TextView tv = new TextView(this);  
        tv = (TextView) findViewById(R.id.text_view);  
        int layout_height = xml_layout.getHeight();  
        int layout_width = xml_layout.getWidth();
    }  

    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        //Error, because I need to use extends View for class, but I can't do it because I also need extends Activity to use onCreate
    }
}
Run Code Online (Sandbox Code Playgroud)

如果我使用MyClass扩展Activity我可以使用onCreate但不能使用onSizeChanged.
如果我使用MyClass extends View我可以使用onSizeChangedbut而不是onCreate.

我该如何解决这个问题?

kaj*_*ham 36

你不必创建一个customView来获得它的高度和宽度.你可以你想要的宽度/高度的视图中添加一个OnLayoutChangedListener(这里的描述),然后基本上获取onLayoutChanged方法中的值,就像这样

View myView = findViewById(R.id.my_view);
myView.addOnLayoutChangeListener(new OnLayoutChangeListener() {

        @Override
        public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight,
                int oldBottom) {
            // its possible that the layout is not complete in which case
            // we will get all zero values for the positions, so ignore the event
            if (left == 0 && top == 0 && right == 0 && bottom == 0) {
                return;
            }

           // Do what you need to do with the height/width since they are now set
        }
    });
Run Code Online (Sandbox Code Playgroud)

原因是因为只有在布局完成后才会绘制视图.然后系统沿着视图层次树走下去,在绘制之前测量每个视图的宽度/高度.

  • OnLayoutChangeListener假设您的目标是API 11+ (7认同)
  • 谢谢你指出这一点,@ CarWhalley!我意识到,当尝试在API 10中使用它:).我实际上发现,如果布局的高度/宽度不依赖于由任何其他布局确定(在相对布局中使用或使用布局权重),您甚至可以强制按如下方式测量视图:view.measure( MeasureSpec.UNSPECIFIED,MeasureSpec.UNSPECIFIED)然后使用getMeasuredHeight/Width获取值 (3认同)

Raw*_*Bag 20

我建议你做的是在你自己的自定义类中扩展ListView.定义一个名为MyListView的类或类似的类,并确保定义所有三个构造函数.然后,重写onSizeChanged方法以在外部调用某些东西 - 非常类似于OnClickListener或OnTouchListener.您可以在MyListView中定义一个方法来接受一个监听器,在您的活动中实例化一个监听器,然后在调用onSizeChanged时将其传递给监听器.这真的很难用英语解释.以下是一些示例代码:

自定义ListView:

public class MyListView extends ListView
{
    public MyListView(Context context)
    {
        super(context);
    }
    public MyListView(Context context, AttributeSet attrs)
    {
        super(context, attrs);
    }
    public MyListView(Context context, AttributeSet attrs, int defStyle)
    {
        super(context, attrs, defStyle);
    }

    public void SetOnResizeListener(MyOnResizeListener orlExt)
    {
        orl = orlExt;
    }

    @Override
    protected void onSizeChanged(int xNew, int yNew, int xOld, int yOld)
    {
        super.onSizeChanged(xNew, yNew, xOld, yOld);

        if(orl != null)
        {
            orl.OnResize(this.getId(), xNew, yNew, xOld, yOld);
        }
    }

    MyOnResizeListener orl = null;
 }
Run Code Online (Sandbox Code Playgroud)

自定义监听器:

public class MyOnResizeListener
 {
    public MyOnResizeListener(){}

    public void OnResize(int id, int xNew, int yNew, int xOld, int yOld){}
 }
Run Code Online (Sandbox Code Playgroud)

您实例化侦听器,如:

Class MyActivity extends Activity
{
      /***Stuff***/

     MyOnResizeListener orlResized = new MyOnResizeListener()
     {
          @Override
          public void OnResize(int id, int xNew, int yNew, int xOld, int yOld)
          {
           /***Handle resize event****/
          }
     };
}
Run Code Online (Sandbox Code Playgroud)

并且不要忘记将您的监听器传递给您的自定义视图:

 /***Probably in your activity's onCreate***/
 ((MyListView)findViewById(R.id.MyList)).SetOnResizeListener(orlResized);
Run Code Online (Sandbox Code Playgroud)

最后,您可以通过执行以下操作将自定义列表添加到XML布局:

 <com.myapplication.whatever.MyListView>
      <!-- Attributes -->
 <com.myapplication.whatever.MyListView/>
Run Code Online (Sandbox Code Playgroud)


use*_*209 1

只需将一个方法添加到您的自定义视图中,当 Activity 中发生 onSizeChanged 时,您将调用该方法。将新值作为被调用方法的参数传递给视图。然后,当您的自定义视图更改大小时,执行需要执行的任何操作。