Öğeleri genişletme / daraltma


145

Daha fazla bilgi göstermek için recyclerView öğemi genişletmek / daraltmak istiyorum. Aynı etki SlideExpandableListView elde etmek istiyorum .

Temelde benim görüşüme göre görünür olmayan bir görünüme sahibim ve görünürlüğü yalnızca GÖRÜNÜR / GONE olarak ayarlamak yerine düzgün bir genişletme / daraltma animasyonu yapmak istiyorum. Sadece bir seferde genişletilecek bir öğeye ihtiyacım var ve öğenin seçildiğini göstermek için bazı yüksekliklere sahip olmak güzel olurdu.

Bu, yeni Android son çağrı geçmişi listesinin aynı etkisidir. "GERİ ÇAĞIR" ve "AYRINTILAR" seçenekleri yalnızca bir öğe seçildiğinde görülebilir.

Genişletilebilir öğeleri görüntüleme


Ben ilgili bir sorum var. Saat uygulamasında, alarm ayarı etkinliği benzer bir özelliğe sahiptir. Aynı şekilde mi yapılıyor?
user2731584

Hey çözümü buldun mu? Ben de benim app için aynı çözümü arıyorum.
Arpit Patel

Herhangi bir çözüm buldunuz mu?
Armin Ghoreishi

1
Google I / O 2016'ya göre bunu yapmanın önerilen yolunu güncelledim. Cevabımı görün stackoverflow.com/questions/27203817/…
Heisenberg

cevabımı buradan basit ve havalı bir çözüm kontrol edin stackoverflow.com/a/48092441/5962715
Kiran Benny Joseph

Yanıtlar:


192

Lütfen bu efekt için herhangi bir kitaplık kullanmayın, bunun yerine Google I / O'ya göre önerilen şekilde kullanın. RecyclerView öğenizin onBindViewHolder yönteminde şunları yapın :

final boolean isExpanded = position==mExpandedPosition;
holder.details.setVisibility(isExpanded?View.VISIBLE:View.GONE);
holder.itemView.setActivated(isExpanded);
holder.itemView.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        mExpandedPosition = isExpanded ? -1:position;
        TransitionManager.beginDelayedTransition(recyclerView);
        notifyDataSetChanged();
    }
});
  • Nerede ayrıntıları dokunma gösterilecektir benim görünümüdür (sizin durumunuzda arama ayrıntılarının. Visibility.GONE Standart).
  • mExpandedPosition , -1 olarak başlatılmış bir int değişkenidir

İstediğiniz harika efektler için bunları list_item özellikleriniz olarak kullanın:

android:background="@drawable/comment_background"
android:stateListAnimator="@animator/comment_selection"

comment_background:

<selector
xmlns:android="http://schemas.android.com/apk/res/android"
android:constantSize="true"
android:enterFadeDuration="@android:integer/config_shortAnimTime"
android:exitFadeDuration="@android:integer/config_shortAnimTime">

<item android:state_activated="true" android:drawable="@color/selected_comment_background" />
<item android:drawable="@color/comment_background" />
</selector>

ve comment_selection:

<selector xmlns:android="http://schemas.android.com/apk/res/android">

<item android:state_activated="true">
    <objectAnimator
        android:propertyName="translationZ"
        android:valueTo="@dimen/z_card"
        android:duration="2000"
        android:interpolator="@android:interpolator/fast_out_slow_in" />
</item>

<item>
    <objectAnimator
        android:propertyName="translationZ"
        android:valueTo="0dp"
        android:duration="2000"
        android:interpolator="@android:interpolator/fast_out_slow_in" />
</item>
</selector>

22
Bu kodu kullanırken, genişletme animasyonu garip görünüyor. Her zaman en üstteki öğe kaybolur ve her şey bir pozisyon yukarı kayar. Hiç benzer bir şey yaşadın mı?
chris-pollux

6
Animasyonu yapmaya çalışıyorum ama bunu adaptöre uyguluyorum, ancak TransitionManager.beginDelayedTransition(recyclerView);geri dönüşümcü görünümü referansından nefret edemezsem bunun çözümü ne olurdu .
Martín Serrano

2
@Ranveer Bu biraz işe yarıyor. İki oldukça benzer recyclerViews var, ama sadece biri için doğru çalışıyor. Neden olduğu hakkında bir fikrim yok. @ MartínDaniel recyclerViewAdaptör için yapıcıda bir parametre olarak geçmeniz gerekiyor
chris-pollux

26
Bu korkunç bir yaklaşım. Google I / O'da önerildiğine inanamıyorum. Plaid projesini inceledikten ve ondan gerekli tüm geçici çözümleri uyguladıktan sonra bile, animasyon RecyclerView'de bazı önemli aksaklıklara neden olur, örneğin ilk / son görünür öğe erken kaybolur. Ayrıca animasyon çalışırken kaydırma, her şeyi kötü bir şekilde karıştırır. Genel olarak, bu yaklaşımın neden olduğu tüm sorunların düzeltilmesinin "sadece bir satır koy ve her şey işe yarayacak" olarak adlandırılabileceğini sanmıyorum.
Vitali Olshevski

6
2019'da bu sorun için daha taze ve kolay bir yol var mı?
Ponomarenko Oleh

76

Bunun için sadece karmaşık olmayan basit çizgilere ihtiyaç vardı

onBindViewHolder yönteminizde aşağıdaki kodu ekleyin

final boolean isExpanded = position==mExpandedPosition;
holder.details.setVisibility(isExpanded?View.VISIBLE:View.GONE);
holder.itemView.setActivated(isExpanded);
holder.itemView.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        mExpandedPosition = isExpanded ? -1:position;
        notifyItemChanged(position);
    }
});

mExpandedPosition , -1 olarak başlatılan bir int global değişkendir

Sadece bir öğenin genişletilmesini ve diğerlerinin daraltılmasını isteyenler için. Bunu kullan

önce previousExpandedPosition = -1 ile genel bir değişken bildir

sonra

    final boolean isExpanded = position==mExpandedPosition;
    holder.details.setVisibility(isExpanded?View.VISIBLE:View.GONE);
    holder.itemView.setActivated(isExpanded);

    if (isExpanded)
       previousExpandedPosition = position;

    holder.itemView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            mExpandedPosition = isExpanded ? -1:position;
            notifyItemChanged(previousExpandedPosition);
            notifyItemChanged(position);
        }
    });

Bitti !!!. Basit ve alçakgönüllü .. :)


harika bir çözüm. Ayrıca OnClickListeneronCreateViewHolderonBindViewHolder
Y

1
Çok iyi çalışıyor, zamanla RecyclerViewişi yapmasına izin veren iyi bir çözüm vardı , yani, LayoutManagerdüzenleri yönetmezse , aksi takdirde ne var! Bu çözüm, daha az koda sahip olduğundan, RecyclerViewişleri halletmesine ve daha iyi çalışmasına izin verdiği için en iyi oy alan çözümden daha iyidir!
Mark Keen

1
"ayrıntılar" görünümünün nasıl ekleneceğini tam olarak anlamadı. Her tutucu için statik olmalı mı? Her liste öğesi için farklı görünümler eklemem gerekirse ne olur?
BekaBot

@BekaBot çöken eşya sırasında gizlemek istediğiniz manzara
Kiran Benny Joseph

@KiranBennyJoseph evet, anlıyorum. Bu durumda görünüm tüm öğeler için aynı mı olmalıdır? Farklı öğeler için farklı görünümler istersem ne olur?
BekaBot

72

Bunun en iyi yaklaşım olduğunu söylememek, ama benim için işe yarıyor gibi görünüyor.

Kodun tamamını şu adreste bulabilirsiniz: https://github.com/dbleicher/recyclerview-grid-quickreturn

Öncelikle, genişletilmiş alanı hücre / öğe düzeninize ekleyin ve çevreleyen hücre düzenini animateLayoutChanges = "true" yapın. Bu, genişletme / daraltma işlemlerinin animasyonlu olmasını sağlar:

<LinearLayout
    android:id="@+id/llCardBack"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:background="@android:color/white"
    android:animateLayoutChanges="true"
    android:padding="4dp"
    android:orientation="vertical">

    <TextView
        android:id="@+id/tvTitle"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center|fill_horizontal"
        android:padding="10dp"
        android:gravity="center"
        android:background="@android:color/holo_green_dark"
        android:text="This is a long title to show wrapping of text in the view."
        android:textColor="@android:color/white"
        android:textSize="16sp" />

    <TextView
        android:id="@+id/tvSubTitle"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center|fill_horizontal"
        android:background="@android:color/holo_purple"
        android:padding="6dp"
        android:text="My subtitle..."
        android:textColor="@android:color/white"
        android:textSize="12sp" />

    <LinearLayout
        android:id="@+id/llExpandArea"
        android:visibility="gone"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:orientation="horizontal">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="6dp"
            android:text="Item One" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="6dp"
            android:text="Item Two" />

    </LinearLayout>
</LinearLayout>

Ardından, RV Adapter sınıfınızın View.OnClickListener uygulamasını gerçekleştirmesini sağlayın, böylece tıklanan öğeye göre hareket edebilirsiniz. Genişletilmiş görünümün konumunu tutmak için bir int alanı ekleyin ve bunu negatif bir değere başlatın:

private int expandedPosition = -1;

Son olarak, ViewHolder, onBindViewHolder () yöntemlerinizi uygulayın ve onClick () yöntemini geçersiz kılın. Konumu "expandedPosition" değerine eşitse, onBindViewHolder'daki görünümü genişletir ve yoksa gizlersiniz. OnClick dinleyicisinde expandedPosition değerini ayarlarsınız:

@Override
public void onBindViewHolder(RVAdapter.ViewHolder holder, int position) {

    int colorIndex = randy.nextInt(bgColors.length);
    holder.tvTitle.setText(mDataset.get(position));
    holder.tvTitle.setBackgroundColor(bgColors[colorIndex]);
    holder.tvSubTitle.setBackgroundColor(sbgColors[colorIndex]);

    if (position == expandedPosition) {
        holder.llExpandArea.setVisibility(View.VISIBLE);
    } else {
        holder.llExpandArea.setVisibility(View.GONE);
    }
}

@Override
public void onClick(View view) {
    ViewHolder holder = (ViewHolder) view.getTag();
    String theString = mDataset.get(holder.getPosition());

    // Check for an expanded view, collapse if you find one
    if (expandedPosition >= 0) {
        int prev = expandedPosition;
        notifyItemChanged(prev);
    }
    // Set the current position to "expanded"
    expandedPosition = holder.getPosition();
    notifyItemChanged(expandedPosition);

    Toast.makeText(mContext, "Clicked: "+theString, Toast.LENGTH_SHORT).show();
}

/**
 * Create a ViewHolder to represent your cell layout
 * and data element structure
 */
public static class ViewHolder extends RecyclerView.ViewHolder {
    TextView tvTitle;
    TextView tvSubTitle;
    LinearLayout llExpandArea;

    public ViewHolder(View itemView) {
        super(itemView);

        tvTitle = (TextView) itemView.findViewById(R.id.tvTitle);
        tvSubTitle = (TextView) itemView.findViewById(R.id.tvSubTitle);
        llExpandArea = (LinearLayout) itemView.findViewById(R.id.llExpandArea);
    }
}

Bu, düzen değişikliği için sistem varsayılan animasyonunu kullanarak bir kerede yalnızca bir öğe genişletmelidir. En azından benim için çalışıyor. Umarım yardımcı olur.


Yalnızca bir öğeyi seçili tutmayı biliyorum. Bu öğedeki animasyonu nasıl yapacağımı gerçekten bilmiyorum. Varsayılan sistem animasyonuyla genişletme / daraltma animasyonu çok düzgün görünmüyor.
14'te

1
Aşağıdakileri henüz denemedim, ama işe yarayacak gibi görünüyor. Cevabı kontrol edin: stackoverflow.com/a/26443762/2259418
MojoTosh

2
@ user2731584 - Sanmıyorum. Kaynaklarına (inandığım) baktığımızda, Lollipop saatinin alarm listesini görüntülemek için bir ListView kullandığı anlaşılıyor. Düzen: android.googlesource.com/platform/packages/apps/DeskClock/+/… Bu listedeki genişlet / daralt öğelerine animasyon uygulamak için özel kodları var gibi görünüyor. Aşağıdaki kaynağa bakın: android.googlesource.com/platform/packages/apps/DeskClock/+/…
MojoTosh

1
@MojoTosh haklısın. ListView kullanıyorlar ve kod kullanarak animasyon yapıyorlar. expandAlarmişlevAlarmClockFragment.javadosyalarındaki genişletme bölümünü yürütür.
user2731584

4
Hangisini onClick()geçersiz kılmalıyım? Hiçbir var onClickAdaptör.
Vicky Leong

15

Gradle destekli kullanımı çok kolay bir kütüphane var: https://github.com/cachapa/ExpandableLayout .

Doğrudan kütüphane belgelerinden:

<net.cachapa.expandablelayout.ExpandableLinearLayout
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:el_duration="1000"
    app:el_expanded="true">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Click here to toggle expansion" />

    <TextView
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:text="Fixed height"
        app:layout_expandable="true" />

 </net.cachapa.expandablelayout.ExpandableLinearLayout>

İşaretledikten sonra genişletilebilir görünümleri, sadece kabın üzerindeki bu yöntemlerden herhangi birini çağırır: expand(), collapse()veyatoggle()


Bu hala bunu yapmanın en iyi yolu mu? Yazdıklarını takip etmeye çalışıyorum. Tıklandığında bir grafik göstermek için genişletmek istediğim bazı geri dönüşüm görünümlerim var
sourlemonaid

10

Orijinal sorunun gönderilmesinden bu yana uzun zaman geçtiğini biliyorum. Ama bence yavaş yavaş olanlar için @ Heisenberg'in cevabının açıklaması biraz yardımcı olacaktır.

Bağdaştırıcı sınıfındaki iki değişkeni şu şekilde bildir:

private int mExpandedPosition= -1;
private RecyclerView recyclerView = null;

Sonra onBindViewHolder orijinal yanıt verildiği gibi.

      // This line checks if the item displayed on screen 
      // was expanded or not (Remembering the fact that Recycler View )
      // reuses views so onBindViewHolder will be called for all
      // items visible on screen.
    final boolean isExpanded = position==mExpandedPosition;

        //This line hides or shows the layout in question
        holder.details.setVisibility(isExpanded?View.VISIBLE:View.GONE);

        // I do not know what the heck this is :)
        holder.itemView.setActivated(isExpanded);

        // Click event for each item (itemView is an in-built variable of holder class)
        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

 // if the clicked item is already expaned then return -1 
//else return the position (this works with notifyDatasetchanged )
                mExpandedPosition = isExpanded ? -1:position;
    // fancy animations can skip if like
                TransitionManager.beginDelayedTransition(recyclerView);
    //This will call the onBindViewHolder for all the itemViews on Screen
                notifyDataSetChanged();
            }
        });

Ve son olarak bağdaştırıcı geçersiz kılmasında recyclerView nesnesini almak için

@Override
public void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView) {
    super.onAttachedToRecyclerView(recyclerView);

    this.recyclerView = recyclerView;
}

Bu yardımcı olur umarım.


3
Harika ve basit bir çözüm. Küçük iyileştirme, sihirli sayı -1 yerine RecyclerView.NO_POSITION kullanın.
Casper Bang

8

Üçüncü taraf kitaplıklarını kullanmaya gerek yoktur. Bir küçük çimdik gösterilmiştir yöntemde Google I / O 2016 Bu konuyla ilgili ve Heisenberg, hile yok.

Yana notifyDataSetChanged() tam yeniden çizimlerinRecyclerView , notifyDataItemChanged()biz konumunu ve var çünkü daha iyi bir seçenek (iyi) olan ViewHolderbizim emrinde ve notifyDataItemChanged()sadece belirli yeniden çizer ViewHolderbelirli bir pozisyonda .

Ancak sorun, ViewHoldertıklamanın erken kaybolması ve ortaya çıkmasının bile ortadan kalkmamasıdır.notifyDataItemChanged() kullanılsa .

Aşağıdaki kod gelmez başvurmak notifyDataSetChanged()veya notifyDataItemChanged()her ViewHolder bir olan bir RecyclerView kullanıldığında API 23 ve bir cazibe gibi eserler üzerinde test edilir CardView's kök eleman olarak:

holder.itemView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            final boolean visibility = holder.details.getVisibility()==View.VISIBLE;

            if (!visibility)
            {
                holder.itemView.setActivated(true);
                holder.details.setVisibility(View.VISIBLE);
                if (prev_expanded!=-1 && prev_expanded!=position)
                {
                    recycler.findViewHolderForLayoutPosition(prev_expanded).itemView.setActivated(false);
                    recycler.findViewHolderForLayoutPosition(prev_expanded).itemView.findViewById(R.id.cpl_details).setVisibility(View.GONE);
                }
                prev_expanded = position;
            }
            else
            {
                holder.itemView.setActivated(false);
                holder.details.setVisibility(View.GONE);
            }
            TransitionManager.beginDelayedTransition(recycler);              
        }
});

prev_position -1 olarak başlatılmış bir global tamsayıdır. details, genişletildiğinde gösterilen ve daraltıldığında gizlenen tam görünümdür.

As kök öğesi, söz konusu ViewHolderbir olduğunu CardViewile foregroundve stateListAnimatorbu konuda Heisenberg tarafından tam olarak tanımlanır söyledi bağlıyor.

GÜNCELLEME: Yukarıdaki gösteri, biri genişletilmişse, daha önce genişletilmiş öğeyi daraltır. Bu davranışı değiştirmek ve genişletilmiş bir öğeyi başka bir öğe genişletilse bile olduğu gibi tutmak için aşağıdaki koda ihtiyacınız olacaktır.

if (row.details.getVisibility()!=View.VISIBLE)
    {
        row.details.setVisibility(View.VISIBLE);
        row.root.setActivated(true);
        row.details.animate().alpha(1).setStartDelay(500);
    }
    else
    {
        row.root.setActivated(false);
        row.details.setVisibility(View.GONE);
        row.details.setAlpha(0);
    }
    TransitionManager.beginDelayedTransition(recycler);

GÜNCELLEME: Listedeki son öğeleri genişletirken, genişletilmiş bölüm ekranın altına ineceğinden tam görünüme getirilemeyebilir. Ekrandaki tüm öğeyi almak için aşağıdaki kodu kullanın.

LinearLayoutManager manager = (LinearLayoutManager) recycler.getLayoutManager();
    int distance;
    View first = recycler.getChildAt(0);
    int height = first.getHeight();
    int current = recycler.getChildAdapterPosition(first);
    int p = Math.abs(position - current);
    if (p > 5) distance = (p - (p - 5)) * height;
    else       distance = p * height;
    manager.scrollToPositionWithOffset(position, distance);

ÖNEMLİ: Yukarıdaki gösterilerin çalışması için, kodlarında RecyclerView ve LayoutManager'ın (daha sonra esneklik için daha sonra) bir örneği tutulmalıdır.


Teşekkürler bu çözüm benim için çalışıyor. Kullanmaktan kaçınmaya çalışıyorum notifyItemChangedçünkü ImageViewbir url'den yüklenen bir resim var. notifyItemChangedResmimi yeniden yükle garip görünüyor
Tam Huynh

Onu çivilenen çizgi TransitionManager.beginDelayedTransition(recycler);, büyük bulmak. Ancak, bu yöntemi kullanarak, birkaç satırı sırayla spam tıklatırsam, sonunda dahili bir çökmeyi tetiklediğini öğrendim The specified child already has a parent. You must call removeView() on the child's parent first. Bunun geri dönüşümcü görünüm sınırları üzerinde geri dönüşüm görünümünden kaynaklandığını hayal ediyorum, ama emin değilim. Aynı sorunu olan var mı?
Roger Oba

Bu hala bunu yapmanın en iyi yolu mu? Yazdıklarını takip etmeye çalışıyorum. Tıklandığında bir grafik göstermek için genişletmek istiyorum bazı geri dönüşüm görünümleri var. Tam olarak ne yapacağımı
anlamakta zorlanıyorum

Herkes bu uygulamanın tam bir örneği var mı? Yani bir çalışma kodu örneği. Lütfen yardım et. Bunu nasıl yapacağımı anlayamıyorum?
Munazza

7

Bir ikamet eden genişletilebilir / katlanabilir öğeleri uygulanması tavsiye edilen şekilde kullandıktan sonra RecyclerViewüzerine RecyclerView / çöküşü öğeleri genişletmek tarafından cevap Heisenberg , ben her bazı göze çarpan eserler gördüm RecyclerViewçağırarak yenilenir TransitionManager.beginDelayedTransition(ViewGroup)sonradan venotifyDatasetChanged() .

Orijinal cevabı:

final boolean isExpanded = position==mExpandedPosition;
holder.details.setVisibility(isExpanded?View.VISIBLE:View.GONE);
holder.itemView.setActivated(isExpanded);
holder.itemView.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        mExpandedPosition = isExpanded ? -1 : position;
        TransitionManager.beginDelayedTransition(recyclerView);
        notifyDataSetChanged();
    }
});

Değiştirilmiş:

final boolean isExpanded = position == mExpandedPosition;
holder.details.setVisibility(isExpanded ? View.VISIBLE : View.GONE);
holder.view.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        if (mExpandedHolder != null) {
            mExpandedHolder.details.setVisibility(View.GONE);
            notifyItemChanged(mExpandedPosition);
        }
        mExpandedPosition = isExpanded ? -1 : holder.getAdapterPosition();
        mExpandedHolder = isExpanded ? null : holder;
        notifyItemChanged(holder.getAdapterPosition());
    }
}
  • ayrıntılar , öğeyi genişletme / daraltma sırasında göstermek / gizlemek istediğiniz görünümdür
  • mExpandedPosition , intgenişletilmiş öğenin kaydını tutan bir
  • mExpandedHolder , ViewHolderöğenin daraltılması sırasında kullanılır

Yöntem Bildirim TransitionManager.beginDelayedTransition(ViewGroup)ve notifyDataSetChanged()değiştirilirnotifyItemChanged(int) belirli öğeyi ve bazı küçük düzeltmeleri hedeflemek .

Değişiklikten sonra, önceki istenmeyen etkiler giderilmelidir. Ancak, bu mükemmel bir çözüm olmayabilir. Sadece istediğimi yaptı, göz kapaklarını yok etti.

::DÜZENLE::

Açıklığa kavuşturmak için, hem mExpandedPositionve mExpandedHolderküreseldir.


Lütfen mExpandedHolder'ın nasıl ve nerede beyan edildiğini ve kullanıldığını açıklayın?
Werner

1
@Werner Cevabı nerede bildirildiğini göstermek için düzenledim. Kullanım, snippet'in kendisi ve amacının içindedir. Çöken, genişletilmiş öğeye animasyon uygulamak için kullanılır.
Chan Teck Wei

Bu yaklaşımı animasyonlar açısından en çok seviyorum, ama öğeyi tıklarken bu küçük "solmaya" sahibim. Bunun yanı sıra ya da farklı bir şekilde koymak, bu notifyItemChanged () kullanmak nedeniyle mi? drive.google.com/file/d/1GaU1fcjHEfSErYF50otQGLGsIWkSyQSe/…
kazume 15:18 '

Evet. Tahmin ettiğiniz gibi, buna neden olur notifyItemChanged(). Öğe yüksekliğini manuel olarak canlandırabilir ve değiştirebilir ve buna görünüm ekleyebilirsiniz.
Chan Teck Wei

@ChanTeckWei: Çözümünüz iyi çalışıyor ancak geri dönüşüm görünümü öğesi satırını daralttığımda veya genişlettiğimde satır resmi titriyor ... Bunun için herhangi bir çözüm var mı?
Pragya Mendiratta

3

OnClick dinleyicisini ViewHolder sınıfına ayarladıktan sonra aşağıdakileri yapın:

@Override
    public void onClick(View v) {
        final int originalHeight = yourLinearLayout.getHeight();
        animationDown(YourLinearLayout, originalHeight);//here put the name of you layout that have the options to expand.
    }

    //Animation for devices with kitkat and below
    public void animationDown(LinearLayout billChoices, int originalHeight){

        // Declare a ValueAnimator object
        ValueAnimator valueAnimator;
        if (!billChoices.isShown()) {
            billChoices.setVisibility(View.VISIBLE);
            billChoices.setEnabled(true);
            valueAnimator = ValueAnimator.ofInt(0, originalHeight+originalHeight); // These values in this method can be changed to expand however much you like
        } else {
            valueAnimator = ValueAnimator.ofInt(originalHeight+originalHeight, 0);

            Animation a = new AlphaAnimation(1.00f, 0.00f); // Fade out

            a.setDuration(200);
            // Set a listener to the animation and configure onAnimationEnd
            a.setAnimationListener(new Animation.AnimationListener() {
                @Override
                public void onAnimationStart(Animation animation) {

                }

                @Override
                public void onAnimationEnd(Animation animation) {
                    billChoices.setVisibility(View.INVISIBLE);
                    billChoices.setEnabled(false);
                }

                @Override
                public void onAnimationRepeat(Animation animation) {

                }
            });
            // Set the animation on the custom view
            billChoices.startAnimation(a);
        }
        valueAnimator.setDuration(200);
        valueAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            public void onAnimationUpdate(ValueAnimator animation) {
                Integer value = (Integer) animation.getAnimatedValue();
                billChoices.getLayoutParams().height = value.intValue();
                billChoices.requestLayout();
            }
        });


        valueAnimator.start();
    }
}

Bunun yardımcı olması gerektiğini düşünüyorum, bu google'ı son çağrı görünümünde uyguladım ve yapıyor.


3

Böyle bir genişletme / daraltma animasyonu sadece 2 satır kod ile elde edilmesi çok kolay olmasına rağmen, henüz kısa bir cevap olmadığına şaşırdım:

(recycler.itemAnimator as SimpleItemAnimator).supportsChangeAnimations = false // called once

birlikte

notifyItemChanged(position) // in adapter, whenever a child view in item's recycler gets hidden/shown

Bu yüzden benim için, aşağıdaki bağlantıdaki açıklamalar gerçekten yararlıydı: https://medium.com/@nikola.jakshic/how-to-expand-collapse-items-in-recyclerview-49a648a403a6


1
//Global Variable

private int selectedPosition = -1;

 @Override
    public void onBindViewHolder(final CustomViewHolder customViewHolder, final int i) {

        final int position = i;
        final GetProductCatalouge.details feedItem = this.postBeanses.get(i);
        customViewHolder.lly_main.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                selectedPosition = i;
                notifyDataSetChanged();
            }
        });
        if (selectedPosition == i) {

          if (customViewHolder.lly_hsn_code.getVisibility() == View.VISIBLE) {

            customViewHolder.lly_hsn_code.setVisibility(View.GONE);
            customViewHolder.lly_sole.setVisibility(View.GONE);
            customViewHolder.lly_sole_material.setVisibility(View.GONE);

        } else {

            customViewHolder.lly_hsn_code.setVisibility(View.VISIBLE);
            customViewHolder.lly_sole.setVisibility(View.VISIBLE);
            customViewHolder.lly_sole_material.setVisibility(View.VISIBLE);
        }


        } else {
            customViewHolder.lly_hsn_code.setVisibility(View.GONE);
            customViewHolder.lly_sole.setVisibility(View.GONE);
            customViewHolder.lly_sole_material.setVisibility(View.GONE);
        }
}

resim açıklamasını buraya girin


0

Bilgisayarınızda iki görünüm türü kullanın RVAdapter. Biri genişletilmiş düzen için, diğeri daraltılmış için. Ve sihirli ayarı ile olur android:animateLayoutChanges="true"için RecyclerView etkisi de 0:42 bu kullanarak elde Checkout bu video


zihin daha iyi açıklamak? Çalışıyor gibi görünmüyorum
sourlemonaid

@sourlemonaid temel olarak liste için stackoverflow.com/a/26245463/3731795 adresinde açıklandığı gibi birden çok görünüm türü oluşturursunuz ... Öğenin genişletildiği ve öğelerin geri kalanının o sırada daraltıldığı bir dizinin kaydını tutarsınız . Şimdi (current_item_index == expanded_item_index) {dönüş VIEW_TYPE_EXPANDED} başka {dönüş VIEW_TYPE_COLLAPSED}
penduDev
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.