Lesson 5 - Supplement 2 - List Based Widgets
Lesson 5 - Supplement 2 - List Based Widgets
• When the set of values to choose from is large, other Android List-Based
Widgets are more appropriate.
2
Showing a large set of choices on the GUI
DATA
Raw data Formatted
& bound
data
DATA
ADAPTER
3
ListViews
4
ArrayAdapter (A Data Beautifier)
5
ArrayAdapter (A Data Beautifier)
textviews…
Array Adapter
object n.toString()
6
Using the ArrayAdapter<String> Class
Parameters:
1. The current activity’s context (this)
2. The TextView layout indicating how an individual row should be
written ( android.R.id.simple_list_item_1 ).
3. The actual data source (array or list containing items to be shown).
7
Example 1: ListView showing a simple list (plain text)
8
Example 1: Layout
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/txtMsg"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#ffffff00"
android:text="Using ListViews..."
android:textSize="16sp" />
<ListView
android:id="@+id/my_list"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</ListView>
</LinearLayout>
9
Example 1: MainActivity
10
When dataset is changed
11
Example1: Custom ListView
You may want to modify the ListView control to use your own GUI design. For
instance, you may replace android.R.layout.simple_list_item_1 with
R.layout.my_custom_text.
Where my_custom_text is the Layout specification listed below (held in the
res/layout folder). It defines how each row is to be shown.
12
Example1: Custom ListView
You may also create the ArrayAdapter with more
parameters. For instance, the following statement:
val adapter: ArrayAdapter<String> = ArrayAdapter(
this,
R.layout.item_view,
R.id.text_item,
items)
Defines a custom list and textview layout to show the
contents of the data array.
<!– item_view -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="6dp" >
<TextView
android:id="@+id/text_item"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#220000ff"
android:padding="1dp"
android:textColor="#ffff0000"
android:textSize="35sp" />
</LinearLayout>
13
The Spinner Widget
• Spinners have the same functionality of a ListView but take less screen
space.
14
Example2: Using the Spinner Widget
A list of options named ‘Data-0’, ‘Data-1’, ‘Data-2’ and so on, should be displayed
when the user taps on the ‘down-arrow’ portion of the spinner.
3. Selected
value
1. Click Drop-
down button
15
Example 2: Layout
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="3dp"
tools:context=".MainActivity" >
<TextView
android:id="@+id/txtMsg"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#ffffff00"
android:text="Spinner selection" />
<Spinner
android:id="@+id/spinner1"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
16
Example 2: MainActivity
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
findViewById<Spinner>(R.id.spinner1).run {
adapter = arrayAdapter
onItemSelectedListener = object : OnItemSelectedListener {
override fun onItemSelected(p0: AdapterView<*>?, p1: View?, p2: Int, p3: Long) {
txtMsg.text = items[p2]
}
override fun onNothingSelected(p0: AdapterView<*>?) {
TODO("Not yet implemented")
}
}
}
}
}
17
The GridView widget
GridView
GridView is a ViewGroup that
displays items in a
two-dimensional, scrollable grid.
18
GridView: Useful Properties
Some properties used to determine the number of columns and their sizes:
• android:numColumns
indicates how many columns to show. When used with option “auto_fit”,
Android determines the number of columns based on available space and
the properties listed below.
• android:columnWidth
column width in dips.
• android:stretchMode
indicates how to modify image size when there is available space not
taken up by columns or spacing .
19
GridView: Fitting the View to the Screen
The user would see three columns taking 310 pixels (three columns of 100
pixels and two separators of 5 pixels).
20
Example 3: GridView Demo - Layout
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/LinearLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="2dp"
tools:context=".MainActivity" >
<TextView
android:id="@+id/txtMsg"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#ff0000ff"
android:textSize="24sp"
android:textStyle="bold"
android:textColor="#ffffffff"
android:padding="2dip" />
<GridView
android:id="@+id/grid"
android:background="#77ffff00"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:verticalSpacing="5dip"
android:horizontalSpacing="5dip"
android:numColumns="auto_fit"
android:columnWidth="100dip"
android:stretchMode="spacingWidth" />
</LinearLayout>
21
Example 3: GridView Demo - MainActivity
findViewById<GridView>(R.id.grid).run {
adapter = arrayAdapter
onItemClickListener = object : OnItemClickListener {
override fun onItemClick(p0: AdapterView<*>?, p1: View?, p2: Int, p3: Long) {
txtMsg.text = items[p2]
}
}
}
}
}
22
The AutoCompleteTextView Widget
• Characters typed so far are compared with the beginning of words held in
a user-supplied list of suggested values.
• The user can choose from the suggestion list or complete typing the
word.
23
The AutoCompleteTextView Widget
Example 4.
A list of selected
words beginning
with “wor” or “set”
Tap to select is being watched.
this option
If any of these
prefixes (3 letters)
are entered the
TextWatcher
mechanism shows
an option list.
24
Example 4: AutoComplete Demo – Layout
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="@+id/txtMsg"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="20sp"
android:textColor="#ffffffff"
android:background="#ff0000ff" >
</TextView>
<AutoCompleteTextView
android:id="@+id/autoCompleteTextView1"
android:hint="type here..."
android:completionThreshold="3"
android:layout_width="wrap_content"
Wait 3 chars to work
android:layout_height="wrap_content"
android:layout_below="@+id/txtMsg"
android:layout_marginTop="15dp"
android:ems="10" />
</RelativeLayout>
25
Example 4: AutoComplete Demo – Main Activity
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val txtMsg: TextView = findViewById(R.id.txtMsg)
val items: Array<String> = arrayOf("words", "starting", "with", "set", "Setback", "Setline",
"Setoffs", "Setouts", "Setters", "Setting", "Settled", "Settler", "Wordless", "Wordiness", "Adios")
val arrayAdapter: ArrayAdapter<String> = ArrayAdapter(this,
android.R.layout.simple_list_item_1, items)
findViewById<AutoCompleteTextView>(R.id.edit_keyword).run {
setAdapter(arrayAdapter)
addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
TODO("Not yet implemented")
}
override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
txtMsg.text = text
}
26
Example 4: AutoComplete Demo – Main Activity
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
findViewById<AutoCompleteTextView>(R.id.edit_keyword).run {
setAdapter(arrayAdapter)
addTextChangedListener(onTextChanged = {text, start, count, after ->
txtMsg.text = text})
}
}
}
27
The HorizontalScrollView Widget
28
Example 5: HorizontalScrollView Demo
29
Example 5: Populating The HorizontalScrollView Widget
3. After the current frame is filled with data, it will be added to the growing
set of views hosted by the scrollViewgroup container (scrollViewgroup is
nested inside the horizontal scroller).
30
Example 5: HorizontalScrollView Demo – Layout 1 of 2
31
Example 5: HorizontalScrollView Demo – Layout 2 of 2
<ImageView
android:id="@+id/imageSelected"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="2" />
</LinearLayout>
32
Example 5: Layout: frame_icon_caption.xml
<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<ImageView
android:id="@+id/icon"
android:layout_width="80dp"
android:layout_height="80dp"
android:paddingLeft="2dp"
android:paddingRight="2dp"
android:paddingTop="2dp"
android:src="@drawable/ic_launcher" />
<TextView
android:id="@+id/caption"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#55ffff00"
android:textSize="20sp" />
</LinearLayout>
33
Example 5: HorizontalScrollView Demo – MainActivity 1 of 2
for (i in 1..27) {
captionList.add("Data-$i")
thumbList.add(resources.getIdentifier("thumb$i", "drawable", packageName))
imageList.add(resources.getIdentifier("wall$i", "drawable", packageName))
}
34
Example 5: HorizontalScrollView Demo – MainActivity 2 of 2
view.findViewById<TextView>(R.id.caption).text = captionList[i]
view.findViewById<ImageView>(R.id.icon).setImageResource(thumbList[i])
viewGroup.addView(view)
35
Image-based GridView
36
Example 6: GridView Images Demo – Layout (activity_main)
37
Example 6: MainActivity
38
Example 6: Custom Adapter - MyImageAdapter
imageView.setImageResource(thumbList[p0])
return imageView
}
}
39
ListView’s Recycler
40
Example 7: Defining your own ListViews
• In those cases, you should create your own subclass of a Data Adapter.
41
Example 7: Create your own DataAdapter
42
Example 7: Designing Custom-Rows
In our example each UI row will show an icon (on the left side) and text
following the icon to its right side.
Custom row
Icon Text
43
Example 7: Designing Custom-Rows
44
Example 7: Layout 1 – activity_main.xml
</LinearLayout>
45
Example 7: Layout 2 – custom_row_icon_label.xml
<ImageView
android:id="@+id/icon"
android:layout_width="100dp"
android:layout_height="75dp"
android:layout_marginRight="3dp"
android:src="@drawable/ic_launcher" />
<TextView
android:id="@+id/label"
android:layout_width="match_parent"
android:layout_height="75dp"
android:background="#22ffff00"
android:textSize="20sp" />
</LinearLayout>
46
Example 7: MainAcitivity
txtMsg = findViewById<TextView>(R.id.txtMsg)
47
Example 7: Custom ListView Demo – Adapter
data class ItemModel(val caption: String, val imageResource: Int)
textView.text = items[p0].caption
imageView.setImageResource(items[p0].imageResource)
return row
}
}
48
The LayoutInflater Class
49
ViewHolder degisn pattern
The figure below is from “Performance Tips for Android’s ListView” by Lucas Rocha
http://lucasr.org/2012/04/05/performance-tips-for-androids-listview/ [Dec, 2014].
It shows a set of rows presented to the user inside a ListView container.
The strategy of reusing these scrapviews is known as the ViewHolder Design Pattern.
It cuts down on the number of times you have to inflate a row-layout and then get
access to its internal widgets by calling the ‘findViewById()’ method.
When reusing the scrapviews (made available as ‘convertView’) all you need to do is
move the appropriate data to the internal widgets and set their onClick listeners.
50
ViewHolder design pattern
In this example a list holding rows showing multiple lines of text and images, is
populated with a custom made BaseAdapter that uses the ViewHolder strategy for
better performance.
51
Example 8: Custom List – activity_main.xml
Layout activity_main.xml shows a ViewList.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="3dp"
android:orientation="vertical" >
<ListView
android:id="@+id/listView"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</ListView>
</LinearLayout>
52
Example 8: Custom List – custom_item_view.xml
Layout custom_item_view.xml shows a custom-made row holding one image, one text
and one checkbox
<?xml version="1.0" encoding="UTF-8"?>
<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="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<ImageView
android:id="@+id/image_icon"
android:layout_width="75dp"
android:layout_height="75dp"
android:src="@drawable/thumb1"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
53
Example 8: Custom List – custom_item_view.xml
Layout custom_item_view.xml shows a custom-made row holding one image, one text
and one checkbox
<TextView
android:id="@+id/text_label"
android:layout_width="0dp"
android:layout_height="75dp"
android:background="#22ffff00"
android:padding="8dp"
android:text="Data"
android:textSize="34sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/image_icon"
app:layout_constraintTop_toTopOf="parent" />
<CheckBox
android:id="@+id/check_select"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
54
Example 8: Custom List – MainActivity
The main activity exposes a ListView. A custom adapter is tied to the ListView. The
adapter gets a reference to a test ‘database’ and the custom row layout.
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
55
Example 8: Custom List – MyCustomAdapter
The getView method in this extended BaseAdapter inflates a supplied row layout, gets
access to its internal widgets, fills them with data and set listeners on some of them.
class MyCustomAdapter(val items: ArrayList<ItemModel>): BaseAdapter() {
override fun getCount(): Int = items.size
56
Example 8: Custom List – MyCustomAdapter
The getView method in this extended BaseAdapter inflates a supplied row layout, gets
access to its internal widgets, fills them with data and set listeners on some of them.
viewHolder.textLabel.text = items[p0].caption
viewHolder.imageIcon.setImageResource(items[p0].imageResource)
viewHolder.checkSelect.isChecked = items[p0].selected
viewHolder.checkSelect.setOnClickListener {
items[p0].selected = !items[p0].selected
notifyDataSetChanged()
}
return itemView
}
class MyViewHolder {
lateinit var textLabel: TextView
lateinit var imageIcon: ImageView
lateinit var checkSelect: CheckBox
}
}
57