Thursday, December 12, 2013

refactor a code example using one of the new Android SDKs

there are multiple ways in any development task to solve the problem, but the refactor below takes advantage of the object animator and results in a more than 50% code saving. Since it's been a few weeks, I'm posting both the original and the refactored MainActivity.java file. 
Code Listing #1: Using the Object Animator
public class MainActivity extends Activity implements OnClickListener{

 private boolean isHere;
 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  isHere = true;
  findViewById(R.id.here_button).setOnClickListener(this);
  findViewById(R.id.there_button).setOnClickListener(this);
 }

 @Override
 public void onClick(View v) {
  View cursor = findViewById(R.id.cursor);
  float diff;
  if (v.getId()==R.id.here_button && !isHere) {
   diff = (float) (cursor.getX() - v.getX() - v.getWidth());
   ObjectAnimator.ofFloat(cursor, "translationX", diff, 0).setDuration(1000).start();
   isHere=true;
  } else if (v.getId()==R.id.there_button && isHere) {
   diff = v.getX() - cursor.getX() - cursor.getWidth();
   ObjectAnimator.ofFloat(cursor, "translationX", 0, diff).setDuration(1000).start();
   isHere=false;
  }
 }
 
}
Code Listing #2: Original MainAcitvity.java
MainActivity extends Activity implements OnClickListener, AnimationListener {

 private final static int HERE = -1;
 private final static int THERE = 1;
 private TranslateAnimation anim;
 private View cursor;
 private int screenWidth;
 private int centerOfScreen;
 private int dest;
 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  screenWidth = (int) (getWindowManager().getDefaultDisplay().getWidth());
  centerOfScreen = (int) (screenWidth *.5);
  cursor = findViewById(R.id.cursor);
  findViewById(R.id.here_button).setOnClickListener(this);
  findViewById(R.id.there_button).setOnClickListener(this);
 }

 @Override
 public void onClick(View v) {
  if (v.getId()==R.id.here_button) {
   animate(HERE);
  } else {
   animate(THERE);
  }
 }
 
 private void animate(int whichWay) {
  if (anim!=null && !anim.hasEnded()) return;
  float target;
  int currentX = cursor.getLeft();
  if (whichWay==HERE ) {
   if (currentX+cursor.getWidth()<=centerOfScreen) return;
   target = (currentX - 
     (findViewById(R.id.here_button).getLeft() + findViewById(R.id.here_button).getWidth()))*-1;
  } else {
   if (currentX>centerOfScreen) return;
   target = findViewById(R.id.there_button).getLeft() - (currentX + cursor.getWidth());
  }
  anim = new TranslateAnimation( TranslateAnimation.ABSOLUTE,0,
         TranslateAnimation.ABSOLUTE,target,
         TranslateAnimation.ABSOLUTE,0.0f,
         TranslateAnimation.ABSOLUTE,0.0f);
  anim.setDuration(500);
  dest = (int) target+cursor.getLeft()+cursor.getWidth();
        anim.setAnimationListener(this);
        cursor.startAnimation(anim);
 }

 @Override
 public void onAnimationEnd(Animation arg0) {
  RelativeLayout.LayoutParams params = 
    new RelativeLayout.LayoutParams(cursor.getWidth(), cursor.getHeight());
  if (dest >= centerOfScreen) {
   params.addRule(RelativeLayout.LEFT_OF, R.id.there_button);
  } else {
   params.addRule(RelativeLayout.RIGHT_OF, R.id.here_button);
  }
  params.addRule(RelativeLayout.CENTER_VERTICAL);
  cursor.setLayoutParams(params);
 }

 @Override
 public void onAnimationRepeat(Animation arg0) {
  // TODO Auto-generated method stub
  
 }

 @Override
 public void onAnimationStart(Animation arg0) {
  // TODO Auto-generated method stub
  
 }
 
}