This shows you the differences between two versions of the page.
|
mdad:laboratoare:04 [2020/10/07 13:55] 127.0.0.1 external edit |
mdad:laboratoare:04 [2020/12/03 08:14] (current) ioana_maria.culic [Exercises :] |
||
|---|---|---|---|
| Line 1: | Line 1: | ||
| - | ===== Laboratorul 04. ===== | + | ===== Lab 04 - Intents ===== |
| + | **Intents** \\ | ||
| - | **Grid Layout**\\ | + | An Intent is a messaging object you can use to request an action from another app component. Although intents facilitate communication between components in several ways, there are three fundamental use cases:\\ |
| - | The grid is composed of a set of infinitely thin lines that separate the viewing area into cells. Throughout the API, grid lines are referenced by grid indices. A grid with N columns has N + 1 grid indices that run from 0 through N inclusive. Regardless of how GridLayout is configured, grid index 0 is fixed to the leading edge of the container and grid index N is fixed to its trailing edge (after padding is taken into account). \\ | + | - Launch an activity\\ |
| - | + | - Launch a service\\ | |
| - | The number of rows and columns within the grid can be declared using the** android:rowCount** and **android:columnCount** properties. Typically, however, if the number of columns is declared the GridLayout will infer the number of rows based on the number of occupied cells making the use of the rowCount property unnecessary. | + | - Deliver a broadcast\\ |
| - | + | ||
| - | Similarly, the orientation of the GridLayout may optionally be defined via the **android:orientation** property. The following example XML declares a 2 x 2 GridLayout configuration in horizontal orientation: \\ | + | |
| - | <GridLayout xmlns:android="http://schemas.android.com/apk/res/android" | + | |
| - | xmlns:tools="http://schemas.android.com/tools" | + | |
| - | android:id="@+id/GridLayout1" | + | |
| - | android:layout_width="wrap_content" | + | |
| - | android:layout_height="wrap_content" | + | |
| - | android:columnCount="2" | + | |
| - | android:rowCount="2" | + | |
| - | android:orientation="horizontal"> | + | |
| - | </GridLayout> | + | |
| \\ | \\ | ||
| - | Child views can be added to a GridLayout by declaring the elements within the <GridLayout> structure in the XML file. If no row and column values are declared for a child it is positioned automatically by the GridLayout class based on the configuration of the layout and the position of the view in the XML file.\\ | + | An Activity represents a single screen in an app. You can start a new instance of an Activity by passing an Intent to startActivity(). The Intent describes the activity to start and passes any necessary data.\\ |
| - | A view can be placed within a specific cell by specifying the intersecting row and column number of the destination cell. The following Button view will be placed in the cell and row 1, column 2 of the parent GridLayout: \\ | + | |
| - | <Button | + | |
| - | android:id="@+id/button" | + | |
| - | android:layout_column="2" | + | |
| - | android:layout_row="1" | + | |
| - | android:text="Button" /> | + | |
| \\ | \\ | ||
| - | More info : https://developer.android.com/reference/android/widget/GridLayout.html\\ | + | {{:dapm:laboratoare:lab3_intent.png?500|}}\\ |
| - | + | How an implicit intent is delivered through the system to start another activity:\\ | |
| - | ====== Exercises ====== | + | [1] Activity A creates an Intent with an action description and passes it to startActivity().[2] The Android System searches all apps for an intent filter that matches the intent. When a match is found, [3] the system starts the matching activity (Activity B) by invoking its onCreate() method and passing it the Intent. \\ |
| - | **X & 0 GAME**\\ | + | |
| - | Download the next 3 image and add them in your new project in the res/drawable folder (copy - paste) or create your own models: \\ | + | |
| - | (back.png, zero.png and x.png) \\ | + | |
| - | {{:mdad:laboratoare:lab4_back.png?150|}} | + | |
| - | {{:mdad:laboratoare:lab4_zero.png?150|}} | + | |
| - | {{:mdad:laboratoare:lab4_x.png?150|}} | + | |
| \\ | \\ | ||
| - | + | Example to start an activity\\ | |
| - | ** For this lab do not use the design from xml, use only the text ! **\\ | + | Intent intent= new Intent(this, SecondClass.class); |
| - | ** Understand the code, at the end of the lab, the assistant will ask you questions ! ** | + | startActivity(intent); |
| \\ | \\ | ||
| + | **Extras**\\ | ||
| + | Key-value pairs that carry additional information required to accomplish the requested action. Just as some actions use particular kinds of data URIs, some actions also use particular extras.\\ | ||
| \\ | \\ | ||
| - | **Ex 1 ** Make a new project, and using the next xml, positionate another 8 image in the grid layout (in the empty spaces), following the next example: \\ | + | Example: send a string to the secondActivity\\ |
| - | **Attention !** [ImageView] The tag value and the index from the id shoud be the same !\\ | + | //In the firstActivity |
| - | Change the column, row, marginLeft and marginRight value (if necessary). | + | Intent i = new Intent(FirstActivity.this, SecondActivity.class); |
| - | \\ | + | String strName = "Lab3 is great!"; |
| - | <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" | + | i.putExtra("STRING_I_NEED", strName); |
| - | xmlns:tools="http://schemas.android.com/tools" | + | |
| - | android:layout_width="match_parent" | + | //In the secondActivity |
| - | android:layout_height="match_parent"> | + | public void onCreate(Bundle savedInstanceState) { |
| - | <GridLayout | + | super.onCreate(savedInstanceState); |
| - | android:id="@+id/gridLayout" | + | setContentView(R.layout.secondactivity); |
| - | android:layout_width="match_parent" | + | |
| - | android:layout_height="360dp" | + | Intent intent = getIntent(); |
| - | android:background="@drawable/back" | + | Bundle extras = intent.getExtras(); |
| - | android:columnCount="3" | + | if(extras != null) { |
| - | android:rowCount="3"> | + | String getString= extras.getString("STRING_I_NEED"); |
| - | + | } | |
| - | <ImageView | + | |
| - | android:id="@+id/imageView0" | + | |
| - | android:tag="0" | + | |
| - | android:layout_width="90dp" | + | |
| - | android:layout_height="90dp" | + | |
| - | android:layout_marginLeft="20dp" | + | |
| - | android:layout_marginTop="10dp" | + | |
| - | android:layout_column="0" | + | |
| - | android:layout_row="0" | + | |
| - | android:onClick="dropIn"/> | + | |
| - | + | ||
| - | </GridLayout> | + | |
| - | </RelativeLayout> | + | |
| - | + | ||
| - | **Ex 2 ** We can see that anything can be a button. In our case, ImageView is a button, and then an image is clicked, //dropIn// method is called. Let's implement the method in our main java class \\ | + | |
| - | Copy these variable in the MainActivity class (under the class declaration, not in the onCreate method) | + | |
| - | // 0 = x, 1 = o | + | |
| - | int activePlayer = 0; | + | |
| - | boolean gameIsActive = true; | + | |
| - | // 2 unplayed | + | |
| - | int[] gameState = {2, 2, 2, 2, 2, 2, 2, 2, 2}; | + | |
| - | int[][] winningPositions = {{0,1,2}, {3,4,5}, {6,7,8}, {0,3,6}, {1,4,7}, {2,5,8}, {0,4,8}, {2,4,6}}; | + | |
| - | \\ | + | |
| - | **Copy the function in your main class and insert your code only where the TODO is** | + | |
| - | \\ | + | |
| - | public void dropIn(View view) { | + | |
| - | ImageView counter = (ImageView) view; | + | |
| - | // get the current Image View (counter tag) | + | |
| - | int tappedCounter = Integer.parseInt(counter.getTag().toString()); | + | |
| - | | + | |
| - | //if the space is empty(is 2) and the game is not over | + | |
| - | if (gameState[tappedCounter] == 2 && gameIsActive) { | + | |
| - | //set the current player | + | |
| - | gameState[tappedCounter] = activePlayer; | + | |
| - | if (activePlayer == 0) { | + | |
| - | // setImageResource for counter as x | + | |
| - | // TODO | + | |
| - | // change the player's turn | + | |
| - | activePlayer = 1; | + | |
| - | } else { | + | |
| - | // setImageResource for counter as zero | + | |
| - | // TODO | + | |
| - | activePlayer = 0; | + | |
| - | } | + | |
| - | for (int[] winningPosition : winningPositions) { | + | |
| - | if (gameState[winningPosition[0]] == gameState[winningPosition[1]] && | + | |
| - | gameState[winningPosition[1]] == gameState[winningPosition[2]] && | + | |
| - | gameState[winningPosition[0]] != 2) { | + | |
| - | // Someone has won! | + | |
| - | gameIsActive = false; | + | |
| - | String winner = "Player1 -> 0"; | + | |
| - | + | ||
| - | if (gameState[winningPosition[0]] == 0) { | + | |
| - | winner = "Player2 -> x"; | + | |
| - | } | + | |
| - | // Make a toast with the messaje winner + " has won!" | + | |
| - | //TODO | + | |
| - | } else { | + | |
| - | boolean gameIsOver = true; | + | |
| - | + | ||
| - | for (int counterState : gameState) { | + | |
| - | if (counterState == 2) | + | |
| - | gameIsOver = false; | + | |
| - | } | + | |
| - | if (gameIsOver) { | + | |
| - | // Make a toast with the messaje "It's a draw!" | + | |
| - | //TODO | + | |
| - | } | + | |
| - | } | + | |
| - | } | + | |
| - | } | + | |
| } | } | ||
| - | + | ||
| - | **Ex 3 ** In the xml file, in the relative layout, add a linear layout (layout_width="wrap_content", layout_height="wrap_content", visibility="invisible", orientation="vertical", center it //vertical// and //horizontal// and add a //padding// (can be 20 dp). | + | You can add extra data with various putExtra() methods, each accepting two parameters: the key name and the value. You can also create a Bundle object with all the extra data, then insert the Bundle in the Intent with putExtras(). |
| - | Change its color (NOT WHITE). | + | |
| \\ | \\ | ||
| - | In the LinearLayout add a TextView and a Button (both with width and height "wrap_content" and with layout_gravity= "center_horizontal" ). Add for the TextView and the Button a proper id. | ||
| - | \\ | ||
| - | |||
| - | **Ex 4 ** Instead of the toasts that you've done to show the result, set the text from TextView with the message from the toast.\\ | ||
| - | Make the LinearLayout visible. | ||
| \\ | \\ | ||
| + | When you use an implicit intent, the Android system finds the appropriate component to start by comparing the contents of the intent to the intent filters declared in the **manifest file** of other apps on the device. If the intent matches an intent filter, the system starts that component and delivers it the Intent object. | ||
| - | **Ex 5 ** When the button from the Linear Layout is pressed, call the "playAgain" function.\\ | + | __Activity example from a manifest file__\\ |
| - | Create a method named "playAgain" in the main class. Reset the gameState, the gameIsActive and the activePlayer variables.\\ | + | <activity android:name="MainActivity"> |
| - | Make the linear layout invisible.\\ | + | <!-- This activity is the main entry, should appear in app launcher --> |
| - | Go through all the GridLayout children and set their image resource 0.\\ | + | <intent-filter> |
| - | for (int i = 0; i< gridLayout.getChildCount(); i++) { | + | <action android:name="android.intent.action.MAIN" /> |
| - | ((ImageView) gridLayout.getChildAt(i)).setImageResource(0) | + | <category android:name="android.intent.category.LAUNCHER" /> |
| - | } | + | </intent-filter> |
| - | \\ | + | </activity> |
| - | **Ex 6 ** Make a login page for the game like in the last lab. | + | |
| + | <activity android:name="ShareActivity"> | ||
| + | <!-- For example, here's an activity declaration with an intent filter to receive an ACTION_SEND intent when the data type is text: --> | ||
| + | <intent-filter> | ||
| + | <action android:name="android.intent.action.SEND"/> | ||
| + | <category android:name="android.intent.category.DEFAULT"/> | ||
| + | <data android:mimeType="text/plain"/> | ||
| + | </intent-filter> | ||
| + | </activity> | ||
| + | |||
| + | ====== Exercises : ====== | ||
| + | |||
| + | **Ex 1 ** | ||
| + | Make a new project with 2 activities (MainActivity and FindTheNumberActivity. | ||
| + | Add the second activity (FindTheNumberActivity) in the manifest file\\ | ||
| \\ | \\ | ||
| + | **Ex 2 ** | ||
| + | MainActivity will be a login page like in the picture.\\ | ||
| + | Add an action to the button: when clicked, it will check the username and the password field, and if it's __correct__, it will redirect you to the second activity (FindTheNumberActivity). \\ | ||
| + | Set the username and the password to the string __student__.\\ | ||
| + | **Attention !** \\ | ||
| + | You get the text from an editText with "getText()" method, and you convert it to string with "toString()" method.\\ | ||
| + | The password and the username field are editText. And the text from the password field will have to be hidden (add android:inputType="textPassword")\\ | ||
| + | {{:dapm:laboratoare:lab3_login.png?255|}} | ||
| - | **BONUS** (only if you've done the exercises) \\ | + | **Ex 3 ** |
| - | 1. Change the colors and the background images as you like. | + | Create the mini-game like in the picture. If the number is lower, show a toast with the message "Lower", and if it is higher with the message "Higher". If the number is correct, reset the number and show another toast saying "You won! Try again".\\ |
| + | {{:dapm:laboratoare:lab3_findthenumber.png?250|}} | ||
| \\ | \\ | ||
| - | + | **Ex 4 ** | |
| - | REFS:\\ | + | In the FindTheNumberActivity, when the button is clicked, change its color (red<->blue) |
| - | http://www.techotopia.com/index.php/Working_with_the_Android_GridLayout_in_XML_Layout_Resources\\ | + | |
| - | https://developer.android.com/reference/android/widget/GridLayout.html\\ | + | |