Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Basic UI elements: Android Buttons (Basics) Marco Ronchetti Università degli Studi di Trento Let’s work with the listener Button button = …; button.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { Log.d("TRACE", "Button has been clicked "); } Anonymous }); Inner Class In Swing it was JButton button=… button.addActionListener (new ActionListener() { public void actionPerformed(ActionEvent e) { 2 …; } }); Let’s work with the listener Button button = …; button.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { Log.d("TRACE", "Button has been clicked "); The event target } Is passed }); MAIN DIFFERENCE In Swing it was 3 JButton button=… button.addActionListener (new ActionListener() { public void actionPerformed(ActionEvent e) { …; } }); The event is passed An alternative The various View classes expose several public callback methods that are useful for UI events. These methods are called by the Android framework when the respective action occurs on that object. For instance, when a View (such as a Button) is touched, the onTouchEvent() method is called on that object. However, in order to intercept this, you must extend the class and override the method. 4 Extending Button to deal with events Class MyButton extends Button { public boolean onTouchEvent(MotionEvent event) { int eventaction = event.getAction(); switch (eventaction) { case MotionEvent.ACTION_DOWN: // finger touches the screen …; break; case MotionEvent.ACTION_MOVE: // finger moves on the screen …; break; 5 case MotionEvent.ACTION_UP: // finger leaves the screen …; break; } // tell the system that we handled the event and no further processing is needed return true; } SimpleClick 6 Let’s recap how to build an app 1) Define the Activity Resources 1) 2) 3) 2) 3) 7 Choose a Layout Add the components via XML Define the strings Code the activity Add info to the Manifest (if needed) UML Diagram Activity Layout 2 TextView Button TextView String String setTitle() String 8 Let’s define the aspect of layout1 9 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android= "http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello" /> <Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/button1_label" /> <TextView android:id="@+id/tf1" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/output" /> </LinearLayout> Let’s define the strings <?xml version="1.0" encoding="utf-8"?> <resources> <string name="hello">This is Activity A1</string> <string name="app_name">SimpleClick</string> <string name="button1_label">Click me!</string> <string name="output">no results yet...</string> </resources> 10 SimpleClick – A1 package it.unitn.science.latemar; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.TextView; public class A1 extends Activity { int nClicks=0; protected void onCreate(Bundle b) { super.onCreate(b); setContentView(R.layout.layout1); final Button button = (Button) findViewById(R.id.button1); final TextView tf = (TextView) findViewById(R.id.tf1); button.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { tf.setText("Clicks :"+(++nClicks)); } }); 11 } } Calling Activities: Explicit Intents Marco Ronchetti Università degli Studi di Trento startActivity(Intent x) startActivity(Intent x) (method of class Activity) 13 • starts a new activity, which will be placed at the top of the activity stack. • takes a single argument which describes the activity to be executed. • An intent is an abstract description of an operation to be performed. A simple example: A1 calls A2 14 Explicit Intents We will use the basic mode: “Explicit starting an activity” Explicit Intents specify the exact class to be run. Often these will not include any other information, simply being a way for an application to launch various internal activities it has as the user interacts with the application. 15 Intent The context of the sender The class to be activated new Intent(Context c, Class c); Remember that a Context is a wrapper for global information about an application environment, and that Activity subclasses Context 16 Equivalent form: Intent i=new Intent(); i.setClass(Context c1, Class c2); Let’s define the aspect of layout1 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android= "http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/activity1HelloString" /> <Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/button1Label" /> 17 </LinearLayout> Let’s define the strings <?xml version="1.0" encoding="utf-8"?> <resources> <string name="activity2HelloString">This is Activity TWO</string> <string name="app_name">ButtonActivatedActions</string> <string name="activity1HelloString">This is Activity ONE</string> <string name="button1Label">Call Activity TWO</string> <string name="button2Label">Call Activity ONE</string> 18 </resources> A1 and A2 package it.unitn.science.latemar; package it.unitn.science.latemar; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.Button; public class A1 extends Activity { protected void onCreate(Bundle icicle) { super.onCreate(icicle); public class A2 extends Activity { protected void onCreate(Bundle icicle) { super.onCreate(icicle); setContentView(R.layout.layout1); final Button button = (Button) findViewById( R.id.button1); button.setOnClickListener( new View.OnClickListener() { public void onClick(View v) { Intent intent = new Intent(A1.this, A2.class); startActivity(intent); } Anonymous }); } } 19 setContentView(R.layout.layout2); final Button button = (Button) findViewById( R.id.button2); button.setOnClickListener( new View.OnClickListener() { public void onClick(View v) { Intent intent = new Intent(A2.this, A1.class); startActivity(intent); } }); Inner Class } } A1.this ? What’s that? button.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { Intent intent = new Intent(A1.this, A2.class); startActivity(intent); } }); final Activity me=this; button.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { Intent intent = new Intent(me, A2.class); startActivity(intent); } }); 20 final Intent intent = new Intent(this, A2.class); button.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { startActivity(intent); } }); Let’s declare A2 in the manifest <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="it.unitn.science.latemar" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="13" /> <application android:icon="@drawable/ic_launcher" android:label="@string/app_name" > <activity android:name="A1" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name="A2"></activity> </application> 21 </manifest> How many instances? Marco Ronchetti Università degli Studi di Trento How many instances? BACK BACK BACK BACK 23 public class A1 extends Activity { static int instances = 0; TextView tf = null; protected void onCreate(Bundle icicle) { super.onCreate(icicle); instances++; setContentView(R.layout.layout1); tf = (TextView) findViewById(R.id.instanceCount); final Button button = (Button) findViewById(R.id.button1); final Intent intent = new Intent(this, A2.class); button.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { protected void onDestroy() { startActivity(intent); super.onDestroy(); }}); instances--; } } The code protected void onResume() { super.onResume(); if (tf != null) tf.setText("Instance count: A1 = " + A1.instances+" - count A2 = " + A2.instances); } 24 } Activity lifecycle States (colored), and Callbacks (gray) 25 The xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/activity1HelloString" /> <Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/button1Label" /> <TextView android:id="@+id/instanceCount" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/instanceCount" /> 26 </LinearLayout> <?xml version="1.0" encoding="utf-8"?> <resources> <string name="activity2HelloString"> This is Activity TWO</string> <string name="app_name"> ButtonActivatedActions</string> <string name="activity1HelloString"> This is Activity ONE</string> <string name="button1Label"> Call Activity TWO</string> <string name="button2Label"> Call Activity ONE</string> <string name="instanceCount"> Instance count: field not initialized</string> <string name="instanceCount2"> Instance count: field not initialized</string> </resources> Minimizing instances protected void onCreate(Bundle icicle) { super.onCreate(icicle); instances++; setContentView(R.layout.layout2); tf2 = (TextView) findViewById(R.id.instanceCount2); final Button button = (Button) findViewById(R.id.button2); final Intent intent = new Intent(this, A1.class); intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); button.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { startActivity(intent); } }); } 27 BACK FLAG_ACTIVITY_CLEAR_TOP senza FLAG_ACTIVITY_CLEAR_TOP A B C D con FLAG_ACTIVITY_CLEAR_TOP (C e D vengono distrutte) 28 B For details see http://developer.android.com/reference/android/content/Intent.html#FLAG_ACTIVITY_BROUGHT_TO_FRONT FLAGS 29 Calling Activities with return values: startActivityForResults Marco Ronchetti Università degli Studi di Trento Returning data 31 Calling activity package it.unitn.science.latemar; import … public class CallingActivity extends Activity { int requestCode=100; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.layout1); final Intent i = new Intent(this,CalledActivity.class); final Button button = (Button) findViewById(R.id.invokebutton); button.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { startActivityForResult(i, requestCode); } }); } 32 } protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); final TextView tf = (TextView) findViewById(R.id.output); if (resultCode==1){ tf.setText(data.getStringExtra("payload")); } else{ tf.setText("Action cancelled"); } } The name should be qualified with the package Called activity 33 package it.unitn.science.latemar; import … public class CalledActivity extends Activity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.layout2); final Intent in = new Intent(); final Button button = (Button) findViewById(R.id.OKbutton); final EditText tf = (EditText) findViewById(R.id.editText1); button.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { setResult(1,in); in.putExtra("payload", tf.getText().toString()); finish(); The name should be } }); qualified with the package final Button button_c = (Button) findViewById(R.id.cancelButton); button_c.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { setResult(0,in); finish(); } }); } } Remember to register the Activity! 34 <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="it.unitn.science.latemar" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="13" /> <application android:icon="@drawable/ic_launcher" android:label="@string/app_name" > <activity android:name=".CallingActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name="CalledActivity"></activity> </application> </manifest> Extras setExtra(String name, #TYPE# payload) where #TYPE# = one of • Primitive data types • String or various types of serializable objects get…Extra(String name) where … is the name of the data types available in getters removeExtra(String name) 35 replaceExtra completely replace the Extras Basic UI elements: Views and Layouts, a deeper insight Marco Ronchetti Università degli Studi di Trento Widgets examples 37 See http://developer.android.com/resources/tutorials/views/index.html Layout examples 38 Defining layouts in XML Each layout file must contain exactly one root element, which must be a View or ViewGroup object. Once you've defined the root element, you can add additional layout objects or widgets as child elements to gradually build a View hierarchy that defines your layout. 39 A view of the Views View View Stub ViewGroup Absolute Layout Analog Clock Frame Layout Surface View Texture View Keyboard View Grid Layout Space Progress Bar Image View Linear Layout Text View Relative Layout Digital Clock Edit Text Button Scroll View Calendar View TimePicker Media Controller Compound Button 40 And several more… Toggle Button Switch Radio Button Check Box invisible, zero-sized View that can be used to lazily inflate layout resources at runtime. used to display a content stream a dedicated drawing surface a progress bar A view of the Views View View Stub ViewGroup Analog Clock analogic with Absolute clockFrame Layout two hands Layout for hours and minutes Scroll View Calendar View Surface View Texture View Keyboard View Grid a keyboard Layout Space Progress Bar Image View used to create gaps Linear between Layout components TimePicker Displays text to the user and optionally allows them to edit it. Text View Displays an arbitrary Relative image, such Layout as an icon. Media Controller Digital Clock Edit Text Button Compound Button 41 And several more… Toggle Button Switch Radio Button Check Box A view of the Views PLEASE READ THIS: http://developer.android.com/reference/android/widget/package-summary.html View View Stub ViewGroup Absolute Layout Analog Clock Surface View Texture View Keyboard View Frame Layout Grid Layout Space Progress Bar Image View Like AnalogClock, but digital. Text View An editable TextView Linear Layout Relative a pushbutton Layout A button with two states Scroll View 42 And Calendar View TimePicker two-state toggle switch widget that can select several more… between two options. Displays checked/ unchecked states as a button Toggle Button Media Controller Switch Digital Clock Edit Text Button Compound Button Radio Button Check Box Android vs. Swing architectures View Component ViewGroup Layout Container Layout 43 A view of the Views View View Stub block out an area on the Analog screen to display a single ViewGroup Clock item Absolute Layout Frame Layout Surface View Keyboard View Texture View Progress Bar arranges its children in a single column or Image Space a single row.View Grid Layout Linear Layout Text View Relative Layout Digital Clock Edit Text Button places its A layout that lets you specify exact Scrolllocations Calendar children in a TimePicker rectangular (x/y coordinates) View of its View grid. children 44 DEPRECATED! the positions of the children Media can be described in relation to each other or to the Compound Controller parent.. Button And several more… Toggle Button Switch Radio Button Check Box A view of the Views View View Stub calendar widget Analog for displaying and ViewGroup selectingClock dates container for a view hierarchy Absolute that can be Layout scrolled Scroll View Frame Layout Calendar View Surface View Texture View Keyboard View A view for selectingGrid the time of day, Layout Space Progress Bar Image View A view containing Linear controls for a MediaPlayer Layout Text View Relative Layout Digital Clock Edit Text Button TimePicker Media Controller Compound Button 45 And several more… Toggle Button Switch Radio Button Check Box Layout examples See several examples in http://luca-petrosino.blogspot.com/2011/03/android-view-e-layout.html We quickly discuss some of them here. 46 Layout properties - horizontal <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="fill_parent"> <Button android:text="Invia" android:id="@+id/Button1" android:layout_width="wrap_content" android:layout_height="wrap_content”/> <Button android:text="Cancella" android:id="@+id/Button2" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </LinearLayout> 47 Layout properties - margin 48 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="fill_parent"> <Button android:text="Invia" android:id="@+id/Button1" android:layout_width="wrap_content" android:layout_height="wrap_content” android:layout_marginLeft="25px" android:layout_marginRight="25px"/> <Button android:text="Cancella" android:id="@+id/Button2" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </LinearLayout> Layout properties – fill_parent <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation=”horizontal" android:layout_width="fill_parent" android:layout_height="fill_parent"> <Button android:text="Invia" android:id="@+id/Button1" android:layout_width="fill_parent" android:layout_height="wrap_content"/> <Button android:text="Cancella" android:id="@+id/Button2" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </LinearLayout> 49 Layout properties – weight 50 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation=”horizontal" android:layout_width="fill_parent" android:layout_height="fill_parent"> <Button android:text="Invia" android:id="@+id/Button1" android:layout_width="fill_parent" android:layout_height="wrap_content” android:layout_weight="1"/> <Button android:text="Cancella" android:id="@+id/Button2" android:layout_width="fill_parent" android:layout_height="wrap_content” android:layout_weight=“2"/> </LinearLayout> Layout properties - vertical <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <Button android:text="Invia" android:id="@+id/Button1" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <Button android:text="Cancella" android:id="@+id/Button2" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </LinearLayout> 51 Basic operations on View 52 • Set properties: e.g. setting the text of a TextView (setText()). Available properties, getters and setters vary among the different subclasses of views. Properties can also be set in the XML layout files. • Set focus: Focus is moved in response to user input. To force focus to a specific view, call requestFocus(). • Set up listeners: e.g. setOnFocusChangeListener (android.view.View.OnFocusChangeListener). View subclasses offer specialized listeners. • Set visibility: You can hide or show views using setVisibility(int). (One of VISIBLE, INVISIBLE, or GONE.) Invisible, but it still takes up space for layout purposes Invisible, and it takes no space for layout purposes Size and location of a View Although there are setters for posizition and size, theyr values are usually controlled (and overwritten) by the Layout. 53 • getLeft(), getTop() : get the coordinates of the upper left vertex. • getMeasuredHeight() e getMeasuredWidth() return the preferred dimensions • getWidth() e getHeight() return the actual dimensions. Custom views To implement a custom view, you will usually begin overriding for some of the standard methods that the framework calls on all views (at least onDraw()). For more details, see http://developer.android.com/reference/android/ view/View.html 54