姜饼列表视图项目动画问题

时间:2013-07-11 08:15:33

标签: android listview animation android-2.3-gingerbread

我已经找到了这个问题,但我找到的并不符合我的情况。

我的问题发生在Android 2.3.x上(在4.x上运行完美)

我有一个带有自定义列表视图的应用程序。我将listview初始化如下

ListAdapter mListAdapter = new ListAdapter(getApplicationContext(), this, ...);
lvSelector = (ListView) findViewById(R.id.listView1);
lvSelector.setAdapter(mListAdapter);

我的ListAdapter如下:

public class ListAdapter extends BaseAdapter {
    static class Holder {
    LinearLayout layoutRoot, layoutColor;
    TextView  hText;
    Animation anim = AnimationUtils.loadAnimation(mActivity, R.anim.anim_list_item);

    public Holder() {
        layoutRoot = new LinearLayout(mContext);
        layoutColor = new LinearLayout(mContext);
        hText = new TextView(mContext);
    }

    public Holder(Holder holder) {
        this.layoutRoot = holder.layoutRoot;
        this.layoutColor = holder.layoutColor;
        this.hText = holder.hText;
    }
}

    int mSwap1, mSwap2;

    Animation mAnimation;

    public ListAdapter(Context _context, Activity _activity, FileHandler _fileHandler, String _strSchemaName, List<String> _list, List<String> _solution) {
        mContext = _context;
        mActivity = _activity;

        mAnimation = AnimationUtils.loadAnimation(mActivity, R.anim.anim_list_item);
        mAnimation.reset();

        mSwap1 = mSwap2 = -1;

        /* ... */

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            final int fPosition = position;

    View row = convertView;
    Holder lHolder = null;

    if (row==null) {
                LayoutInflater inflater = mActivity.getLayoutInflater();
                row = inflater.inflate(R.layout.layout_schema_element, parent, false);

                lHolder = new Holder();
                lHolder.layoutRoot = (LinearLayout) row.findViewById(R.id.elementLayoutRoot);
                lHolder.layoutColor = (LinearLayout) row.findViewById(R.id.elementLayoutColor);
                lHolder.hText = (TextView) row.findViewById(R.id.textViewWord);

                row.setTag(lHolder);
            }
            else {
                lHolder = (Holder)row.getTag();
            }

            row.setOnClickListener(null);

            if (position==0 || position==mDataList.size()-1) {
                lHolder.layoutColor.setBackgroundResource(R.drawable.bg_elem_fixed);
                lHolder.layoutColor.setOnClickListener(null);
            }
            else {
                lHolder.layoutColor.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        moveElement(fPosition);
                    }
                });

    }

    lHolder.hText.setText(mDataList.get(position));
    lHolder.layoutRoot.setBackgroundResource(0);

    mHolder.set(position, lHolder);

    return row;
    }
}

protected void moveElement(int _element) {
    if (mDataList.get(_element).equals(mSolution.get(_element)))
        return;

    if (mSwap1==-1)
    {
        System.out.println("setting swap1=" + _element);
        mHolder.get(_element).layoutRoot.setBackgroundResource(R.drawable.bg_elem_selected_lite);
        mSwap1 = _element;
    }
    else
    {
        if (mSwap2==-1)
        {
            System.out.println("setting swap2=" + _element);

            mHolder.get(_element).layoutRoot.setBackgroundResource(R.drawable.bg_elem_selected_lite);
            mSwap2 = _element;
        }
    }

            if (mSwap1!=-1)
    {
        System.out.println("running animation on mSwap1=" + mSwap1);
        mHolder.get(mSwap1).layoutRoot.clearAnimation();
        mHolder.get(mSwap1).layoutRoot.startAnimation(mAnimation);
    }

    /***** THIS IS WHAT DOES NOT WORK *****/
            if (mSwap2!=-1)
    {
        System.out.println("running animation on mSwap2=" + mSwap2);
        mHolder.get(mSwap2).layoutRoot.clearAnimation();
        mHolder.get(mSwap2).layoutRoot.startAnimation(mAnimation);
    }


    if (mSwap1!=-1 && mSwap2!=-1)
    {
        mHolder.get(mSwap1).layoutRoot.setBackgroundColor(0);
        mHolder.get(mSwap2).layoutRoot.setBackgroundColor(0);

        if (mSwap1==mSwap2)
        {
            mSwap1 = mSwap2 = -1;
            return;
        }

        Collections.swap(mDataList, mSwap1, mSwap2);
        Collections.swap(mHolder, mSwap1, mSwap2);
        Collections.swap(dataObjs, mSwap1, mSwap2);

        mSwap1 = mSwap2 = -1;

        notifyDataSetChanged();
    }
}

}

当我执行 Collections.swap(list,mSwap1,mSwap2)时,一切正常,元素被正确交换。

第一个动画(mSwap1)运行正常;我的问题是当第二个动画运行时(mSwap2),它在屏幕上的另一个元素上执行,即使mSwap2是正确的(例如:mSwap1 = 1 - &gt;列表中的第二个元素是动画的,mSwap2 = 2 - &gt; n-列表中的1个元素和n-2个元素是动画的,其中n是可见元素的数量。)

1 个答案:

答案 0 :(得分:0)

我已经解决了替换动画调用的问题

mHolder.get(idx).layoutRoot.clearAnimation();
mHolder.get(idx).layoutRoot.startAnimation(mAnimation);

使用以下方法

private void animateItem(int _index, Animation _animation) {
    if (
        _index<mLvSelector.getFirstVisiblePosition()   // selected item is above first visible element
        || _index>mLvSelector.getLastVisiblePosition() // selected item is below last  visible element
    )
        // element is invisible -> no animation
        return;

    int newIndex = _index;

    if (
        android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH // before android 4.0
        && mSwap2>=0 // second selection
        && mSwap1!=mSwap2 // second selection differs from first selection
    )
        newIndex = mLvSelector.getFirstVisiblePosition() + (mLvSelector.getLastVisiblePosition() - _index);

    mHolder.get(newIndex).layoutRoot.clearAnimation();
    mHolder.get(newIndex).layoutRoot.startAnimation(_animation);
}

在方法中添加动画参数可以区分元素之间的动画(mSwap1和mSwap2)。