This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
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.