如何在 Recyclerview 交错网格布局中使用 Picasso 加载图像之前设置 ImageView 的高度和宽度

How to set ImageView height and width before image is loaded with Picasso inside Recycerview StaggeredGridLayout

我希望在使用 Picasso 加载图像之前设置 ImageView 高度。试图阻止父视图将其高度更改为图像。我正在获取图像的高度和宽度并将其设置在 Picasso 内部,然后按比例缩小。

如何在使用 Picasso 加载图像之前根据 "webformatHeight" 和 "webformatWidth" 缩放 ImageView 以防止调整大小。

数据

{
    ...
    "hits":[
        {
            "webformatHeight":426,
            "webformatWidth":640,
            "webformatURL":"https://pixabay.com/get/eb32b5062dfd013ed95c4518b74a4291ea77ead204b0144190f8c478a2ebb3_640.jpg",
            ...
        },
        ...
    ]
}

回收器实施

RecyclerView recycler = (RecyclerView) findViewById(R.id.recycler);
mPixabayAdapter = new PixabayAdapter();
recycler.setLayoutManager(new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL));
recycler.setAdapter(mPixabayAdapter);

ViewHolder

class ViewHolder extends RecyclerView.ViewHolder {

    private ImageView mImage;
    private TextView mTitle;

    private ViewHolder(View view) {
        super(view);
        mImage = view.findViewById(R.id.image);
        mTitle = view.findViewById(R.id.title);
    }

    void bindView() {
        ColorDrawable[] shotLoadingPlaceholders = new ColorDrawable[]{new ColorDrawable(ContextCompat.getColor(itemView.getContext(), R.color.background_light))};
        Hit hit = mHitList.get(getAdapterPosition());
        mTitle.setText(hit.getUser());
        Picasso
                .with(mImage.getContext())
                .load(hit.getWebformatURL())
                .placeholder(shotLoadingPlaceholders[0])
                .resize(hit.getImageWidth(), hit.getImageHeight())
                .priority(Picasso.Priority.HIGH)
                .onlyScaleDown()
                .into(mImage);
    }
}

XML

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="4dp">

    <ImageView
        android:id="@+id/image"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:adjustViewBounds="true" />

    <TextView
        android:id="@+id/title"
        android:layout_width="match_parent"
        android:layout_height="48dp"
        android:layout_below="@+id/image"
        android:background="@color/background_light"
        android:fontFamily="sans-serif-medium"
        android:gravity="center_vertical"
        android:maxLines="1"
        android:paddingLeft="16dp"
        android:paddingRight="16dp"
        android:textColor="@color/white_light"
        android:textSize="13sp" />
</RelativeLayout>

你可以像这样设置 bindView 上 ImageView 的 layoutParams 的宽度和高度 Hit class。

RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(hit.getImageWidth(), hit.getImageHeight());
mImage.setLayoutParams(layoutParams);

问候。

通过 width/height 计算图像的纵横比并将 ImageView 包裹在这样的东西中:

public class RelativeSizeLayout extends FrameLayout {
    private float aspectRatio = 1.77f;

    public RelativeSizeLayout(Context context) {
        this(context,null);
    }

    public RelativeSizeLayout(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public RelativeSizeLayout(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    public boolean shouldDelayChildPressedState() {
        return false;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        final int width = MeasureSpec.getSize(widthMeasureSpec);
        heightMeasureSpec = MeasureSpec.makeMeasureSpec((int) (width / aspectRatio), MeasureSpec.EXACTLY);
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    public void setAspectRatio(float ratio) {
        aspectRatio = ratio;
    }
}