如何使用gridlayout在recyclerview中设置动态大小的占位符?

时间:2016-09-09 11:57:27

标签: android android-recyclerview picasso gridlayoutmanager

我正在编写一段代码,允许用户从Facebook中选择一张照片,并将其作为个人资料图片在我们的应用中使用。逻辑已经完成,但布局给我带来了一些麻烦。

我的图像布局

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_gravity="center"
    android:layout_margin="5dp"
    >
    <ImageView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/imageView"
        />
</android.support.v7.widget.CardView>

我正在使用RecyclerView,它将相册的每个图像加载到2列网格中(由GridLayoutManager提供)。这是使用毕加索完成的:

mImageLoader.load(image.getUrl()).resize(480, 480).centerCrop().into(holder.imageView);

因为加载包含数百张图片的相册需要一段时间,我想显示一个占位符。这可以使用Picasso中的.placeholder运算符来实现。

我的问题是我不知道我的ViewHolders有多高和多宽。

GridLayoutManager将计算可用空间的大小并为每个项目分配一个宽度值,因此我指定的数量将适合,这就是为什么我不能使用预定义的drawable为我的占位符,因为我可以永远不要确定我的240x240 drawable适用于每台设备。

所以,我的问题是:如何在我的recyclerview中获取每张卡的宽度,所以我将在运行时创建的位图应用为占位符?

2 个答案:

答案 0 :(得分:0)

您需要动态添加布局管理器,您必须在运行时通过网格布局传递列数。

喜欢这个

RecyclerView.LayoutManager layoutManager = new GridLayoutManager(getApplicationContext(),2); recyclerView.setLayoutManager(的layoutManager);

答案 1 :(得分:0)

虽然这不是问题的答案,但我真正需要的是一个始终是方形的ImageView。这样,我可以简单地将任何我想要的东西加载到那个东西中并调整它以适合使用Picasso。

mImageLoader.load(image.getUrl()).fit().into(holder.imageView);

为了实现这一点,我将ImageView子类化,并在onMeasure方法中,将width-value赋给View的height-parameter。

public class SquareImageView extends ImageView {

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int edgeLen = getMeasuredWidth();
        setMeasuredDimension(edgeLen, edgeLen);
    }
}

问题是,如果我使用水平滚动Grid-Layout,它会将每个元素拉伸异常很长,所以我们需要添加一个属性来确定它的主导方面,因为我很懒,我只需添加一个默认值-parameter。

因为将它定义为view-parameter会很好,我们在attr文件中实现了stylable-declaration

<declare-styleable name="SquareImageView">
    <attr name="dominantSide" format="enum">
        <enum name="width" value="0"/>
        <enum name="height" value="1"/>
    </attr>
</declare-styleable>

现在,我们可以简单地将它添加到SquareImageView

<com.example.android.ui.custom.SquareImageView
    android:layout_width="match_parent"
    android:layout_height="0dp"
    app:dominantSide="width" />

因为我们宣称我们的主导方是width,所以我们可以做任何我们想要的高度。您可以将其指定为0dp,match_parent,3.14159dp或其他任何您想要的。你需要分配一些东西,否则IntelliJ会骂你。

在我们的自定义类中,我们只需获取参数dominantSide

public class SquareImageView extends ImageView {

    private int dominantSide;

    public SquareImageView(Context context, AttributeSet attrs) {
        super(context, attrs);

        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SquareImageView);
        dominantSide = a.getInt(R.styleable.SquareImageView_dominantSide, 0);
        a.recycle();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int edgeLen = dominantSide == 0 ? getMeasuredWidth() : getMeasuredHeight();
        setMeasuredDimension(edgeLen, edgeLen);
    }
}