5

我正在尝试在 ios 应用 Applauze 中制作自定义列表视图。

我扩展了 listview 类,并在 onTouchEvent 的帮助下尝试检测子行的移动并在移动时改变它们的高度。因此,与其他行相比,最上面的孩子具有最大的高度。

  public class CustView extends ListView{

    private float mLastTouchY;
    private int mActivePointerId;
    private boolean up=false;
    private boolean down=false;
    private final Camera mCamera = new Camera();
    private final Matrix mMatrix = new Matrix();
    private Context context;
    private Paint mPaint;


    public CustView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
        this.setChildrenDrawingOrderEnabled(true);
    }   
    public CustView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        // TODO Auto-generated constructor stub
    }

    @Override
    protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
        // get top left coordinates
        boolean isTop = false;
        final int top = child.getTop();
        final int bottom = child.getBottom();
        child.setMinimumHeight(getHeight()/3);
        Bitmap bitmap = child.getDrawingCache();
        Bitmap cropBitmap;
        if (bitmap == null) {
            child.setDrawingCacheEnabled(true);
            child.buildDrawingCache();
            bitmap = child.getDrawingCache();
        }
        int belowE = (child.getHeight()*2/3)+getPaddingTop();
        int aboveE = (child.getHeight())+getPaddingTop();
        mCamera.save();
        if(up){
            if (top>=belowE) {
                //make all small
                isTop = true;
                //canvas.scale(1.0f, 0.5f);
                cropBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight()/2);
                child.setMinimumHeight(2);
                //child.setLayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT));
                child.setPressed(true);
                Log.e("Chota", child.getMeasuredHeight()+"True"+top);
            }  
            else {
                //canvas.scale(1.0f,xy);
                cropBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight());
                //child.setLayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT));
                //child.setMinimumHeight(4);
                Log.e("Bada", child.getMeasuredHeight()+"False"+top);
                child.setPressed(false);
            };
        }
        else{
            if (bottom>aboveE) {
                //make center row bigger
                isTop = true;
                //canvas.scale(1.0f, 0.5f);
                cropBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight()/2);
                child.setMinimumHeight(2);
                child.setPressed(true);
                Log.e("Bada", child.getMeasuredHeight()+"True"+top);
            }  
            else {
                //canvas.scale(1.0f,xy);
                cropBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight());
                //child.setMinimumHeight(getHeight()/4);
                Log.e("Chota", child.getMeasuredHeight()+"False"+top);
                child.setPressed(false);
            };
        }

            mCamera.getMatrix(mMatrix);
        mCamera.restore();

        // create and initialize the paint object
        if (mPaint == null) {
            mPaint = new Paint();
            mPaint.setAntiAlias(true);
            mPaint.setFilterBitmap(true);
        }
        mMatrix.postScale(1.0f, 1.5f);
        mMatrix.postTranslate(child.getLeft(), top);
        canvas.drawBitmap(cropBitmap, mMatrix, mPaint);
        //Log.e("Up", "Child"+top+" "+getTop());
        return false;
    }



    /* (non-Javadoc)
     * @see android.widget.AbsListView#onTouchEvent(android.view.MotionEvent)
     */
    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        // TODO Auto-generated method stub
        final int action = MotionEventCompat.getActionMasked(ev); 

        int INVALID_POINTER_ID=65421385;
        switch (action) { 
        case MotionEvent.ACTION_DOWN: {
            final int pointerIndex = MotionEventCompat.getActionIndex(ev); 
            // Remember where we started (for dragging)
            mLastTouchY = MotionEventCompat.getY(ev, pointerIndex);
            // Save the ID of this pointer (for dragging)
            mActivePointerId = MotionEventCompat.getPointerId(ev, 0);
            Log.e("Down", "Down");
            break;
        }

        case MotionEvent.ACTION_MOVE: {
            // Find the index of the active pointer and fetch its position
            final int pointerIndex = 
                    MotionEventCompat.findPointerIndex(ev, mActivePointerId);  
            final float y = MotionEventCompat.getY(ev, pointerIndex);

            // Calculate the distance moved
            final float dy = y - mLastTouchY;

            up = dy<0;
            down = dy>0;

            //((MyAdapter)getListAdapter()).animate(fVI,top,bottom,getChildCount());
            if(Math.abs(dy)>10){
                Log.e("Dist", "D-"+Math.abs(dy));
                invalidate();
            }

            // Remember this touch position for the next move event
            mLastTouchY = y;
            Log.e("Move", "Move");
            break;
        }

        case MotionEvent.ACTION_UP: {
            mActivePointerId = INVALID_POINTER_ID;
            Log.e("Up", "Up");
            break;
        }

        case MotionEvent.ACTION_CANCEL: {
            mActivePointerId = INVALID_POINTER_ID;
            break;
        }

        case MotionEvent.ACTION_POINTER_UP: {

            final int pointerIndex = MotionEventCompat.getActionIndex(ev); 
            final int pointerId = MotionEventCompat.getPointerId(ev, pointerIndex); 

            if (pointerId == mActivePointerId) {
                // This was our active pointer going up. Choose a new
                // active pointer and adjust accordingly.
                final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
                mLastTouchY = MotionEventCompat.getY(ev, newPointerIndex); 
                mActivePointerId = MotionEventCompat.getPointerId(ev, newPointerIndex);
            }
            break;
        }
        }
        return super.onTouchEvent(ev);
    }

    /* (non-Javadoc)
     * @see android.view.View#onScrollChanged(int, int, int, int)
     */
    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        // TODO Auto-generated method stub
        super.onScrollChanged(l, t, oldl, oldt);
    }
}

但问题是,正如我在日志中看到的那样,drawchild 函数被反复调用,这使得列表视图的响应性降低。还有将动画应用于每一行的最佳方法是什么?如果有人知道原因请告诉我!!!谢谢。

4

1 回答 1

1

当您在重复调用的drawChild()函数中做大量工作时,显然会插入滞后,从而使您的列表视图响应速度降低。因此,您可能可以根据某些计时器或其他逻辑跳过某些drawChild()函数调用。当我们在应用程序中处理传感器事件时,我们通常会这样做。实现这一点应该很简单。

对于列表视图行动画,您可以点击以下链接。制作动画的最佳方法是编写动画 xml,然后使用它们为列表视图中的行制作动画:

http://karnshah8890.blogspot.kr/2013/04/listview-animation-tutorial.html

希望这可以帮助。

于 2014-03-06T08:09:58.843 回答