ListView项目上的自定义动画不会第一次触发

时间:2014-07-30 13:16:07

标签: android listview animation android-cursoradapter

我在这里有一些代码(我没有写),我需要修复它。这是所需的流程:

  1. 用户点击ListView
  2. 中的项目
  3. 该项目展开以显示隐藏的页脚
  4. 如果展开了另一个列表项,则会缩小回正常大小(因此一次只展开一个项目)。
  5. 我的问题:当点击未展开的项目时,没有任何反应。第二次,项目扩展,点击再次收缩,然后第一次点击什么都不做,等等。

    当然,我正在努力消除第一个无效的冗余水龙头。

    另一个有趣的副作用:当我第一次点击一个项目时,没有任何反应,那么我将点击一个不同的项目,这两个项目将一起扩展。

    我已经对代码进行了很长一段时间了,我看不出是什么导致了这个问题。

    以下是代码:

    ListView

    上设置监听器
    productsListView.setOnItemClickListener(new OnItemClickListener() {
    
                @Override
                public void onItemClick(AdapterView<?> list, View view,int position, long id) 
                {
    
    
                    if (lastSelectedPosition == -1) {
                        lastSelectedPosition = position;
                    } else if (lastSelectedPosition == position) {
                        lastSelectedPosition = -1;
                    } else {
                        lastSelectedPosition = position;
                    }
    
    
                    View child;
                    ProductItemView tag;
                    for (int i = 0; i < productsListView.getChildCount(); i++) {
                        child = productsListView.getChildAt(i);
                        tag = (ProductItemView) child.getTag();
                        tag.onSomeListItemClicked(position);
                        productsListView.smoothScrollToPosition(position);
                    }
    
    
                }
            });
    

    列表视图的适配器:

    public class ProductsCursorAdapter extends CursorAdapter {
    
            public ProductsCursorAdapter(Context context, Cursor c, int flags) {
                super(context, c, flags);
            }
    
            @Override
            public void bindView(View view, Context context, Cursor cursor) {
    
                ProductItemView item = null;
    
                int pos = cursor.getPosition();
                Log.d("BookListFragment", "BookListFragment: Position is: " + pos);
                item = new ProductItemView(getActivity(), cursor.getPosition(), view, new ProductDAO(cursor));
    
                view.setTag(item);
    
                item.setContainer(BookListFragment.this, BookListFragment.this);
    
                if (lastSelectedPosition == cursor.getPosition()) {
                    item.openedFooter();
                }
    
            }
    
            @Override
            public View newView(Context context, Cursor cursor, ViewGroup viewGroup) {
                View view = (View) getActivity().getLayoutInflater().inflate(R.layout.course_list_item, null);
    
                return view;
    
            }
        }
    

    ProductItemView中的相关代码:

    public void onSomeListItemClicked(int position) 
        {
            if (m_position == position)
            {
                Log.i("ProductItemView", "Animate footer for position: " + m_position);
                animateFooter(position);
            }
            else
            {
    
                Log.i("ProductItemView", "Hide footer for position: " + m_position);
                hideFooter(position);
    
            }
        }
    
    public void showFooter(int position) {
    
            if (!isFooterVisible())
            {
                animateFooter(position);
            }
        }
    
        public void hideFooter(int position) 
        {
            Log.i("ProductItemView", "Hide called for position: " + m_position);
    
            if (isFooterVisible() && position != m_position)
            {
                animateFooter(position);
            }
    
        }
    
        public void animateFooter(final int position) 
        {
            if (footer != null && (m_footerExpandAnim == null || m_footerExpandAnim.hasEnded()))
            {
                Log.i("ProductItemView", "Animating footer for position: " + m_position);
                isFooterVisible=!isFooterVisible;
    
    
                m_footerExpandAnim = new ExpandAnimation(footer, 200, animationDelegate, position);
                footer.startAnimation(m_footerExpandAnim);      
            }
        }
    

    ExpandAnimation:

    public ExpandAnimation(View view, int duration, AnimationDelegate delegate, int position) {
    
            this.position = position;
            this.delegate = delegate;
            setDuration(duration);
            mAnimatedView = view;
            mViewLayoutParams = (LayoutParams) view.getLayoutParams();
    
            // decide to show or hide the view
            mIsVisibleAfter = (view.getVisibility() == View.VISIBLE);
    
    
            mMarginStart = mViewLayoutParams.bottomMargin;
    
    
            mMarginEnd = (mMarginStart == 0 ? (-view.getHeight()) : 0);
            mAnimatedView.clearAnimation();
    
            Log.i("ExpandAnimation", "Margin Start = " + mMarginStart + ", Margin End = " + mMarginEnd);
            //view.setVisibility(View.VISIBLE);
        }
    
        @Override
        protected void applyTransformation(float interpolatedTime, Transformation t) {
            super.applyTransformation(interpolatedTime, t);
    
            Log.i("ExpandAnimation", "InterpolatedTime: " + interpolatedTime);
    
            if (interpolatedTime < 1.0f) {
    
                // Calculating the new bottom margin, and setting it
                mViewLayoutParams.bottomMargin = mMarginStart
                        + (int) ((float)(mMarginEnd - mMarginStart) * interpolatedTime);
    
                mAnimatedView.setLayoutParams(mViewLayoutParams);
                // Invalidating the layout, making us seeing the changes we made
                mAnimatedView.requestLayout();
                mAnimatedView.postInvalidate();
    
            // Making sure we didn't run the ending before (it happens!)
            } else if (!mWasEndedAlready) {
                mViewLayoutParams.bottomMargin = mMarginEnd;
                mAnimatedView.setLayoutParams(mViewLayoutParams);
                mAnimatedView.requestLayout();
                mAnimatedView.postInvalidate();
    
                if (mIsVisibleAfter) {
                    //mAnimatedView.setVisibility(View.GONE);
                }
                mWasEndedAlready = true;
            }
    
            if(delegate!=null){
                delegate.animationDidEnd(position);
            }
        }
    

    我注意到的一些事情:

    1. 第一次单击该项时,确实调用了ExpandAnimation's构造函数,但不会打印applyTransformation方法中的日志。

    2. 第二次单击该项时,将调用ExpandAnimation's构造函数,但mMarginStart值不是它应该的值(在-60到-80之间随机而不是-100),但是applyTransformation中的日志正确打印​​。

    3. 如果您需要更多代码,请与我们联系。任何想法都会有所帮助。

      正如我所提到的,这不是我的代码 - 我正在尝试编辑自此以后开发人员编写的代码。如果由我来决定,整个事情的写法将大不相同。我需要一个解决方案,它对代码结构的修改很少。

1 个答案:

答案 0 :(得分:0)

好的,我发现了问题。

线索是我注意到在第一次点击“没有做”之后,如果我稍微滚动列表,我点击的项目会突然扩大。这告诉我,由于某种原因,ListView阻止其子视图执行UI操作。

我在OnItemClick侦听器的列表中添加了一个postInvalidate调用,一切都按预期工作。

有趣。