2012-01-08 23 views
29

Bir ExpandableListView öğesinin bir öğesini genişletirken/daraltırken güzel bir yukarı/aşağı efektinin olması mümkün mü?Kaydırılabilirlik efekti ExpandableListView

Evet ise, nasıl?

Şimdiden teşekkürler.

+0

Belki sadece bir ExpandableListView genişletmek etkisinin hızını yavaşlatmak için basit bir yolu yoktur. Bir yolu var mı ??? – thomaus

+1

Bunu nasıl başarmayı düşünen tek kişi ben miyim ???? – thomaus

+1

Herhangi bir çözüm buldunuz mu? Teşekkürler. – user430926

cevap

30

Bu, this'un tam bir kopyasıdır. Kısacası, normal bir liste kullandım, kendi açılır menümüzü oluşturdum, özel bir açılır menü animasyonu ve voila başarısı kullandım (daha fazla açıklama için bağlantıya bakın).

Düzenleme:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:id="@+id/row_parent" 
    android:orientation="vertical"> 
    <RelativeLayout 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:id="@+id/row_simple_parent" 
     > 
    <View 
     android:id="@+id/row_simple_parent_invis_cover" 
     android:visibility="gone" 
     android:layout_height="something that fills out your content" 
     android:layout_width="match_parent" 
     android:background="@android:color/transparent"/> 
    </RelativeLayout> 

    <!-- Dropdown --> 
    <RelativeLayout 
     android:id="@+id/row_dropdown" 
     android:layout_height="wrap_content" 
     android:layout_width="match_parent"> 
    </RelativeLayout> 
</LinearLayout> 

açılan animasyon takip ediyor:

Önce xml list_row oluşturun: Ayrıntılı kılavuz

import android.app.Activity; 
import android.util.DisplayMetrics; 
import android.view.View; 
import android.view.View.MeasureSpec; 
import android.view.animation.Animation; 
import android.view.animation.Transformation; 

/** 
* Class for handling collapse and expand animations. 
* @author Esben Gaarsmand 
* 
*/ 
public class ExpandCollapseAnimation extends Animation { 
    private View mAnimatedView; 
    private int mEndHeight; 
    private int mStartVisibility; 

    /** 
    * Initializes expand collapse animation. If the passed view is invisible/gone the animation will be a drop down, 
    * if it is visible the animation will be collapse from bottom 
    * @param view The view to animate 
    * @param duration 
    */ 
    public ExpandCollapseAnimation(View view, int duration) { 
     setDuration(duration); 
     mAnimatedView = view; 
     mEndHeight = mAnimatedView.getLayoutParams().height; 
     mStartVisibility = mAnimatedView.getVisibility(); 
     if(mStartVisibility == View.GONE || mStartVisibility == View.INVISIBLE) { 
      mAnimatedView.setVisibility(View.VISIBLE); 
      mAnimatedView.getLayoutParams().height = 0; 
     } 
    } 

    @Override 
    protected void applyTransformation(float interpolatedTime, Transformation t) { 
     super.applyTransformation(interpolatedTime, t); 
     if (interpolatedTime < 1.0f) { 
      if(mStartVisibility == View.GONE || mStartVisibility == View.INVISIBLE) { 
       mAnimatedView.getLayoutParams().height = (int) (mEndHeight * interpolatedTime); 
      } else { 
       mAnimatedView.getLayoutParams().height = mEndHeight - (int) (mEndHeight * interpolatedTime); 
      } 
      mAnimatedView.requestLayout(); 
     } else { 
      if(mStartVisibility == View.GONE || mStartVisibility == View.INVISIBLE) { 
       mAnimatedView.getLayoutParams().height = mEndHeight; 
       mAnimatedView.requestLayout(); 
      } else { 
       mAnimatedView.getLayoutParams().height = 0; 
       mAnimatedView.setVisibility(View.GONE); 
       mAnimatedView.requestLayout(); 
       mAnimatedView.getLayoutParams().height = mEndHeight; 
      } 
     } 
    } 

    /** 
    * This methode can be used to calculate the height and set itm for views with wrap_content as height. 
    * This should be done before ExpandCollapseAnimation is created. 
    * @param activity 
    * @param view 
    */ 
    public static void setHeightForWrapContent(Activity activity, View view) { 
     DisplayMetrics metrics = new DisplayMetrics(); 
     activity.getWindowManager().getDefaultDisplay().getMetrics(metrics); 

     int screenWidth = metrics.widthPixels; 

     int heightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); 
     int widthMeasureSpec = MeasureSpec.makeMeasureSpec(screenWidth, MeasureSpec.EXACTLY); 

     view.measure(widthMeasureSpec, heightMeasureSpec); 
     int height = view.getMeasuredHeight(); 
     view.getLayoutParams().height = height; 
    } 
} 

Sonra Adaptörümdeki içindeki (eğer' ll ofcourse daha fazla sözdizimi ekleyin, ve listede görünmez olduğunda açılır kapanmazsa, bunu bir tür parametre ile de tutmalısınız:Bu bunu yapmanın en iyi yolu emin değilim ama bu benim için çalıştı budur:

@Override 
public void onListItemClick(ListView list, View view, int position, long id) { 
    final ListItem item = (ListItem) list.getAdapter().getItem(position); 
    // set dropdown data 
    ViewHolder holder = (ViewHolder) view.getTag(); 
    final View dropDown = holder.mDropDown; 

    // set click close on top part of view, this is so you can click the view 
    // and it can close or whatever, if you start to add buttons etc. you'll loose 
    // the ability to click the view until you set the dropdown view to gone again. 
    final View simpleView = view.findViewById(R.id.row_simple_parent_invis_cover); 
    simpleView.setVisibility(View.VISIBLE); 

    final Handler handler = new Handler() { 
     @Override 
     public void handleMessage(Message msg) { 
      if(msg.what == 0) { 
       // first we measure height, we need to do this because we used wrap_content 
       // if we use a fixed height we could just pass that in px. 
       ExpandCollapseAnimation.setHeightForWrapContent(getActivity(), dropDown); 
       ExpandCollapseAnimation expandAni = new ExpandCollapseAnimation(dropDown, DROP_DOWN_TIME); 
       dropDown.startAnimation(expandAni); 

       Message newMsg = new Message(); 

      } else if(msg.what == 1) { 
       ExpandCollapseAnimation expandAni = new ExpandCollapseAnimation(dropDown, DROP_DOWN_TIME); 
       dropDown.startAnimation(expandAni); 

       simpleView.setOnClickListener(null); 
       simpleView.setVisibility(View.GONE); 
      } 
     } 
    }; 

    simpleView.setOnClickListener(new OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      handler.sendEmptyMessage(1); 
     } 
    }); 

    // start drop down animation 
    handler.sendEmptyMessage(0); 
} 

Final comment:

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
    final ViewHolder holder; 
    if(convertView == null) { 
     // setup holder 
     holder = new ViewHolder(); 
     convertView = mInflater.inflate(R.layout.list_row, null); 
     holder.mDropDown = convertView.findViewById(R.id.row_dropdown); 
     convertView.setTag(holder); 
    } else { 
     // get existing row view 
     holder = (ViewHolder) convertView.getTag(); 
    } 
    holder.mDropDown.setVisibility(View.GONE); 
    return convertView; 
} 
Sonra sihirli Listelerinizdeki onItemClick olur.

Edit: youtube'da DevBytes tarafından farklı bir çözüm var, here görüntülenebilir.

+0

Bana gerçek bir örnek gösterir misiniz? Teşekkürler – Kermia

+1

@Kermia Daha sonra yapacağım. Buradan/diğer gönderiden veya her ikisinden de yazdığınızdan emin değilsiniz. İstediğinden beri burada yayınlayacağım sanırım. – Warpzit

+0

Merhaba, Kendi animasyonumu yapmak için örneğinizi kullanıyorum, ancak postDropHandler'ın ne yaptığını bilmiyorum ve mümkün olduğunda nasıl uygulanacağını bilmiyorum. Teşekkürler –

5

Warpzit tarafından belirtilen anwser doğrudur. aslında nasıl çalıştığını bilmek zorunda kalmadan kolayca uygulamada gömebilirsiniz bir kütüphane sağlamak için bu yaklaşım kullanılır:

https://github.com/tjerkw/Android-SlideExpandableListView

Daha bu blog yayınında okunabilir hakkında: http://tjerktech.wordpress.com/2012/06/23/an-emerging-android-ui-pattern-for-contextual-actions/

+0

lib'iniz oldukça ilgi çekicidir. Harika iş. – user755

-1
java sınıfında bu deneyin

 expListView.setAdapter(listAdapter); 
    expListView.setOnGroupExpandListener(new OnGroupExpandListener() { 
     int previousGroup = -1; 

     @Override 
     public void onGroupExpand(int groupPosition) { 
      if(groupPosition != previousGroup) 
       expListView.collapseGroup(previousGroup); 
      previousGroup = groupPosition; 
     } 
    }); 
3

çocuklu bir sürü gruplarını desteklemek için gerekirse Warpzit tarafından uygulanması kesinlikle ancak kullanışsız bir iştir gelmez a (100 diyelim) ListView'ın optimize edilmiş yapısını kullanmıyorsunuz (örn. Çocuk görüşlerinin yeniden kullanımı/geri dönüşümü). Bunun yerine, here'u anlattığım tekniği kullanan bir AnimatedExpandableListView oluşturmak için ExpandableListView öğesini genişletmeyi bitirdim. Bunu yaparak, AnimatedExpandableListView, hala en yüksek performansı sunarken grup genişletmeyi canlandırabilir.Have a look.

1

genişletmek/daraltmak buradan kodu ile çalışmaz: https://github.com/tjerkw/Android-SlideExpandableListViewAbstractSlideExpandableListAdapter den OnItemExpandCollapseListener expandCollapseListener çünkü null olduğu; yöntem notifiyExpandCollapseListener animasyon başladığında denilen, ancak çünkü dinleyici null bulunmaktadır: Eğer ActionSlideExpandableListView var:

ActionSlideExpandableListView lv = (ActionSlideExpandableListView) findViewById(R.id.list_view); 
SlideExpandableListAdapter slideAdapter = new SlideExpandableListAdapter(adapter,R.id.expandable_toggle_button, R.id.expandable); 

ve adaptör ayarlayın: SlideExpandableListView dan yöntemini setAdapter çağırır lv.setAdapter(slideAdapter); ve SlideExpandableListAdapter orada yeni bir örneği yaratıldı.

böyle değiştirildi: ActionSlideExpandableListView den setAdapter yöntem SlideExpandableListView den setAdapter yönteme geçirilir da bir parametre AbstractSlideExpandableListAdapter.OnItemExpandCollapseListener olarak alır . Ben SlideExpandableListAdapter oluştururken Ben de bu dinleyici vardır pass:

public void setAdapter(ListAdapter adapter, AbstractSlideExpandableListAdapter.OnItemExpandCollapseListener expandCollapseListener) { 
     this.adapter = new SlideExpandableListAdapter(adapter, expandCollapseListener); 
     super.setAdapter(this.adapter); 
    } 

    public SlideExpandableListAdapter(ListAdapter wrapped, OnItemExpandCollapseListener expandCollapseListener) { 
     this(wrapped, R.id.expandable_toggle_button, R.id.expandable); 
     setItemExpandCollapseListener(expandCollapseListener); 
    }