Resize image to full width and variable height with Picasso

前端 未结 12 1510
野趣味
野趣味 2020-11-29 17:10

I have a listView with an adapter that contains ImageView of variable size (width and height). I need resize the pictures load with Picasso to the max width of

相关标签:
12条回答
  • 2020-11-29 17:47
    Picasso.get()
    .load(message_pic_url)
    .fit()
    .centerCrop()
    .placeholder(R.drawable.profile_wall_picture)
    .into(holder.message_picture);
    

    Try this code, Worked for me.

    0 讨论(0)
  • 2020-11-29 17:52
    @Override
        protected void onResume() {
            super.onResume();
    
            imageView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                @Override
                public void onGlobalLayout() {
                    loadImageIfReady();
                }
            });
    
        }
    
        private void loadImageIfReady() {
            if (imageView.getMeasuredWidth() <= 0 || mPayload == null)
                this.finish();    // if not ready GTFO
    
            Picasso.with(this)
                        .load(mPayload)
                        .resize(imageView.getMeasuredWidth(), imageView.getMeasuredWidth())
                        .centerInside()
                        .into(imageView);
    
    
        }
    
    0 讨论(0)
  • 2020-11-29 17:53

    Finally I solved it doing a transformation of Picasso, here is the snippet:

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

    This line is for customize with your desired width:

    int targetWidth = holder.message_picture.getWidth();
    

    Additionally this snipped include Callback for loading hide and error drawable built-in Picasso.

    If you need more information to debug any error, you MUST implement a custom listener (Picasso builder) beacuse the onError Callback information is "null". You only know that there is an error for UI behavior.

    I hope this helps someone to save many hours.

    0 讨论(0)
  • 2020-11-29 17:54

    As of Picasso 2.4.0, this operation is now directly supported. Simply add a .resize() request with one of the dimensions as 0. For example, to have a variable width, your call would become:

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

    Note that this call uses .getHeight() and therefore assumes the message_picture has already been measured. If that isn't the case, such as when you have inflated a new view in a ListAdapter, you can delay this call until after measurement by adding an OnGlobalLayoutListener to the view:

    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);
                }
            });
    
    0 讨论(0)
  • 2020-11-29 18:02
        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"/>
    

    This will help you with variable height of images for all devices

    0 讨论(0)
  • 2020-11-29 18:06

    extend ImageView then override onMeasure method like the following.

    @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
            Drawable d = getDrawable();
    
            if(d!=null && fittingType == FittingTypeEnum.FIT_TO_WIDTH){
                int width = MeasureSpec.getSize(widthMeasureSpec);
                int height = (int) Math.ceil((float) width * (float) d.getIntrinsicHeight() / (float) d.getIntrinsicWidth());
                setMeasuredDimension(width, height);
            }else{
                super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            }
        }
    
    0 讨论(0)
提交回复
热议问题