StaggeredLayout с FlexboxLayoutManager - PullRequest
0 голосов
/ 11 мая 2018

У меня есть какой-либо способ реализовать разнесенный макет с помощью библиотеки Flexbox от Google, подобной этой

Layout implemented using StaggeredLayoutManager

Вышеприведенный макет создан с использованием StaggeredLayoutManger также поддерживает соотношение сторон изображения

Я пробовал код:

recyclerView.apply {
        layoutManager = FlexboxLayoutManager(context).apply {
            flexWrap = FlexWrap.WRAP
            justifyContent = JustifyContent.CENTER
        }
        adapter = mAdapter
    }

Но это делает макет с одним столбцом и соотношение сторон также не поддерживается (Учитывая, что изображения имеют большой размер).

Ответы [ 3 ]

0 голосов
/ 19 июля 2018

Кажется, вы хотите, чтобы ваш дизайн, как Pinterest.Если вы хотите плавного взаимодействия с пользователем в соответствии с изображением выше, то вам нужно иметь высоту / ширину изображения перед загрузкой изображения, чтобы вы могли установить правильное соотношение сторон.Pinterest и другие делают то же самое.

Для этого вам нужно использовать GridLayoutManager, а с помощью ConstrainLayout вы можете легко установить соотношение сторон изображения следующим образом.

private val set = ConstraintSet()

override fun onBindViewHolder(holder: ViewHolder, position: Int) {
    val poster = mMoviePosters[position]

    Glide.with(holder.itemView.context)
                .setDefaultRequestOptions(requestOptions)
                .load(poster.imageUrl)
                .into(holder.mImgPoster)

    val ratio =String.format("%d:%d", poster.width,poster.height)
    set.clone(holder.mConstraintLayout)
    set.setDimensionRatio(holder.mImgPoster.id, ratio)
    set.applyTo(holder.mConstraintLayout)
}

У меня естьуже написал подробный пост в блоге об этом.Если вы хотите узнать больше, прочитайте Соотношение сторон в Staggered LayoutManager с использованием Constraint Layout

0 голосов
/ 20 июля 2018

enter image description here

Итак, это то, что я сделал в одном проекте, используйте FlexBoxLayout, в моем случае некоторые изображения были очень большими по размеру, поэтому пришлосьсделайте что-нибудь с параллелизмом.

  flexboxLayoutManager = new FlexboxLayoutManager(yourActivity.this);
  flexboxLayoutManager.setFlexWrap(FlexWrap.WRAP);
  flexboxLayoutManager.setAlignItems(AlignItems.STRETCH);
  flexboxLayoutManager.setFlexDirection(FlexDirection.ROW);
  recyclerView.setLayoutManager(flexboxLayoutManager);

Основная логика входит в адаптер , на onBindViewHolder

 Glide.with(context)
         .load(String.format("yourUrlHere")
         .diskCacheStrategy(DiskCacheStrategy.ALL)
         .animate(R.anim.fadein)
         .override(dpToPx(90) ,dpToPx(90)) // here replace with your desired size.
         .centerCrop()
         .listener(new RequestListener<String, GlideDrawable>() {
                    @Override
                    public boolean onException(Exception e, String model, Target<GlideDrawable> target, boolean isFirstResource) {
                        //  holder.loader.setVisibility(View.GONE);
                        return false;
                    }

                    @Override
                    public boolean onResourceReady(GlideDrawable resource, String model, Target<GlideDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) {
                        //  holder.loader.setVisibility(View.GONE);
                        return false;
                    }
                })
         .priority(Priority.IMMEDIATE)
          .into(viewHolder.imageView);

   ViewGroup.LayoutParams lp = viewHolder.imageView.getLayoutParams();
    if (lp instanceof FlexboxLayoutManager.LayoutParams) {
        FlexboxLayoutManager.LayoutParams flexboxLp = (FlexboxLayoutManager.LayoutParams) lp;
        Random random = new Random();
        int val = random.nextInt(5);
        if (val ==0){
            val = 1;
        }
        flexboxLp.setFlexGrow(val);
        flexboxLp.setFlexShrink(1f);

    } 

И вы можете решить свою проблему, используя этот код,как я реализовал сам в одном проекте.Надеюсь, это решит вашу проблему. Счастливое кодирование :)

Примечание: В моем проекте, в зависимости от требований, я использовал flexboxLayoutManager.setFlexDirection(FlexDirection.COLUMN);, поэтому мой макет такой.

0 голосов
/ 16 июля 2018

Использование

flexDirection = FlexDirection.ROW
alignItems = AlignItems.STRETCH

Вместо

justifyContent = JustifyContent.CENTER

Ваш новый код будет похож на

recyclerView.apply {
        layoutManager =FlexboxLayoutManager(context).apply {
            flexWrap = FlexWrap.WRAP
            flexDirection = FlexDirection.ROW
            alignItems = AlignItems.STRETCH
        }
        adapter = mAdapter
    }
...