[android] Picasso를 사용하여 이미지를 전체 너비 및 가변 높이로 크기 조정

ImageView가변 크기 (너비 및 높이) 가 포함 된 어댑터가있는 listView가 있습니다 . Picasso를 사용하여 그림로드의 크기를 레이아웃의 최대 너비와 그림의 가로 세로 비율로 지정된 가변 높이로 조정해야합니다.

이 질문을 확인했습니다 :
Picasso를 사용하여 이미지를 전체 너비와 고정 높이로 크기 조정

fit()작동하지만 사진의 가로 세로 비율을 유지하기 위해 아무것도 발견하지 않았습니다.

이 코드는 어댑터 레이아웃에서 높이를 고정하면 부분적으로 작동합니다.

Picasso.with(this.context).load(message_pic_url)
.placeholder(R.drawable.profile_wall_picture)
.fit().centerInside()
.into(holder.message_picture);

그러나 그림이 해당 높이가 없을 수 있기 때문에 listView 그림 사이에 공백을 생성합니다.

미리 감사드립니다.



답변

Picasso 2.4.0부터이 작업은 이제 직접 지원됩니다 . 단순히 추가 .resize()로 치수 중 하나를 요청 0. 예를 들어 가변 너비를 가지려면 다음과 같이 호출합니다.

Picasso.with(this.context)
       .load(message_pic_url)
       .placeholder(R.drawable.profile_wall_picture)
       .resize(0, holder.message_picture.getHeight()),
       .into(holder.message_picture);

이 호출은를 사용 .getHeight()하므로 message_picture이미 측정되었다고 가정합니다 . 그렇지 않은 경우 (예 :에서 새 뷰를 확장 한 ListAdapter경우) 뷰에 를 추가하여 측정 후까지이 호출을 지연 할 수 OnGlobalLayoutListener있습니다.

holder.message_picture.getViewTreeObserver()
      .addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            // Wait until layout to call Picasso
            @Override
            public void onGlobalLayout() {
                // Ensure we call this only once
                imageView.getViewTreeObserver()
                         .removeOnGlobalLayoutListener(this);


                Picasso.with(this.context)
                       .load(message_pic_url)
                       .placeholder(R.drawable.profile_wall_picture)
                       .resize(0, holder.message_picture.getHeight())
                       .into(holder.message_picture);
            }
        });


답변

나는 같은 문제를 만났고 해결책을 찾는 데 시간이 걸렸지 만 마침내 나를 위해 일하는 것을 발견했습니다.

먼저 Picasso 호출을

Picasso.with(this.context).load(message_pic_url)
.placeholder(R.drawable.profile_wall_picture)
.into(holder.message_picture);

제거 단계 fit와를 centerInside. 다음으로 XML의 ImageView에 다음 줄을 추가해야합니다.

android:scaleType="fitStart"
android:adjustViewBounds="true"

바라건대 그것은 당신에게도 효과가있을 것입니다.


답변

마지막으로 피카소를 변환하여 해결했습니다. 여기에 스 니펫이 있습니다.

    Transformation transformation = new Transformation() {

        @Override
        public Bitmap transform(Bitmap source) {
            int targetWidth = holder.message_picture.getWidth();

            double aspectRatio = (double) source.getHeight() / (double) source.getWidth();
            int targetHeight = (int) (targetWidth * aspectRatio);
            Bitmap result = Bitmap.createScaledBitmap(source, targetWidth, targetHeight, false);
            if (result != source) {
                // Same bitmap is returned if sizes are the same
                source.recycle();
            }
            return result;
        }

        @Override
        public String key() {
            return "transformation" + " desiredWidth";
        }
    };

    mMessage_pic_url = message_pic_url;

    Picasso.with(this.context)
        .load(message_pic_url)
        .error(android.R.drawable.stat_notify_error)
        .transform(transformation)
        .into(holder.message_picture, new Callback() {
            @Override
            public void onSuccess() {
                holder.progressBar_picture.setVisibility(View.GONE);
            }

            @Override
            public void onError() {
                Log.e(LOGTAG, "error");
                holder.progressBar_picture.setVisibility(View.GONE);
            }
    });

이 줄은 원하는 너비로 사용자 지정하기위한 것입니다.

int targetWidth = holder.message_picture.getWidth();

또한 여기에는 숨김 및 오류 드로어 블 내장 Picasso를로드하기위한 콜백이 포함됩니다.

오류를 디버깅하기 위해 추가 정보가 필요한 경우 onError Callback정보가 “null”이므로 사용자 정의 리스너 (Picasso 빌더)를 구현해야합니다 . UI 동작에 오류가 있다는 것만 알고 있습니다.

누군가가 많은 시간을 절약하는 데 도움이되기를 바랍니다.


답변

허용의 대답은 모두에게 유용하지만 여러 바인딩하는 경우 ViewHolder복수를 위해 Views당신은을위한 클래스를 생성하여 코드를 줄일 수 있습니다 변환 및 전달 이미지 뷰를 에서 ViewHolder.

/**
 * Created by Pratik Butani
 */
public class ImageTransformation {

    public static Transformation getTransformation(final ImageView imageView) {
        return new Transformation() {

            @Override
            public Bitmap transform(Bitmap source) {
                int targetWidth = imageView.getWidth();

                double aspectRatio = (double) source.getHeight() / (double) source.getWidth();
                int targetHeight = (int) (targetWidth * aspectRatio);
                Bitmap result = Bitmap.createScaledBitmap(source, targetWidth, targetHeight, false);
                if (result != source) {
                    // Same bitmap is returned if sizes are the same
                    source.recycle();
                }
                return result;
            }

            @Override
            public String key() {
                return "transformation" + " desiredWidth";
            }
        };
    }
}

에서 전화 ViewHolder:

Picasso.with(context).load(baseUrlForImage)
                     .transform(ImageTransformation.getTransformation(holder.ImageView1))
                     .error(R.drawable.ic_place_holder_circle)
                     .placeholder(R.drawable.ic_place_holder_circle)
                     .into(holder.mMainPhotoImageView1);

그것이 당신을 도울 수 있기를 바랍니다.


답변

    Picasso.with(this).load(url).resize(1800, 1800).centerInside().into(secondImageView)

    <ImageView
        android:id="@+id/SecondImage"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentStart="true"
        android:layout_alignParentLeft="true"
        android:adjustViewBounds="true"
        android:layout_margin="10dp"
        android:visibility="gone"/>

이것은 모든 장치에 대해 다양한 이미지 높이를 지원합니다.


답변

레이아웃 완료 리스너를 추가하고 레이아웃 프로세스가 완료되면 (imageView)를 호출하는 간단한 도우미를 작성했습니다.

public class PicassoDelegate {

private RequestCreator mRequestCreator;

public PicassoDelegate(ImageView target, RequestCreator requestCreator) {
    if (target.getWidth() > 0 && target.getHeight() > 0) {
        complete(target, requestCreator);
    } else {
        mRequestCreator = requestCreator;
        target.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
            @Override
            public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
                v.removeOnLayoutChangeListener(this);
                complete((ImageView) v, mRequestCreator);
            }
        });

    }

}

private void complete(ImageView target, RequestCreator requestCreator) {
    if (target.getWidth() > 0 && target.getHeight() > 0) {
        requestCreator.resize(target.getWidth(), target.getHeight());
    }

    requestCreator.into(target);
}

}

따라서 예를 들어 조각의 onViewCreated ()에서 이와 같이 쉽게 사용할 수 있습니다.

new PicassoDelegate(customerPhoto, Picasso.with(getActivity()).load(user.getPhotoUrl()).centerCrop());


답변

imageView.post(new Runnable() {
      @Override public void run() {
        Picasso.with(context)
            .resize(0, imageView.getHeight())
            .onlyScaleDown()
            .into(imageView, new ImageCallback(callback, null));
      }
    });