Добавить анимацию в ExpandableListView - PullRequest
11 голосов
/ 16 марта 2012

Есть ли способ добавить анимацию при открытии расширяемого списка в Android? Я хочу, чтобы, когда пользователь нажимал на расширяемый список, у него была анимация / эффект, как будто я открываю выдвижной ящик.

Медленно движется до полного открытия.

Ответы [ 5 ]

4 голосов
/ 08 декабря 2012

Я потратил много времени на поиски без удачи. Существующие решения просто недостаточно гладкие - если ваш макет представляет собой нечто более сложное, чем просто две кнопки, он становится запаздывающим.

Итак, я создал свой собственный ListAdapter, который кэширует весь вид в Bitmap, а затем выполняет анимацию для кэшированного представления вместо самого представления. Он работает намного быстрее.

Вот оно: https://github.com/dmitry-zaitsev/ExpandableAdapter

Хорошей новостью является то, что вам не нужно переписывать кучу кода - просто оберните мой ExpandableAdapter вокруг вашего адаптера и укажите идентификатор вида, который будет действовать как кнопка переключения, и идентификатор вида, который содержит содержимое второго уровня:

new ExpandableAdapter(context, yourAdapter, R.id.switch, R.id.holder);

И это все.

2 голосов
/ 22 августа 2013

Я тоже пытался сделать эту работу.Я нашел одно решение, которое работает для childViews.Это не оживляет фактическое расширение группы, но оживляет дочерние ячейки, поскольку они заполняют пространство, оставленное расширением.

Редактировать: при свертывании есть ошибка, из-за которой некоторые ячейки не должныбыть скрытым, стать скрытым.Вероятно, это связано с View-переработкой в ​​listView.Я обновлю, когда у меня будет решение этой проблемы.

Анимация с layoutAnimation в setOnGroupClickListener

        mResultList.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() {
        @Override
        public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) {
            if(mResultList.isGroupExpanded(groupPosition)){
                mProgAdap.prepareToCollapseGroup(groupPosition);
                setupLayoutAnimationClose(groupPosition);
                mResultList.requestLayout();
            }else{
                boolean autoScrollToExpandedGroup = false;
                mResultList.expandGroup(groupPosition,autoScrollToExpandedGroup);
                setupLayoutAnimation();
                //*/
            }
            //telling the listView we have handled the group click, and don't want the default actions.
            return true;
        }

        private void setupLayoutAnimation() {
            AnimationSet set = new AnimationSet(true);
            Animation animation = new AlphaAnimation(0.0f, 1.0f);
            animation.setDuration(50);
            set.addAnimation(animation);

            animation = new ScaleAnimation(1.0f, 1.0f, 0.0f, 1.0f, 0.5f, 1.0f);
            animation.setDuration(50);
            set.addAnimation(animation);

            LayoutAnimationController controller = new LayoutAnimationController(set, 0.75f);
            mResultList.setLayoutAnimationListener(null);
            mResultList.setLayoutAnimation(controller);
        }

        private void setupLayoutAnimationClose(final int groupPosition) {
            AnimationSet set = new AnimationSet(true);
            Animation animation = new AlphaAnimation(1.0f, 0.0f);
            animation.setDuration(50);
            animation.setFillAfter(true);
            animation.setFillEnabled(true);
            set.addAnimation(animation);
            animation = new ScaleAnimation(1.0f, 1.0f, 1.0f, 0.0f, 0.5f, 0.0f);
            animation.setDuration(50);
            animation.setFillAfter(true);
            animation.setFillEnabled(true);
            set.addAnimation(animation);
            set.setFillAfter(true);
            set.setFillEnabled(true);
            LayoutAnimationController controller = new LayoutAnimationController(set, 0.75f);
            controller.setOrder(LayoutAnimationController.ORDER_REVERSE);
            mResultList.setLayoutAnimationListener(new Animation.AnimationListener() {
                @Override
                public void onAnimationStart(Animation animation) {

                }

                @Override
                public void onAnimationEnd(Animation animation) {
                    mResultList.collapseGroup(groupPosition);
                }

                @Override
                public void onAnimationRepeat(Animation animation) {

                }
            });
            mResultList.setLayoutAnimation(controller);
        }
    });

Нам нужно больше настроек, чтобы анимация применялась только кфактические дети расширенной / свернутой группы.Поскольку мы не можем перегрузить правильную часть в LayoutAnimationController, нам нужно создать специальный класс ViewGroup.Это та же техника, что и в «Может LayoutAnimationController анимировать только указанные представления» .

В ExpandableListViewAdapter нам теперь требуется некоторая обработка состояний, чтобы разрешить или игнорировать анимацию для элементов в списке.

    @Override
public void onGroupExpanded(int groupPos){
    super.onGroupExpanded(groupPos);

    int childCount = getChildrenCount(groupPos);
    Log.d("EXPLIST","setting children to be expanded:" + childCount);

    for(int j=0; j < getGroupCount(); j++){
        for(int k=0; k < getChildrenCount(j); k++){
            GoalServiceCell cell =  (GoalServiceCell)getChild(j,k);
            cell.expandAnimState = GoalServiceCell.ExpandAnimState.SHOULD_NOT_ANIMATE;
        }
    }

    for(int i=0; i < childCount; i++){
        GoalServiceCell cell =  (GoalServiceCell)getChild(groupPos,i);
        cell.expandAnimState = GoalServiceCell.ExpandAnimState.SHOULD_START_EXPAND;

    }

}

public void prepareToCollapseGroup(int groupPos){
    int childCount = getChildrenCount(groupPos);
    for(int j=0; j < getGroupCount(); j++){
        for(int k=0; k < getChildrenCount(j); k++){
            GoalServiceCell cell =  (GoalServiceCell)getChild(j,k);
            cell.expandAnimState = GoalServiceCell.ExpandAnimState.SHOULD_NOT_ANIMATE;
        }
    }

    for(int i=0; i < childCount; i++){
        GoalServiceCell cell =  (GoalServiceCell)getChild(groupPos,i);
        cell.expandAnimState = GoalServiceCell.ExpandAnimState.SHOULD_START_COLLAPSIN;

    }
}

@Override
public void onGroupCollapsed(int groupPos){
    super.onGroupCollapsed(groupPos);
    int childCount = getChildrenCount(groupPos);
    for(int i=0; i < childCount; i++){
        GoalServiceCell cell =  (GoalServiceCell)getChild(groupPos,i);
        cell.expandAnimState = GoalServiceCell.ExpandAnimState.SHOULD_NOT_ANIMATE;
    }

}

И в ViewHolder дочерних элементов.

       void expandOrCollapse(GoalServiceCell cell,int position){

        AnimationAverseRelativeLayout hack = (AnimationAverseRelativeLayout)master;
        boolean shouldAnim = cell.expandAnimState == GoalServiceCell.ExpandAnimState.SHOULD_START_EXPAND ||
                             cell.expandAnimState == GoalServiceCell.ExpandAnimState.SHOULD_START_COLLAPSIN;
        hack.setIfShouldAnimate(shouldAnim);

    }

GroupViews также содержатся в AnimationAverseRelativeLayout.Так как я установил для «shouldAnimate» значение по умолчанию false, мне не нужно их трогать.

2 голосов
/ 23 июня 2012

У меня была такая же проблема. И я исправил это раз и навсегда. Я открыл его для GitHub. https://github.com/tjerkw/Android-SlideExpandableListView

По сути, вы включаете эту зависимость проекта в свой проект Android. А затем заверните ваш ListAdapter в SlideExpandableListAdapter. Обертка добавит функциональность слайдов с анимацией к вашему ListView.

Надеюсь, это поможет вам, я уже использую его в двух проектах.

1 голос
/ 03 апреля 2012

Итак, я использовал обычный ListView, а затем выполнил анимацию в onListItemClick. Анимация похожа на ту, что я делаю по этой ссылке: Android-анимация, собственно выпадающий / верхний вид

Но только для части вида строки. Представление строки реализовано следующим образом в xml:

<somelayout>
    <normal>
    </normal>
    <expanded>
    </expanded>
</somelayout>

Обычный используется без расширения. Когда расширение активировано, расширенное становится видимым, а не пропавшим. Вам нужно сохранить контроль над тем, чтобы при закрытии он снова исчез (помните, что это установлено в ваших конвертированных представлениях, которые были переработаны).

Я могу уточнить, если это необходимо, просто достаточно много кода для вставки.

0 голосов
/ 08 декабря 2012

Это то, что я делал в этих ситуациях.

ObjectAnimator objectAnimator = ObjectAnimator.ofPropertyValuesHolder (list1, PropertyValuesHolder.ofInt ("bottom", currentlistHeight, currentlistHeight * 2));

* 1005)*

Что это будет делать, так это то, что высота listView увеличится вдвое и будет анимированной .Если вы установите текущую высоту списка ZERO .это будет действовать как ящик.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...