This practical codelab is part of Unit 1: Get started in CS3040/DC3040. You will get the most value out of this course if you work through the codelabs in sequence:
The TextView class is a subclass of the View class that displays text on the screen. You can control how the text appears with TextView
attributes in the XML layout file. This practical shows how to work with multiple TextView
elements, including one in which the user can scroll its contents vertically.
If you have more information than fits on the device's display, you can create a scrolling view so that the user can scroll vertically by swiping up or down, or horizontally by swiping right or left.
You would typically use a scrolling view for news stories, articles, or any lengthy text that doesn't completely fit on the display. You can also use a scrolling view to enable users to enter multiple lines of text, or to combine UI elements (such as a text field and a button) within a scrolling view.
The ScrollView class provides the layout for the scrolling view. ScrollView
is a subclass of FrameLayout. Place only one view as a child within it - a child view contains the entire contents to scroll. This child view may itself be a ViewGroup (such as LinearLayout) containing UI elements.
Complex layouts may suffer performance issues with child views such as images. A good choice for a View
within a ScrollView
is a LinearLayout
that is arranged in a vertical orientation, presenting items that the user can scroll through (such as TextView
elements).
With a ScrollView
, all of the UI elements are in memory and in the view hierarchy even if they aren't displayed on screen. This makes ScrollView
ideal for scrolling pages of free-form text smoothly, because the text is already in memory. However, ScrollView
can use up a lot of memory, which can affect the performance of the rest of your app. To display long lists of items that users can add to, delete from, or edit, consider using a RecyclerView, which is described in a separate lesson.
You should be able to:
TextView
in a layout for an app.TextView
elements.View
.TextView
background color and text color.ConstraintLayout
from ViewGroup
to RelativeLayout
.TextView
elements for the article heading and subheading.TextAppearance
styles and colors for the article heading and subheading.lineSpacingExtra
attribute to add line spacing for readability.ScrollView
to the layout to enable scrolling a TextView
element.autoLink
attribute to enable URLs in the text to be active and clickable.The Scrolling Text app demonstrates the ScrollView UI component. ScrollView
is a ViewGroup
that in this example contains a TextView
. It shows a lengthy page of text—in this case, a music album review—that the user can scroll vertically to read by swiping up and down. A scroll bar appears in the right margin. The app shows how you can use text formatted with minimal HTML tags for setting text to bold or italic, and with new-line characters to separate paragraphs. You can also include active web links in the text.
In the above figure, the following appear:
In this practical, you will create an Android project for the ScrollingText app, add TextView
elements to the layout for an article title and subtitle, and change the existing "Hello World" TextView
element to show a lengthy article. The figure below is a diagram of the layout.
You will make all these changes in the XML code and in the strings.xml
file. You will edit the XML code for the layout in the Code pane, which you show by clicking the Code tab, rather than clicking the Design tab for the Design pane. Some changes to UI elements and attributes are easier to make directly in the Code pane using XML source code.
In this task you will create the project and the TextView
elements, and use TextView
attributes for styling the text and background.
Tip: To learn more about these attributes, see the TextView reference.
Attribute | Value |
Template | Empty Activity |
Application Name | Scrolling Text |
Package name |
|
Save location | appropriate folder on your computer |
Language | Java |
Minimum SDK | API 18: Android 4.3 (Jelly Bean) |
Use legacy android.support libraries | Not selected |
activity_main.xml
file, and click the Code tab to see the XML code.View
hierarchy is the ConstraintLayout
ViewGroup:<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
ViewGroup
to RelativeLayout
. The first line of code now looks something like this:<RelativeLayout
RelativeLayout
lets you place UI elements relative to each other, or relative to the parent RelativeLayout
itself.TextView
element created by the Empty Layout template still has constraint attributes (such as app:layout_constraintBottom_toBottomOf="parent"
). Don't worry—you will remove them in a subsequent step. xmlns:app="http://schemas.android.com/apk/res-auto"
The block of XML code at the top now looks like this:<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
TextView
element above the "Hello World" TextView
by entering <TextView. A TextView
block appears that ends with />
and shows the layout_width
and layout_height
attributes, which are required for the TextView
.TextView #1 attribute | Value |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
android:text
attribute's hardcoded string "Article Title"
in the TextView
to create an entry for it in strings.xml
.article_title
.android:padding
attribute's hardcoded string "10dp"
in the TextView
to create dimens.xml
and add an entry to it.padding_regular
.TextView
element above the "Hello World" TextView
and below the TextView
you created in the previous steps. Add the following attributes to the TextView
:TextView #2 Attribute | Value |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"10dp"
string to padding_regular
in the previously created TextView
, you can use "@dimen/padding_regular"
for the android:padding
attribute in this TextView
.android:text
attribute's hardcoded string "Article Subtitle"
in the TextView
to article_subtitle
.TextView
element, delete the layout_constraint
attributes:app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
TextView
attributes to the "Hello World" TextView
element, and change the android:text
attribute:TextView Attribute | Value |
|
|
|
|
|
|
|
|
| Change to |
"Article text"
to article_text
, and extract the dimension
resource for "5sp"
to line_spacing
.In a real app that accesses magazine or newspaper articles, the articles that appear would probably come from an online source through a content provider, or might be saved in advance in a database on the device.
For this practical, you will create the article as a single long string in the strings.xml
resource.
strings.xml
.article_title
and article_subtitle
with either a made-up title and subtitle, or use the values "Beatles Anthology Vol.1"
and "Behind That Locked Door: Beatles Rarities"
respectively. Make the string values single-line text without HTML tags or multiple lines.article_text
string.article_text
string below. The only requirement for this task is that the text must be long enough so that it doesn't fit on the screen.In a vault deep inside Abbey Road Studios in London — protected by an unmarked, triple-locked, police-alarmed door — are something like 400 hours of unreleased Beatles recordings, starting from June 2, 1962 and ending with the very last tracks recorded for the <i>Let It Be</i> album. The best of the best were released by Apple Records in the form of the 3-volume Anthology series.
For more information, see the Beatles Time Capsule at www.rockument.com.
\n\n
This volume starts with the first new Beatle song, "Free as a Bird" (based on a John Lennon demo, found only on <i>The Lost Lennon Tapes Vol. 28</i>, and covers the very earliest historical recordings, outtakes from the first albums, and live recordings from early concerts and BBC Radio sessions.
\n\n
<b>Highlights include:</b>
\n\n
<b><i>Cry for a Shadow</i></b> - Many a Beatle fanatic started down the outtake road, like I did, with a first listen to this song. Originally titled "Beatle Bop" and recorded in a single session that yielded four songs (the other three featured Tony Sheridan with the Beatles as a backing band), "Cry for a Shadow" is an instrumental written by Lennon and Harrison, which makes it unique to this day. John Lennon plays rhythm guitar, George Harrison plays lead guitar, Paul McCartney plays bass, and Pete Best plays drums. The sessions were produced by Bert Kaempfert in Hamburg, Germany, during the Beatles' second visit from April through July of 1961 to play in the Reeperbahn-section clubs.
\n\n
<b><i>My Bonnie</i></b> and <b><i>Ain't She Sweet</i></b> — At the same session, the Beatles played on "My Bonnie" (the first-ever single with Beatles playing), as the backing band for English singer Tony Sheridan, originally a member of the Jets. The popularity of this single in Liverpool brought the Beatles to the attention of Brian Epstein, who worked in the NEMS record store and tried to meet demand for the disc. John Lennon then sings a fine "Ain't She Sweet" (his first-ever released vocal).
\n\n
<b><i>Searchin</i></b> — A Jerry Leiber - Mike Stoller comedy song that was a hit for the Coasters in 1957, and a popular live favorite of the Beatles. The Coasters also had a hit with "Besame Mucho" and the Beatles covered that song as well. Ringo Starr had by now replaced Pete Best on drums. The high falsetto is George, who also plays a hesitant lead guitar. This is from their first audition for Decca Records in London on Jan 1., 1962, live in the studio. The Grateful Dead would later cover "Searchin" with a similar arrangement, Pigpen doing the Paul vocals. A live version is available on outtake records featuring the Dead joined by the Beach Boys!
\n\n
<b><i>Love Me Do</i></b> — An early version of the song, played a bit slower and with more of a blues feeling, and a cool bossa-nova beat in middle. Paul had to sing while John played harmonica — a first for the group. Pete Best played drums on this version.
\n\n
<b><i>She Loves You – Till There Was You – Twist and Shout</i></b> — Live at the Princess Wales Theatre by Leicester Square in London, attended by the Queen. "Till There Was You" (by Meredith Wilson) is from the musical The Music Man and a hit for Peggy Lee in 1961. Before playing it, Paul said it was recorded by his favorite American group, "Sophie Tucker" (which got some laughs). At the end, John tells the people in the cheaper seats to clap their hands, and the rest to "rattle your jewelry" and then announces "Twist and Shout" (a song by Bert Russell and Phil Medley that was first recorded in 1962 by the Isley Brothers). A film of the performance shows the Queen smiling at John's remark.
\n\n
<b><i>Leave My Kitten Alone</i></b> — One of the lost Beatle songs recorded during the "Beatles For Sale" sessions but never released. This song, written by Little Willie John, Titus Turner, and James McDougal, was a 1959 R&B hit for Little Willie John and covered by Johnny Preston before the Beatles tried it and shelved it. A reference to a "big fat bulldog" may have influenced John's "Hey Bulldog" (Yellow Submarine album), which is a similar rocker.
\n\n
<b><i>One After 909</i></b> — A song recorded for the <i>Let It Be</i> album was actually worked on way back in the beginning, six years earlier. This take shows how they did it much more slowly, with an R&B feel to it.
Keep in mind the following (refer to the figure below for an example):
strings.xml
file, the text lines don't wrap around to the next line - they extend beyond the right margin. This is the correct behavior - each new line of text starting at the left margin represents an entire paragraph. If you want the text in strings.xml
to be wrapped, you can press Return to enter hard line endings, or format the text first in a text editor with hard line endings.'
) in your text, you must escape it by preceding it with a backslash (\'
). If you have a double-quote in your text, you must also escape it (\"
). You must also escape any other non-ASCII characters. See the Formatting and styling section of String resources for more details.<b><i>
... words ...</i></b>
. Other HTML tags are ignored.<string name="article_text"> </string>
in the strings.xml
file.Run the app. The article appears, but the user can't scroll the article because you haven't yet included a ScrollView
(which you will do in the next task). Note also that tapping a web link does not currently do anything. You will also fix that in the next task.
The activity_main.xml
layout file looks like the following:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="@+id/article_heading"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/colorPrimary"
android:padding="@dimen/padding_regular"
android:text="@string/article_title"
android:textAppearance="@android:style/TextAppearance.DeviceDefault.Large"
android:textColor="@android:color/white"
android:textStyle="bold" />
<TextView
android:id="@+id/article_subheading"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/article_heading"
android:padding="@dimen/padding_regular"
android:text="@string/article_heading"
android:textAppearance="@android:style/TextAppearance.DeviceDefault" />
<TextView
android:id="@+id/article"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/article_subheading"
android:autoLink="web"
android:lineSpacingExtra="@dimen/line_spacing"
android:padding="@dimen/padding_regular"
android:text="@string/article_text" />
</RelativeLayout>
In the previous task you created the ScrollingText app with TextView
elements for an article title, subtitle, and lengthy article text. You also included a web link, but the link is not yet active. You will add the code to make it active.
Also, the TextView
by itself can't enable users to scroll the article text to see all of it. You will add a new ViewGroup
called ScrollView
to the XML layout that will make the TextView
scrollable.
Add the android:autoLink="web"
attribute to the article TextView
. The XML code for this TextView now looks like this:
<TextView
android:id="@+id/article"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/article_subheading"
android:autoLink="web"
android:lineSpacingExtra="@dimen/line_spacing"
android:padding="@dimen/padding_regular"
android:text="@string/article_text" />
To make a View
(such as a TextView
) scrollable, embed the View
inside a ScrollView
.
ScrollView
between the article_subheading
TextView and the article
TextView. As you enter <ScrollView, Android Studio automatically presents the android:layout_width
and android:layout_height
attributes with suggestions. Choose wrap_content
from the suggestions for both attributes.</ScrollView>
TextView
elements and the ScrollView
now looks like this: <TextView
android:id="@+id/article_subheading"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/article_heading"
android:padding="@dimen/padding_regular"
android:text="@string/article_heading"
android:textAppearance="@android:style/TextAppearance.DeviceDefault" />
<ScrollView
android:layout_width="wrap_content"
android:layout_height="wrap_content"></ScrollView>
<TextView
android:id="@+id/article"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/article_subheading"
android:autoLink="web"
android:lineSpacingExtra="@dimen/line_spacing"
android:padding="@dimen/padding_regular"
android:text="@string/article_text" />
</ScrollView>
code after the articleTextView
so that the article TextView
attributes are entirely inside the ScrollView
.TextView
and add it to the ScrollView
:android:layout_below="@id/article_subheading"
With the above attribute, the ScrollView
element will appear below the article subheading. The article is inside the ScrollView
element.TextView
now appears indented inside the <ScrollView>
element.The layout components are now nested in this arrangement:
To examine how the text scrolls:
android:autoLink
attribute turns any recognizable URL in the TextView
(such as www.rockument.com
) into a web link.
In the above figure, the following appear:
The XML code for the layout with the scroll view is as follows:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="@+id/article_heading"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/colorPrimary"
android:padding="@dimen/padding_regular"
android:text="@string/article_title"
android:textAppearance="@android:style/TextAppearance.DeviceDefault.Large"
android:textColor="@android:color/white"
android:textStyle="bold" />
<TextView
android:id="@+id/article_subheading"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/article_heading"
android:padding="@dimen/padding_regular"
android:text="@string/article_heading"
android:textAppearance="@android:style/TextAppearance.DeviceDefault" />
<ScrollView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/article_subheading">
<TextView
android:id="@+id/article"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:autoLink="web"
android:lineSpacingExtra="@dimen/line_spacing"
android:padding="@dimen/padding_regular"
android:text="@string/article_text" />
</ScrollView>
</RelativeLayout>
As noted before, a ScrollView
can contain only one child View
(such as the article TextView
you created). However, that View
can be another ViewGroup
that contains View
elements, such as LinearLayout
. You can nest a ViewGroup
such as LinearLayout
within the ScrollView
, thereby scrolling everything that is inside the LinearLayout
.
For example, if you want the subheading of the article to scroll along with the article, add a LinearLayout
within the ScrollView
, and move the subheading and article into the LinearLayout
. The LinearLayout
becomes the single child View
in the ScrollView
as shown in the figure below, and the user can scroll the entire LinearLayout
: the subheading and the article.
activity_main.xml
file of the ScrollingText app project, and select the Code tab to edit the XML code (if it is not already selected).LinearLayout
above the article TextView
within the ScrollView
. As you enter <LinearLayout, Android Studio automatically presents the android:layout_width
and android:layout_height
attributes with suggestions. Choose match_parent
and wrap_content
from the suggestions for its width and height, respectively. When you close the opening tag, Android Studio automatically adds </LinearLayout>
to the end. <ScrollView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/article_subheading">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"></LinearLayout>
<TextView
android:id="@+id/article"
You use match_parent
to match the width of the parent ViewGroup
. You use wrap_content
to resize the LinearLayout
so it is just big enough to enclose its contents.
</LinearLayout>
code after the article TextView
but before the closing </ScrollView>
.LinearLayout
now includes the article TextView
, and is completely inside the ScrollView
.android:orientation="vertical"
to the LinearLayout
to set its orientation to vertical. <ScrollView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/article_subheading">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/article"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:autoLink="web"
android:lineSpacingExtra="@dimen/line_spacing"
android:padding="@dimen/padding_regular"
android:text="@string/article_text" />
</LinearLayout>
</ScrollView>
The LinearLayout
now has only one UI element—the article TextView
. You want to include the article_subheading
TextView in the LinearLayout
so that both will scroll.
article_subheading
TextView, select the code, choose Edit > Cut, click above the articleTextView
inside the LinearLayout
, and choose Edit > Paste.android:layout_below="@id/article_heading"
attribute from the article_subheading
TextView. This TextView
is now within the LinearLayout
, so this attribute would conflict with the LinearLayout
attributes.android:layout_below="@id/article_subheading"
to android:layout_below="@id/article_heading"
. Now that the subheading is part of the LinearLayout
, the ScrollView
must be placed below the heading, not the subheading. <ScrollView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/article_heading">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/article_subheading"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="@dimen/padding_regular"
android:text="@string/article_heading"
android:textAppearance="@android:style/TextAppearance.DeviceDefault" />
<TextView
android:id="@+id/article"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:autoLink="web"
android:lineSpacingExtra="@dimen/line_spacing"
android:padding="@dimen/padding_regular"
android:text="@string/article_text" />
</LinearLayout>
</ScrollView>
Swipe up and down to scroll the article, and notice that the subheading now scrolls along with the article while the heading stays in place.
You will be able to find the solution code for the scrolling text app on Blackboard.
Challenge: Add another UI element - a Button
- to the LinearLayout
inside the ScrollView
so that it scrolls with the text.
Button
appear below the article. The user scrolls to the end of the article to see the Button
.Button
element in the proper place in the layout.ScrollView
to scroll a single child View
(such as a TextView
). A ScrollView
can hold only one child View or ViewGroup.ViewGroup
such as LinearLayout
as a child View
within a ScrollView
to scroll more than one View
element. Enclose the elements within the LinearLayout
.TextView
with HTML formatting tags for bold and italics.\n
as an end-of-line character in free-form text to keep a paragraph from running into the next paragraph.android:autoLink="web"
attribute to make web links in the text clickable.The related concept documentation is in 1.3 Text and scrolling views.
Android Studio documentation:
Android developer documentation:
Other:
Android Developers Blog: Linkify your Text!
Codepath: Working with a TextView