【问题标题】:How to get view width and height when I added it to window?将视图添加到窗口时如何获取视图宽度和高度?
【发布时间】:2015-07-23 06:27:53
【问题描述】:

我要写一个服务在后台做截图,所以我应该使用服务来做。在这些代码中,我无法创建位图,因为我无法获取宽度和高度

@Override
public void onCreate() {
    super.onCreate();

    try {
        mView = new LinearLayout(this);
        mView.setBackgroundColor(0);
        WindowManager.LayoutParams params = new WindowManager.LayoutParams(
                WindowManager.LayoutParams.MATCH_PARENT,
                WindowManager.LayoutParams.MATCH_PARENT,
                WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
                0 | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                        | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
                        | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
                        | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR
                        | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED,
                PixelFormat.TRANSLUCENT);
        WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
        wm.addView(mView, params);


        //all return 0
        int w = mView.getWidth();
        int h = mView.getHeight();
        w = mView.getMeasuredWidth();
        h = mView.getMeasuredHeight();


        mView.measure(View.MeasureSpec.makeMeasureSpec(
                        View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED),
                View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
        mView.layout(0, 0, mView.getMeasuredWidth(),
                mView.getMeasuredHeight());
        mView.setDrawingCacheEnabled(true);
        mView.buildDrawingCache();
        Bitmap bitmap = Bitmap.createBitmap(mView.getMeasuredWidth(),
                mView.getMeasuredHeight(), Bitmap.Config.ARGB_8888);

        Canvas canvas = new Canvas(bitmap);
        Paint paint = new Paint();
        int height = bitmap.getHeight();
        canvas.drawBitmap(bitmap, 0, height, paint);
        mView.draw(canvas);

        if (bitmap != null) {
            try {
                String filePath = Environment.getExternalStorageDirectory()
                        .toString();
                OutputStream out = null;
                File file = new File(filePath, "/mViewScreenShot.png");
                Log.v("0",file.getPath());
                out = new FileOutputStream(file);

                bitmap.compress(Bitmap.CompressFormat.PNG, 50, out);
                out.flush();
                out.close();
                bitmap.recycle();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    }
    catch(Exception e)
    {
        stopSelf();
    }
    stopSelf();
}

我尝试了getWidth和getMeasuredWidth,它们也返回0

int w = mView.getWidth();
int h = mView.getHeight();
w = mView.getMeasuredWidth();
h = mView.getMeasuredHeight();

而且我在getMeasuredWidth和getMeasuredHeight之前也试过这个,还是不行。

mView.measure(MeasureSpec.UNSPECIFIED,MeasureSpec.UNSPECIFIED)

【问题讨论】:

标签: android android-layout android-service android-view android-windowmanager


【解决方案1】:

绘图后视图会知道它的暗淡。试试这个:

mView.post(new Runnable{
    @Override
    public void run() {
        width = mView.getWidth();
        height = mView.getHeight();
    }
});

【讨论】:

    【解决方案2】:

    您可以使用 ViewTreeObserver 获取视图的宽度和高度。您可以使用它的 onCreate 方法,如下所示:

    LinearLayout layout = (LinearLayout)findViewById(R.id.YOUR_VIEW_ID);
    ViewTreeObserver vto = layout.getViewTreeObserver(); 
    vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() { 
        @Override 
        public void onGlobalLayout() { 
            this.layout.getViewTreeObserver().removeGlobalOnLayoutListener(this); 
            int width  = layout.getMeasuredWidth();
            int height = layout.getMeasuredHeight(); 
    
        } 
    });
    

    【讨论】:

    • 这个答案也应该是接受的答案,但是.post更简单,所以我接受这个答案。
    【解决方案3】:

    getMeasuredWidth()getMeasuredHeight() 不会返回非零值,除非您调用 measure() first

    之后,您可以使用测量值调用layout() 并从getWidth()getHeight() 中获取正确的值。

    mView.measure(View.MeasureSpec.makeMeasureSpec(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
    mView.layout(0, 0, mView.getMeasuredWidth(), mView.getMeasuredHeight());
    int w = mView.getWidth();
    int h = mView.getHeight();
    w = mView.getMeasuredWidth();
    h = mView.getMeasuredHeight();
    

    【讨论】:

    • onLayout 是受保护的访问。
    • @CLSo 这是我的错字,抱歉。您应该调用具有公共访问权限的 layout()。这会在调用两个同步方法 measure() 和 layout() 后立即为您提供所有视图的尺寸。
    猜你喜欢
    • 2023-03-20
    • 2011-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-20
    相关资源
    最近更新 更多