mobappdev (fall 2014): circular motion, sinusoid curves, & application objects: part 02

25
MobAppDev Circular Motion, Sinusoid Curves, & Application Objects Part 02 Vladimir Kulyukin www.vkedco.blogspot.com

Upload: vladimir-kulyukin

Post on 14-Dec-2014

70 views

Category:

Technology


3 download

DESCRIPTION

 

TRANSCRIPT

  • 1. MobAppDev Circular Motion, Sinusoid Curves, & Application Objects Part 02 Vladimir Kulyukin www.vkedco.blogspot.com
  • 2. Outline Circular Motion Application Application Objects Using Application Objects to Pass Data between Activities Circles as Runnables
  • 3. Circular Motion Application
  • 4. Circular Motion Application In Part 01 of this lecture series, we started to develop an application that models circular motion with sinusoids and covered some basic math behind harmonics and circular motion Recall that the application rotates four circles (red, blue, magenta, and yellow) of specific radii on the left side of the custom view and translates their circular motion into the corresponding sinusoids displayed on the right side of the view The user can control which circles are displayed and the amplitude of each circle through a different activity Source code is at https://github.com/VKEDCO/CircularMotion
  • 5. Main Activity Main screen with a customized view. The left side models four rotating circles. The right side translates the motion of each rotating circle into a corresponding sinusoid.
  • 6. Main Activity's Layout All graphics is done within the custom view implemented in CircularMotionPainterView.java. Note that it is the only view in the layout. It does not really matter in this case whether the main layout is RelativeLayout.
  • 7. Options Menu Menu option Tuneup that allows the user to tune up which circles are displayed and the circle's amplitudes.
  • 8. Options Menu The options menu of the main activity has only one item that calls the tuneup activity implemented in CircularMotionTuneupAct.java.
  • 9. Passing Data to Tuneup Activity public boolean onOptionsItemSelected(MenuItem item) { int id = item.getItemId(); if (id == R.id.action_tuneup) { Intent tuneupIntent = new Intent(this, CirclarMotionTuneupAct.class); tuneupIntent.putExtra(mRes.getString(R.string.is_red_circle_displayed), mApp.isRedCircleDisplayed()); tuneupIntent.putExtra(mRes.getString(R.string.is_blue_circle_displayed), mApp.isBlueCircleDisplayed()); tuneupIntent.putExtra(mRes.getString(R.string.is_magenta_circle_displayed), mApp.isMagentaCircleDisplayed()); tuneupIntent.putExtra(mRes.getString(R.string.is_yellow_circle_displayed), mApp.isYellowCircleDisplayed()); tuneupIntent.putExtra(mRes.getString(R.string.max_amp), (int)mPainterView.getRhoMax()); tuneupIntent.putExtra(mRes.getString(R.string.red_amp), (int)mPainterView.getRedRho()); tuneupIntent.putExtra(mRes.getString(R.string.blue_amp), (int)mPainterView.getBlueRho()); tuneupIntent.putExtra(mRes.getString(R.string.magenta_amp), (int)mPainterView.getMagentaRho()); tuneupIntent.putExtra(mRes.getString(R.string.yellow_amp), (int)mPainterView.getYellowRho()); this.startActivity(tuneupIntent); return true; } return super.onOptionsItemSelected(item); } The necessary data for the tuneup activity is passed via an Intent. Note that mApp refers to the Application object. More on it later.
  • 10. Tuneup Activity Tuneup activity starts with an explicit intent from the main activity, as shown on the previous slide. The radio buttons allow the user to control which circles are displayed. The seek bars allow the user to control the amplitude (radius) of each circle.
  • 11. Tuneup Activity Quiz Which widgets does this layout consist of?
  • 12. Tuneup Activity It is a LinearLayout that contains four check boxes and a TableLayout with four rows. Each row consists of a TextView and a SeekBar. Check motion_circle_tuneup.xml for details.
  • 13. Tuneup Activity The user unchecks the magenta circle, sets the amplitude of the red circle to 41, and clicks Confirm. As the user manipulates the widgets the appropriate member variables are set in the Application object.
  • 14. Tuneup Activity @Override public void onStopTrackingTouch(SeekBar seekBar) { switch ( seekBar.getId() ) { case R.id.sbRedCircleAmp: mApp.setRedAmp(seekBar.getProgress()); break; case R.id.sbBlueCircleAmp: mApp.setBlueAmp(seekBar.getProgress()); break; case R.id.sbMagentaCircleAmp: mApp.setMagentaAmp(seekBar.getProgress()); break; case R.id.sbYellowCircleAmp: mApp.setYellowAmp(seekBar.getProgress()); break; } } Here is an example of how the application object is used to pass data between activities. When the user is done interacting with a specific SeekBar, an appropriate member is set to a specific amplitude. For example, mApp.setRedAmp(seekBar.getProgress()) sets the value of the red circle's amplitude in the application object mApp.
  • 15. Tuneup Activity mYellowCircleCheckBox.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { if ( ((CheckBox) v).isChecked() ) { mApp.setYellowCircleDisplayed(true); } else { mApp.setYellowCircleDisplayed(false); } }}); Check buttons are used to modify the application object's state reflecting which circles are displayed. When the user interacts with a checkbox widget, an appropriate boolean member variable is set in the application object mApp. In the above code snippet, the user check/unchecks the Yellow Circle Check Box mYellowCircleCheckBox and the appropriate member variable is set to true or false.
  • 16. Main Activity Modified The main activity is displayed again after the the Confirm button is pressed. The magenta circle is no longer displayed. The red circle's amplitude is now 41, as shown in the red rotating circle's modified amplitude on the left and the corresponding red sinusoid on the right. These values were passed to the main activity's view via the application object.
  • 17. Application Object
  • 18. Application Objects All activities within one application share the Application object Each activity can obtain that object via getApplication() An application can extend the Application class and request Android to create the object of that class when the application starts The custom Application subclass can, if & when necessary, create arbitrarily complex data structures that can be accessed by each activity for data transfers
  • 19. Extended Application Class public class CircularMotionApp extends Application { static enum CIRCLE_COLOR { RED, BLUE, MAGENTA, GRAY }; CircularMotionPainterView mPainterView = null; boolean mIsRedCircleDisplayed = true; boolean mIsBlueCircleDisplayed = true; boolean mIsMagentaCircleDisplayed = true; boolean mIsYellowCircleDisplayed = true; int mRedAmp = 0; int mBlueAmp = 0; int mMagentaAmp = 0; int mYellowAmp = 0; // rest of code } The custom application class is implemented in CircularMotionApp.java. It has member variables for each data type that must be passed back and forth between activities.
  • 20. Application Class Declaration The custom application class must be declared in AndroidManifest.xml under the application node as the value of the attribute android:name if you want Android to create the custom application object when your application starts. If it is not declared, the default application object will be created that will not have the data you want.
  • 21. Circles as Runnables
  • 22. Circles & Threads Rotating circles are implemented via Threads Each circle changes its position on the screen However, the drawing of circles must be synchronized to ensure that the position of each rotating circle corresponds to the position of its counterpart traveling on the corresponding sinusoid This can be done with thread synchronization
  • 23. Runnable that Moves Circles class UnsynchronizedPainterRunnable implements Runnable { Circle mCircle = null; boolean mThreadRunning = false; public UnsynchronizedPainterRunnable(Circle c) { mCircle = c; } @Override public void run() { mThreadRunning = true; while ( mThreadRunning ) { ((RotatingCircle) mCircle).move(); try { // Have the thread sleep Thread.sleep(CircularMotionMainActivity.SLEEP_INTERVAL); } catch (InterruptedException e) { e.printStackTrace(); mThreadRunning = false; } } } } While the thread is running, the circle object stored in mCircle is cast into RotatingCircle (implemented in RotatingCircle.java)and moved (i.e., rotated a specific amount around the coordinate center on the left of the custom view). The thread then goes to sleep. This class is an inner class of CircularMotionMainActivity.java.
  • 24. Runnable that Moves Circles public class CircularMotionMainActivity extends Activity { ArrayList mCircleThreads = null; protected void onCreate(Bundle savedInstanceState) { mCircleThreads = new ArrayList(); startUnsynchronizedThreads(); } private void startUnsynchronizedThreads() { Thread th = null; for(Circle c: mPainterView.getCircles()) { th = new Thread(new UnsynchronizedPainterRunnable(c)); mCircleThreads.add(th); th.start(); } } The main activity creates an ArrayList of Threads. The onCreate() method of the main activity starts the threads and adds them to the ArrayList of Threads.
  • 25. To Be Continued