共享图像元素过渡显示大小不正确

12

我有一个Recycle View用于显示所有照片缩略图项。当点击某个项时,我使用转换将此项中的ImageView传递到详细活动中。问题在于,图片源是通过UIL从互联网上获取的。并且有时(并非总是),图像不能重新加载正确的大小,如下所示:

transition error

 // on view holder item click
  final Pair<View, String>[] pairs = TransitionHelper.createSafeTransitionParticipants(this, false,
                    new Pair<>(((ItemViewHolder) viewHolder).thumbnail, getString(R.string.TransitionName_Profile_Image)),
                    new Pair<>(((ItemViewHolder) viewHolder).tvName, getString(R.string.TransitionName_Profile_Name)));

  ActivityOptionsCompat transitionActivityOptions = ActivityOptionsCompat.makeSceneTransitionAnimation(this, pairs);
  startActivityForResult(intent, requestCode, transitionActivityOptions.toBundle());

详细活动

// try to post pone transition until UIL load finish
ActivityCompat.postponeEnterTransition(this);
getSupportFragmentManager().beginTransaction().replace(R.id.layoutContent, new DetailFragment()).commit();

片段详情

ImageLoader.getInstance().displayImage(url, imageViewDetail, new ImageLoadingListener() {
                @Override
                public void onLoadingStarted(String imageUri, View view) {

                }

                @Override
                public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
                    finishAnimation();
                }

                @Override
                public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {

                    finishAnimation();
                }

                @Override
                public void onLoadingCancelled(String imageUri, View view) {
                    finishAnimation();
                }
            });


 private void finishAnimation(){
     ActivityCompat.startPostponedEnterTransition(getActivity());
     imageViewDetail.invalidate();
 }

fragment_detail.xml

 <FrameLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >

     <ImageView
        android:transitionName="@string/TransitionName.Profile.Image"
        android:id="@+id/imageViewDetail"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:adjustViewBounds="true"
        android:scaleType="centerCrop"/>
</FrameLayout>

我甚至等待视图布局完成后再加载图片,但仍然不起作用:

imageViewDetail.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
            @Override
            public boolean onPreDraw() {
                // code load image from UIL
                return false;
            }
        });

有什么方法可以避免这个问题吗?


你正在使用centerCrop,也许这是个问题,尝试使用不同的缩放类型。 - h_patel
@Himani 嗯,我必须使用它,因为照片必须适合屏幕并保持比例。但是你有关于 scaletype 错误的线索吗?它在许多情况下都可以工作,但有时候看起来好像图像没有准备好。 - ductran
@Himani 首先,fitXY不保持长宽比。第二,仍然不起作用。 - ductran
@R4j,你事先知道源图像的纵横比吗?我曾经遇到过类似的图片问题。但在我的情况下,我事先知道我的图片的纵横比,即2:3。因此,我有一个ImageView,在运行时根据设备屏幕大小动态更改ImageView的尺寸。如果这是您的要求,我可以发布执行此操作的代码。 - Adithya Upadhya
@kingston 不,我退出并删除转换。 - ductran
显示剩余4条评论
1个回答

0

这个 XML 可以处理不同的图片尺寸

 <ScrollView
        android:id="@+id/vScroll"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginBottom="51dp"
        android:scrollbars="none" >

        <HorizontalScrollView
            android:id="@+id/hScroll"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:scrollbars="none" 
            android:layout_gravity="center">

            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" >

                <ImageView
                    android:id="@+id/imgFullscreen"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:scaleType="fitXY" />
            </LinearLayout>
        </HorizontalScrollView>
    </ScrollView>

在Java中

fullImageView = (ImageView) findViewById(R.id.imgFullscreen);
selectedPhoto = (FeedItem) i.getSerializableExtra(TAG_SEL_IMAGE);
        zoom = 1;

        if (selectedPhoto != null) {
            fetchFullResolutionImage();
        } else {
            Toast.makeText(getApplicationContext(),
                    getString(R.string.msg_unknown_error), Toast.LENGTH_SHORT)
                    .show();
        }



private void fetchFullResolutionImage() {
    try {
        final URL url = new URL(selectedPhoto.getImge());       
        new Thread(new Runnable() {

            @Override
            public void run() {
                try {
                    Bitmap bmp = BitmapFactory.decodeStream(url
                            .openStream());
                    if (bmp != null)
                        setImage(bmp);
                    else {
                        showToast("Error fetching image!");
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    } catch (IOException e) {
        e.printStackTrace();
    }

}
private void setImage(final Bitmap bmp) {
        runOnUiThread(new Runnable() {
            public void run() {
                fullImageView.setImageBitmap(bmp);
                adjustImageAspect(selectedPhoto.getWidth(),
                        selectedPhoto.getHeight());
            }
        });
    }
private void adjustImageAspect(int bWidth, int bHeight) {
        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
                LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
        if (bWidth == 0 || bHeight == 0)
            return;
        int swidth;

        if (android.os.Build.VERSION.SDK_INT >= 13) {
            Display display = getWindowManager().getDefaultDisplay();
            Point size = new Point();
            display.getSize(size);
            swidth = size.x;
        } else {
            Display display = getWindowManager().getDefaultDisplay();
            swidth = display.getWidth();
        }

        int new_height = 0;
        new_height = swidth * bHeight / bWidth;
        params.width = swidth;
        params.height = new_height;
        saveW = swidth;
        saveH = new_height;
        fullImageView.setLayoutParams(params);
    }

我的问题是过渡问题,而不是图像缩放。你的代码只是将图像缩放以适应屏幕高度。 - ductran

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接