1

我一直在寻找这个问题,但没有找到与我的情况相符的东西。

我的问题发生在 Android 2.3.x 上(在 4.x 上它工作得很好)

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

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 -> 列表中的第二个元素是动画的,mSwap2=2 -> n-1 元素并且列表中的 n-2 元素是动画的,其中 n 是可见元素的数量)。

4

1 回答 1

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);
}

向该方法添加Animation参数允许区分元素(mSwap1 和 mSwap2)之间的动画。

于 2013-07-12T07:19:21.740 回答