title: Image View Flicker when resizing on Touch events
body: <p><B>Requirement:</B></p>
  
  <p>To create a list of image view on top of each other which can be resized(only heightwise) on touch events. Resizing one view should not resize other view.</p>
  
  <p><strong>Issue:</strong></p>
  
  <p>I created a relative layout and I aligned my first child (image view) to the bottom of the relative layout using <code>ALIGN_PARENT_BOTTOM.</code> I add more image views above the bottom image view. I have also implemented image resize on touch event as below. The problem is that the image view flickers as I resize on <code>ACTION_MOVE</code>. If I align my first child(image View) to top this doesn't happen. I believe this is because of the <code>ALIGN_PARENT_BOTTOM</code> being called on touch event. Not sure how to fix this. </p>
  
  <p><strong>Feedback:</strong></p>
  
  <p>Also want to get feedback on this approach for meeting the requirements.I am not sure is performance is a downside in this approach. </p>
  
  <p>Any help is Appreciated. Thanks!</p>
  
  <pre><code>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 &amp; 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 &amp; 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;
      }
  }
  }
  </code></pre>