简体   繁体   English

如何在每次绘制到 UI 之前获取 ImageView 的高度和宽度(在 Fragment 中)

[英]How to get ImageView Height and Width every time, before it is drawn to the UI (in a Fragment)

I want to set a Photo from the external Storage into a (Circular)ImageView.我想将外部存储中的照片设置为(圆形)ImageView。 Therefore I have a function, that asks for the ImageView Hight and Width, to crop the Picture and then sets it as Bitmap.因此我有一个函数,它要求 ImageView 的高度和宽度来裁剪图片,然后将其设置为位图。

My Problem is, that this function gets called before the UI is loaded.我的问题是,在加载 UI 之前调用此函数。 I came across with the solution, that I call this function the first time, in onViewCreated, where I add a Listener to addOnWindowFocusChangeListener.我遇到了解决方案,我第一次在 onViewCreated 中调用了这个函数,在那里我向 addOnWindowFocusChangeListener 添加了一个监听器。 This works for the first time.这是第一次起作用。

The fragment is inside a ViewPager and if I go to the fragment on the left and then over the middle to the right, it is again gone.该片段在 ViewPager 内,如果我转到左侧的片段,然后从中间转到右侧,它又消失了。

I am completely new to StackOverflow.我对 StackOverflow 完全陌生。 I appreciate every Tip, what I can do better.我很欣赏每一个提示,我可以做得更好。

//This works for the First Time

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        View m = getView();
        ViewTreeObserver n = m.getViewTreeObserver();
        n.addOnWindowFocusChangeListener(new ViewTreeObserver.OnWindowFocusChangeListener() {
            @Override
            public void onWindowFocusChanged(final boolean hasFocus) {
                // do your stuff here
                ImageUtil.setPic(binding.photoRoundProfile, mCurrentPhotoPath);

            }
        });
    }
//The function where I set the Picture into the ImageView

static public void setPic(ImageView mImageView, String pPath) {
        try {
            if (pPath == null) return;
            File f = new File(pPath);
            if (!f.exists() || f.isDirectory()) return;

            // Get the dimensions of the View
            int targetW = mImageView.getWidth();
            if (targetW == 0) targetW = mImageView.getMeasuredWidth();
            int targetH = mImageView.getHeight();
            if (targetH == 0) targetH = mImageView.getMeasuredHeight();

            // Get the dimensions of the bitmap
            BitmapFactory.Options bmOptions = new BitmapFactory.Options();
            bmOptions.inJustDecodeBounds = true;
            BitmapFactory.decodeFile(pPath, bmOptions);
            int photoW = bmOptions.outWidth;
            int photoH = bmOptions.outHeight;

            // Determine how much to scale down the image
            int scaleFactor = photoW / targetW; //Math.min(photoW/targetW, photoH/targetH);

            // Decode the image file into a Bitmap sized to fill the View
            bmOptions.inJustDecodeBounds = false;
            bmOptions.inSampleSize = scaleFactor;
            bmOptions.inPurgeable = true;

            Bitmap bitmap = BitmapFactory.decodeFile(pPath, bmOptions);
            Bitmap orientedBitmap = ExifUtil.rotateBitmap(pPath, bitmap);
            mImageView.setImageBitmap(orientedBitmap);

            //mImageView.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
            mImageView.setAdjustViewBounds(true);
            mImageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

There is a video, for better understanding: https://www.loom.com/share/05c4174562d74c9bba8ff02c9072c866有个视频,为了更好的理解: https : //www.loom.com/share/05c4174562d74c9bba8ff02c9072c866

I found a solution to my problem.我找到了解决我的问题的方法。 I have found the Method onPreDraw in OnPreDrawListener .我在OnPreDrawListener找到了onPreDraw方法。 This Listener runs every time the ImageView is updated.每次更新ImageView都会运行此侦听器。 Therefore I added an if-Statement to save performance and not redrawing every time.因此我添加了一个 if-Statement 来节省性能而不是每次都重绘。

@Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        ImageView iv= binding.photoRoundProfile;
        ViewTreeObserver vto = iv.getViewTreeObserver();
        vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {

            private int mFinalWidth = 0;
            private int mFinalHeight = 0;

            public boolean onPreDraw() {

                if(mFinalHeight != 0 || mFinalWidth != 0)
                    return true;

                mFinalHeight = iv.getHeight();
                mFinalWidth = iv.getWidth();
                Log.d("hilength","Height: " + mFinalHeight + " Width: " + mFinalWidth);

                ImageUtil.setPic(binding.photoRoundProfile, mCurrentPhotoPath);
                return true;
            }
        });
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM