调整Touch事件大小时的图像视图闪烁

时间:2015-04-03 10:16:40

标签: android performance android-layout

要求:

创建彼此重叠的图像视图列表,可以在触摸事件上调整大小(仅限高度)。调整一个视图的大小不应该调整其他视图的大小。

问题:

我创建了一个相对布局,并使用ALIGN_PARENT_BOTTOM.将我的第一个孩子(图片视图)对齐到相对布局的底部。我在底部图片视图上方添加了更多图片视图。我还在触摸事件上实现了图像调整大小,如下所示。问题是当我在ACTION_MOVE上调整大小时,图像视图会闪烁。如果我将我的第一个孩子(图片视图)与顶部对齐,则不会发生这种情况。我相信这是因为ALIGN_PARENT_BOTTOM被称为触摸事件。不知道如何解决这个问题。

反馈

也希望获得有关满足要求的这种方法的反馈。我不确定这种方法的性能是否有缺点。

任何帮助都是赞赏的。谢谢!

public class StackLayoutActivity extends ActionBarActivity {

private float mLastTouchX;
private float mLastTouchY;
private int mActivePointerId;
private float mPosX;
private float mPosY;
private static final int INVALID_POINTER_ID = -1;
private ImageView imageViewTwo;
private ImageView imageViewOne;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.stack_layout);
    init();
}

@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
private void init() {
    int imageTwoHeight = 250;
    int imageOneHeight = 400;
    RelativeLayout.LayoutParams imageTwoParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, imageTwoHeight);
    RelativeLayout.LayoutParams imageOneParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, imageOneHeight);

    imageViewTwo = new ImageView(getApplicationContext());
    imageViewTwo.setScaleType(ImageView.ScaleType.MATRIX);
    imageViewTwo.setImageDrawable(getResources().getDrawable(R.drawable.abc_ic_menu_moreoverflow_mtrl_alpha));
    imageViewTwo.setId(View.generateViewId());
    imageViewTwo.setOnTouchListener(new ImageTwoTouchListener());

    imageViewOne = new ImageView(getApplicationContext());
    imageOneParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, RelativeLayout.TRUE);
    imageViewOne.setLayoutParams(imageOneParams);
    imageViewOne.setScaleType(ImageView.ScaleType.MATRIX);
    imageViewOne.setImageDrawable(getResources().getDrawable(R.drawable.abc_ic_ab_back_mtrl_am_alpha));
    imageViewOne.setId(View.generateViewId());
    imageViewOne.setOnTouchListener(new ImageOneTouchListener());
    RelativeLayout layout = (RelativeLayout) this.findViewById(R.id.container);

    imageTwoParams.addRule(RelativeLayout.ABOVE, imageViewOne.getId());
    layout.addView(imageViewOne);
    layout.addView(imageViewTwo, imageTwoParams);
}


private class ImageOneTouchListener implements View.OnTouchListener {
    @Override
    public boolean onTouch(View v, MotionEvent ev) {
        final int action = ev.getAction();
        switch (action & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_DOWN: {
                final float x = ev.getX();
                final float y = ev.getY();

                mLastTouchX = x;
                mLastTouchY = y;
                mActivePointerId = ev.getPointerId(0);
                break;
            }

            case MotionEvent.ACTION_MOVE: {
                final int pointerIndex = ev.findPointerIndex(mActivePointerId);
                final float x = ev.getX(pointerIndex);
                final float y = ev.getY(pointerIndex);


                final float dist = y - mLastTouchY;

                // Only move if the ScaleGestureDetector isn't processing a gesture.
                final float dx = x - mLastTouchX;
                final float dy = y - mLastTouchY;

                mPosX += dx;
                mPosY += dy;

                mLastTouchX = x;
                mLastTouchY = y;

                ViewGroup.LayoutParams lp = imageViewOne.getLayoutParams();
                lp.height -= dist;
                imageViewOne.setLayoutParams(lp);
                break;
            }

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

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

        return true;
    }
}

private class ImageTwoTouchListener implements View.OnTouchListener {
    @Override
    public boolean onTouch(View v, MotionEvent ev) {
        final int action = ev.getAction();
        switch (action & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_DOWN: {
                final float x = ev.getX();
                final float y = ev.getY();

                mLastTouchX = x;
                mLastTouchY = y;
                mActivePointerId = ev.getPointerId(0);
                break;
            }

            case MotionEvent.ACTION_MOVE: {
                final int pointerIndex = ev.findPointerIndex(mActivePointerId);
                final float x = ev.getX(pointerIndex);
                final float y = ev.getY(pointerIndex);

                final float dist = y - mLastTouchY;

                // Only move if the ScaleGestureDetector isn't processing a gesture.
                final float dx = x - mLastTouchX;
                final float dy = y - mLastTouchY;

                mPosX += dx;
                mPosY += dy;


                mLastTouchX = x;
                mLastTouchY = y;

                ViewGroup.LayoutParams lp = imageViewTwo.getLayoutParams();
                lp.height -= dist;
                imageViewTwo.setLayoutParams(lp);

                break;
            }

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

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

        return true;
    }
}
}

1 个答案:

答案 0 :(得分:0)

通过删除ACTION_MOVE中对Last touch位置的修改来修复闪烁问题。从ACTION_MOVE块中删除了以下代码

mLastTouchX = x;
mLastTouchY = y;