【问题标题】:How to set a dynamically sized placeholder in a recyclerview with gridlayout?如何使用gridlayout在recyclerview中设置动态大小的占位符?
【发布时间】:2016-09-09 11:57:27
【问题描述】:

我正在编写一段代码,允许用户从 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 将计算有多少可用空间并为每个项目分配一个宽度值,因此我分配的数量将适合,这就是为什么我不能为占位符使用预定义的可绘制对象的原因,因为我可以永远不要确定我的 240x240 drawable 是否适合所有设备。


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

【问题讨论】:

    标签: android android-recyclerview picasso gridlayoutmanager


    【解决方案1】:

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

    像这样

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

    【讨论】:

    • 这不是我想要的。我已经提到我正在使用 GridLayoutManager。我想要的是适配器中每个项目的宽度,所以我可以生成一个占位符位图
    【解决方案2】:

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

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

    为了实现这一点,我将 ImageView 子类化,并在 onMeasure 方法中,将宽度值分配给视图的高度参数。

    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,它会将每个元素拉伸得异常长,所以我们需要添加一个属性来确定它的优势侧,因为我很懒,所以我将简单地添加一个默认值-参数。

    因为将其简单地定义为视图参数会很好,所以我们在 attr 文件中实现了样式声明

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-09-12
      • 2012-07-24
      • 1970-01-01
      • 2013-03-01
      • 2015-02-27
      • 1970-01-01
      • 1970-01-01
      • 2011-01-15
      相关资源
      最近更新 更多