CardStackView ve Picasso Resim ile Scrollview'da LinearLayout'ta ImageView görünmüyor

Sep 09 2020

Bir Android uygulaması geliştiriyorum.

Kart yığını kitaplığı için "com.yuyakaido.android:card-stack-view:2.3.4" kullanıyorum.

ImageView, CardView'daki ScrollView'da LinearLayout içindedir.

Yapmak istediğim, kart ilk yüklendiğinde aşağıdaki resme göre görüntüyü kart boyutuna sığdırmak.

Ve aşağı kaydırırsanız, aşağıdaki resme göre bazı metinler gösterecektir.

Görüntüyü ImageView'a sığdırmak için Picasso kullanıyorum ama görüntü gösterilmiyor.

Bu, CardStackView'a sahip olan parçadır

override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?,
    savedInstanceState: Bundle?
): View? {
    return inflater.inflate(R.layout.fragment_card_stack, container, false)
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    initCardStackView()
}

private fun initCardStackView() {
    manager = CardStackLayoutManager(context)
    manager.setCanScrollVertical(false)
    manager.setSwipeableMethod(SwipeableMethod.Manual)
    adapter = CardStackAdapter(context, createDummyProfiles())
    cardStackView.layoutManager = manager
    cardStackView.adapter = adapter
    cardStackView.itemAnimator = DefaultItemAnimator()
}

Bu, Fragment düzenidir

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/linearLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    
    <com.yuyakaido.android.cardstackview.CardStackView
        android:id="@+id/cardStackView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:padding="80dp"
        android:clipToPadding="false"/>

</LinearLayout>

Bu CardStackAdapter, burada resmi kırpıp Piccaso ile ImageView'a sığdırıyorum

class CardStackAdapter(private var context: Context?, private var movies: MutableList<Movies>) :
    RecyclerView.Adapter<CardStackAdapter.ViewHolder>() {

    class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {

    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val inflater = LayoutInflater.from(parent.context)
        return ViewHolder(inflater.inflate(R.layout.card_view, parent, false))
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        Picasso.get().load(R.drawable.person3).fit().centerCrop().into(holder.itemView.imageView)
    }

    override fun getItemCount(): Int {
        return movies.size
    }

    fun setItems(items: MutableList<Profile>) {
        this.movies = items
    }
}

Bu, CardStackAdapter'ın viewHolder düzenini oluşturan card_view

<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/cardView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="?attr/selectableItemBackground"
    android:foreground="?attr/selectableItemBackground"
    app:cardBackgroundColor="@android:color/white"
    app:cardCornerRadius="18dp"
    app:cardPreventCornerOverlap="false"
    app:cardUseCompatPadding="true">

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <ImageView
                android:id="@+id/imageView"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="@string/lipsum"/>

        </LinearLayout>

    </ScrollView>

</androidx.cardview.widget.CardView>

Uygulamayı çalıştırdığımda, kartı resimsiz olarak alıyorum, ancak aşağıdaki resimdeki gibi sadece metinler

Kart yüklendiğinde, kart boyutundaki resmi nasıl görüntüleyebilirim?



------------------------- GÜNCELLEME ------------------------ ----

** NOT: Görüntü, yerel çekilemez değil sunucudan alınacaktır. Resimleri sadece test amaçlı olarak yerel çekmecede kullandım.

Görüntünün neden görünmediğinden emin değilim. Ancak imageView'in layoutParams öğesinin yüksekliğini ve genişliğini aşağıdaki koda göre ayarlarsam, görüntü ortaya çıkıyor.

override fun onBindViewHolder(holder: ViewHolder, position: Int) {
    holder.itemView.imageView.layoutParams.height = 1918
    holder.itemView.imageView.layoutParams.width = 970
    Picasso.get().load(R.drawable.person3).fit().centerCrop().into(holder.itemView.imageView)
}

Öyleyse, şimdi soru ImageView'ün yüksekliğini ve genişliğini ScrollView( imageViewebeveyninin ebeveyninin) veya CardView( imageViewebeveyninin ebeveyninin) NOT LinearLayout (ebeveyn) yüksekliğine ve genişliğine eşit olarak ayarlayıp ayarlayamayacağım çünkü LinearLayout'un yüksekliği "wrap_content" olmalıdır.



------------------------- GÜNCELLEME ------------------------ ----

Çözümünüz görüntünün yüksekliğine ve genişliğine bağlı gibi görünüyor, ancak görüntüyü CardView veya ScrollView'a sığdırmam gerekiyor

İşte onBindViewHolder kodum. Picasso'yu kaldırdım.

override fun onBindViewHolder(holder: ViewHolder, position: Int) {
    holder.itemView.imageView.setImageResource(R.drawable.person2)
}

İşte CardView düzenim

<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/cardView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="?attr/selectableItemBackground"
    android:foreground="?attr/selectableItemBackground"
    app:cardCornerRadius="18dp"
    app:cardPreventCornerOverlap="false"
    app:cardUseCompatPadding="true">

    <androidx.core.widget.NestedScrollView
        android:fillViewport="true"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <ImageView
                android:id="@+id/imageView"
                android:src="@drawable/person2"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:adjustViewBounds="true"
                android:scaleType="centerCrop"/>

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="@string/lipsum"/>

        </LinearLayout>

    </androidx.core.widget.NestedScrollView>

</androidx.cardview.widget.CardView>

AVD'mde sahip olduğum şey bu. Görüntü, CardView'ın altını doldurmuyor çünkü yüksekliğine ve genişliğine göre ölçekleniyor.

Yanıtlar

1 ADM Sep 17 2020 at 19:08

Güncellenen sorunuzdan ne anladığımı, Yükseklik'e ImageViewkadar doldurmanız gerekiyor ve kaydırdıktan sonra görünür olacak. Bu biraz zor görünüyor çünkü bir şekilde yüksekliği dinamik olarak ayarlamamız gerekmiyor . Aşağıda bir Çözüm yaptım, bu antrenmanın sizin için olup olmadığını görün. Özel bir Görüntü görünümü oluşturun ve içini kullanın .CardViewtextViewScrollViewmatch_parentScrollView
CardView

class FillImageView : AppCompatImageView {
constructor(context: Context?) : super(context!!) {}
constructor(context: Context?, attrs: AttributeSet?) : super(context!!, attrs) {}
constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(context!!, attrs, defStyleAttr) {}

override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec)
    val parentWidth = MeasureSpec.getSize(widthMeasureSpec)
    setMeasuredDimension(parentWidth, (parent.parent as View).measuredHeight)
}
}

Ve NestedScrolllViewaşağıdakileri CardView içine ekleyin

<androidx.core.widget.NestedScrollView
            android:layout_width="match_parent"
            android:fillViewport="true"
            android:layout_height="match_parent">
        <LinearLayout
                android:layout_width="match_parent"
                android:orientation="vertical"
                android:layout_height="wrap_content">
            <com.ace.myapplication.FillImageView
                    android:layout_width="match_parent"
                    android:src="@drawable/hello"
                    android:adjustViewBounds="true"
                    android:layout_height="match_parent"
                    android:scaleType="centerCrop"/>
            <TextView
                    android:layout_width="match_parent"
                    android:textSize="23sp"
                    android:padding="10dp"
                    android:layout_height="wrap_content"/>
        </LinearLayout>
    </androidx.core.widget.NestedScrollView>

Not - Yükseklik ayarı ile çirkin bir çözüm olabilir (parent.parent as View).measuredHeightama şu anda yapabileceğim tek şey bu. bunun için zarif bir çözüm görmeyi seviyorum. İle test etmedim CardStackView.

Şimdi GüncelleRecyclerView , sorunla birlikte , adaptör ayarlandıktan sonra çizilen öğedir ve o layoutManagerzamandan beri çizilen Öğenin geri çağrısını dinlememiz gerekir . Bunu karmaşık hale getirmeden üstesinden gelmenin bir yolu, cadStackViewyüksekliği imageView olarak ayarlayın . Yalnızca gerekli kodu ekleyerek aşağıdaki koda bakın.

class CardStackAdapter(val stackViewHeight:Int, private var movies: MutableList<Moview>) :
    RecyclerView.Adapter<CardStackAdapter.ViewHolder>() {

   inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        val imageView:ImageView = itemView.findViewById(R.id.imageView)
        init {
            imageView.layoutParams.height= stackViewHeight
        }
    }
}

Şimdi senin parçanda

cardStackView.post {
       initCardStackView()
   }

Ve içindeki dapter oluşumunu initCardStackViewaşağıdaki gibi değiştirin . Ayrıca Bağdaştırıcıya Bağdaştırıcıyı iletmeniz gerekmez, her görünümün kendisine eklenmiş bir bağlamı vardır. Ayrıca FillImageViewbu durumda ImageViewxml düzeninde normal kullanmayın .

// Since you are using android:padding it will be same for all sides
    val cardHeight=cardStackView.height- (2*cardStackView.paddingTop)
    val adapter = CardStackAdapter(cardHeight, createDummyProfiles())
BrunoVieira Sep 16 2020 at 02:46

Yerel bir çizilebilir dosya yüklemek için neden Picasso kullanıyorsunuz? Kaynak çekilebilir dosyanızı ImageView'a uygulayabilirsiniz.

<ImageView
    android:id="@+id/imageView"
    android:layout_width="match_parent"
    android:scaleType="fitCenter"
    android:src="@drawable/person3"
    android:layout_height="wrap_content" />

Bunun yanı sıra, NestedScrollViewbunun yerine kullanmanızı şiddetle tavsiye ederim ScrollViewve sonra lütfen fillViewPortboyunu çocuğun boyuna eşit olacak şekilde uzatmak için (ScrollView özniteliğini) true olarak ayarlayın.


Güncelleme:

Picasso'yu harici bir URL'yi yüklemek için gerçekten kullanmak istiyorsanız, lütfen aşağıdaki yapılandırmayı yapın:

Picasso
    .get()
    .load([url_you_want_to_load])
    .placeholder([placeholder_you_want_to_pre_load])
    .into(imageView)

ve ardından, ImageView'unuzu merkeze sığacak ve en boy oranını koruyacak şekilde yapılandırın:

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