Как получать высоту и ширину изображения каждый раз, прежде чем оно будет отображено в пользовательском интерфейсе (во фрагменте)

#java #android #android-fragments #android-viewpager #imageview

#java #Android #android-фрагменты #android-viewpager #imageview

Вопрос:

Я хочу установить фотографию из внешнего хранилища в (круговой) вид изображения. Поэтому у меня есть функция, которая запрашивает высоту и ширину изображения, чтобы обрезать изображение, а затем устанавливает его как растровое изображение.

Моя проблема в том, что эта функция вызывается до загрузки пользовательского интерфейса. Я столкнулся с решением, что я вызываю эту функцию в первый раз, в onViewCreated, где я добавляю слушателя в addOnWindowFocusChangeListener. Это работает в первый раз.

Фрагмент находится внутри ViewPager, и если я перейду к фрагменту слева, а затем к середине справа, он снова исчезнет.

Я совершенно новичок в StackOverflow. Я ценю каждый совет, что я могу сделать лучше.

 //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();
        }
    }
  

Для лучшего понимания есть видео:https://www.loom.com/share/05c4174562d74c9bba8ff02c9072c866

Ответ №1:

Я нашел решение своей проблемы. Я нашел метод onPreDraw в OnPreDrawListener . Этот прослушиватель запускается каждый раз, когда ImageView обновляется. Поэтому я добавил оператор if, чтобы сохранить производительность и не перерисовывать каждый раз.

 @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;
            }
        });
    }