|
1 | 1 | # Dynamic Data for Tweet List Screen |
2 | 2 |
|
3 | | -Cool, so we are done storing login data. It is time to handle data for Tweet List Screen. |
| 3 | +We are done storing login data from previous lessons. It is time to handle data for Tweet List Screen. |
4 | 4 |
|
5 | | -In this lesson, each tweet item will have different data. We will create a Tweet model which will store the data corresponding to each tweet. In subsequent lessons, we will learn how to serialize & read/write the Tweet model object array to a local file. |
| 5 | +In this module, we will add the feature - each tweet item should have different data. We will create a Tweet model which will store the data corresponding to each tweet. In subsequent lessons, we will learn how to serialize & read/write the Tweet model object array to a local file. |
6 | 6 |
|
7 | | -##Recap from module 1 |
| 7 | +> In this module, you will going to learn how to access & modify data in a ListView & best practices of storing data using models in Java/Android. |
8 | 8 |
|
9 | | -In module 1, each tweet item had dummy data and its appearance was based on row_tweet.xml. We also created a TweetListAdapter with a `getView()` method which simply inflated the resource xml |
| 9 | +1. <%= link_to "Create Tweet model", app_tutorial_lesson_with_token_path(@app_name, AppLesson.find_by_number(@current_lesson.number + 1).lesson.token) %> - A quick intro on how data models are created in Java & why we need it for our case followed by assignment to actually create it. |
10 | 10 |
|
11 | | -`TweetAdapter.java` |
12 | | - |
13 | | - public class TweetAdapter extends ArrayAdapter { |
14 | | - . |
15 | | - . |
16 | | - @Override |
17 | | - public View getView(int position, View convertView, ViewGroup parent){ |
18 | | - return inflater.inflate(R.layout.row_tweet, parent, false); |
19 | | - } |
20 | | - |
21 | | - } |
22 | | - |
23 | | -Because of the above step, all tweet items looked the same. In real life, each tweet item will hold a different value that comes from the twitter server. Since we are not doing network calls yet, we will populate some dummy but different data. |
24 | | - |
25 | | -The steps we are going to follow :- |
26 | | - |
27 | | -**1. New Tweet model to hold data ** |
28 | | - |
29 | | -Good programming practice in Java mandates that any kind of data should be held in a class. It is also referred as Model of Model View Controller architecture. Consider the Activity classes as Controllers & XML as Views. We will create a new class Tweet.java which will hold the tweet data. |
30 | | - |
31 | | -**2. Populating the Tweet model ** |
32 | | - |
33 | | -In a real Twitter app, data would be fetched from the network. Since we are not doing network call here, we are just going to put some dummy data in our Tweet model. |
34 | | - |
35 | | -**3. Using Tweet model to show data on screen ** |
36 | | - |
37 | | -We are then going to pass the tweet model array to TweetAdapter & change the code to use the model data to show on the screen. |
38 | | - |
39 | | -## Step 1 - Creating Tweet Model |
40 | | - |
41 | | -When we will do network calls to fetch tweets, all the tweets will have uniform structure. Each tweet will have an image, twitter handle, body, date etc. In Java, it is a good practice to create a Java class for this. Such an object is also known as **P**lain **O**ld **J**ava **O**bject (POJO) in Java. We can store multiple tweets as array of the Tweet object. |
42 | | - |
43 | | - |
44 | | -### Assignment - create Tweet model |
45 | | - |
46 | | -** 1. Create Tweet.java ** |
47 | | - |
48 | | -The file needs to be in src -> org -> codelearn -> twitter -> models directory. You can either manually create it or follow the Eclipse steps below. |
49 | | - |
50 | | -* Create new folder |
51 | | - |
52 | | -<div class="row-fluid"> |
53 | | - <div class="span6"> |
54 | | - <%= image_tag "twitter-client/new-folder-src.png" %> |
55 | | - </div> |
56 | | - <div class="span6"> |
57 | | - <%= image_tag "twitter-client/create-folder-src.png" %> |
58 | | - </div> |
59 | | -</div> |
60 | | - |
61 | | -* Create Tweet.java inside org.codelearn.twitter.models |
62 | | - |
63 | | -<div class="row-fluid"> |
64 | | - <div class="span6"> |
65 | | - <%= image_tag "twitter-client/new-class-folder-src.png" %> |
66 | | - </div> |
67 | | - <div class="span6"> |
68 | | - <%= image_tag "twitter-client/create-class-folder-src.png" %> |
69 | | - </div> |
70 | | -</div> |
71 | | - |
72 | | -* This is how the newly created Tweet.java will look |
73 | | - |
74 | | -<%= image_tag "twitter-client/tweet.java.png" %> |
75 | | - |
76 | | -**2. Copy contents to Tweet.java ** |
77 | | - |
78 | | -`Tweet.java` |
79 | | - |
80 | | - package org.codelearn.twitter.models; |
81 | | - |
82 | | - public class Tweet { |
83 | | - private String id; |
84 | | - private String title; |
85 | | - private String body; |
86 | | - |
87 | | - public String getId() { |
88 | | - return id; |
89 | | - } |
90 | | - |
91 | | - public String getTitle() { |
92 | | - return title; |
93 | | - } |
94 | | - |
95 | | - public void setTitle(String title) { |
96 | | - this.title = title; |
97 | | - } |
98 | | - |
99 | | - public String getBody() { |
100 | | - return body; |
101 | | - } |
102 | | - |
103 | | - public void setBody(String body) { |
104 | | - this.body = body; |
105 | | - } |
106 | | - } |
107 | | - |
108 | | -Like a regular POJO , the class has methods to get/set different instance variables of the object of Tweet class. |
109 | | - |
110 | | -## Step 2 - Using Tweet model in TweetListActivity class |
111 | | - |
112 | | -We will be holding a lot of tweets at a given time. So we need an array of Tweet model objects. |
113 | | - |
114 | | - List<Tweet> tweets = new ArrayList<Tweet>(); |
115 | | - |
116 | | -While `List` is a generic array class in java (also called interface), `ArrayList` is simply an array implementation of List interface. Putting a `<Tweet>` typecasts it to an array of our Tweet class. |
117 | | - |
118 | | -Presently, we create random data inside getView() when the user visits the TweetListActivity. Since we've created a new Tweet model, we will iterate over the Tweet objects, get each element's value like header, date, body etc & set the appropriate field in the inflated View. |
119 | | - |
120 | | -We don't have any tweets yet, so`tweets` will be empty. Let's write some code to populate `tweets` with some random data. |
121 | | - |
122 | | - for ( int i = 0; i < 20; i++ ) { |
123 | | - Tweet tweet = new Tweet(); |
124 | | - tweet.setTitle("A nice header for Tweet # " +i); |
125 | | - tweet.setBody("Some random body text for the tweet # " +i); |
126 | | - tweets.add(tweet); |
127 | | - } |
128 | | - |
129 | | -The code above will put 20 Tweet objects in tweets array. |
130 | | - |
131 | | -### Assignment - create & populate tweets array |
132 | | - |
133 | | -Implement the above steps. |
134 | | - |
135 | | -You will need to refer to the tweets array at multiple places inside TweetListActivity class. So you should declare it as member of the TweetListActivity class. |
136 | | - |
137 | | -<div class="alert alert-info"><b>Hint</b>: onCreate() in TweetListActivity.java is the place you should initialize the array with random tweets</div> |
138 | | - |
139 | | -Make sure you add the appropriate import statement |
140 | | - |
141 | | - import org.codelearn.twitter.models.Tweet |
142 | | - |
143 | | -in TweetListActivity.java. Otherwise, Eclipse will not be able to understand that 'Tweet' actually stands for the Tweet class defined elsewhere. |
144 | | - |
145 | | - |
146 | | -## Step 3 - Showing dynamic data through Tweet model object |
147 | | - |
148 | | -Now that we have populated the tweets array, we need to show the data it holds on the screen. |
149 | | - |
150 | | -A quick recap. Data is passed to the ListView through an Adapter. We had the below code in TweetListActivity.java . |
151 | | - |
152 | | -<pre>tweetItemArrayAdapter = new TweetAdapter(this, new String[10]);</pre> |
153 | | - |
154 | | -We were not actually passing any data to the Adapter. Just the size of the String array is used by the Adapter to create 10 tweet entries. Now we will be passing `tweets` array to TweetAdapter which will in-turn be used in getView() method to set the title, body & date in inflated View. |
155 | | - |
156 | | -`TweetListActivity.java` |
157 | | - |
158 | | -<pre>tweetItemArrayAdapter = new TweetAdapter(this, <span class="highlight"><strike>new String[10]</strike> tweets</span>);</pre> |
159 | | - |
160 | | -Also TweetAdapter.java needs to be modified appropriately to accept array of Tweet model as argument. The array is then used in getView(..) to set title, date & body inside the inflated View. |
161 | | - |
162 | | -`TweetAdapter.java` |
163 | | - |
164 | | -<pre>public class TweetAdapter extends ArrayAdapter<span class="highlight"><Tweet></span> { |
165 | | - . |
166 | | - |
167 | | - public TweetAdapter(Activity activity, <span class="highlight"><strike>String[] items</strike> List<Tweet>tweets</span>) { |
168 | | - . |
169 | | - . |
170 | | - } |
171 | | -</pre> |
172 | | - |
173 | | -We also need to modify getView() method to use the tweets array. The method `getView()` returns an object of type View. Before returning the View, the content of the inflated View can be modified by accessing elements of the View using `findViewById()` method and setting the text using `setText(..)`. |
174 | | - |
175 | | -<div class="alert alert-info"><b>Tip</b>: Remember that <b>getView()</b> is called every time a Tweet is to be displayed on screen. Therefore, getView() is an opportunity to retrieve the tweet from the <b>tweets</b> list and set the content of the current Tweet in the header, body etc of the <b>row_tweet.xml</b> </div> |
176 | | - |
177 | | -Example, the code below will inflate row_tweet.xml, look for a TextView with id title_id, sets its text before returning the inflated View. |
178 | | - |
179 | | -`getView() in TweetAdapter.java` |
180 | | -<pre> |
181 | | - <strike>return inflater.inflate(R.layout.row_tweet, parent, false);</strike> |
182 | | - View row = inflater.inflate(R.layout.row_tweet, parent, false); |
183 | | - Tweet currentTweet = tweets.get(position); |
184 | | - TextView title = (TextView) row.findViewById(R.id.title_id); |
185 | | - title.setText(currentTweet.getTitle()); |
186 | | - //Modify the body |
187 | | - return row; |
188 | | -</pre> |
189 | | - |
190 | | - |
191 | | -### Assignment - populate data in TweetAdapter's getView() from tweets array |
192 | | - |
193 | | -Follow the three steps. Create Tweet.java, create a tweets array in TweetListActivity.java, populate it with dummy data & then pass it to TweetAdapter. Modify TweetAdapter to use the tweets array to show its data on the screen. |
194 | | - |
195 | | -<%= image_tag "twitter-client/different-tweets.png" %> |
196 | | - |
197 | | -<div class="alert alert-info"><b>Hint</b>: Store <b>tweets</b> passed to <b>public TweetAdapter(..)</b> in a TweetAdapter member variable. You will need the tweets array in getView(..) but it is passed in the constructor method. See how <b>inflater</b> variable is initialized in the constructor & used in getView(..) & derive inspiration from it.</div> |
| 11 | +2. <%= link_to "Populate the Tweet model & use it in the Activity", app_tutorial_lesson_with_token_path(@app_name, AppLesson.find_by_number(@current_lesson.number + 2).lesson.token) %> - Once the model is created, it is populated & the data with dummy data & the data is shown on the TweetListActivity. |
0 commit comments