2.5.3 Basic Usage of Spinner (List Selection Box)
Category Android Basic Tutorial
Introduction:
>
Initially, this section was intended to introduce the Gallery widget, but I decided against it since it has been deprecated since Android 4.1. Even though we can use compatibility to employ Gallery, it's not recommended because Gallery recreates the view every time an image is switched, leading to significant resource waste. We can achieve Gallery-like effects using other methods, such as HorizontalScrollView for horizontal scrolling or creating a horizontal ListView. If interested, you can search for more details online.
This section focuses on the Spinner, an Adapter widget. It is used in scenarios where an app requires user input, providing a convenient alternative to typing by listing options for users to select from.
Let's dive into the basic usage of Spinner.
1. Related Attributes
>
- android:dropDownHorizontalOffset: Sets the horizontal offset of the dropdown list.
- android:dropDownVerticalOffset: Sets the vertical offset of the dropdown list.
- android:dropDownSelector: Background for the dropdown list when selected.
- android:dropDownWidth: Sets the width of the dropdown list.
- android:gravity: Alignment of components inside.
- android:popupBackground: Background of the dropdown list.
- android:prompt: Prompt message (title) for the dialog-style list, referencing a resource ID from string.xml.
- android:spinnerMode: Mode of the list, with options: dialog (dialog-style window) and dropdown (dropdown-style window, default).
- Optional attribute: android:entries: Sets the dropdown list items using an array resource.
2. Usage Example:
>
Note that Spinner defaults to selecting the first item, equivalent to calling spinner.setSelection(0)
, which triggers an OnItemSelectedListener
event. There's no solution to prevent this initial trigger, so a workaround involves setting a boolean flag to false and checking its value in onItemSelected
. If false, it indicates the default trigger and no action is taken; if true, the event is handled normally.
The example includes two different Spinners, demonstrating variations in data source and style.
Effect Diagram:
Code Implementation:
This example uses a reusable BaseAdapter.
First Spinner's data source:
Create a file myarrays.xml under res/values with the following content:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="data">
<item>Valor Bronze</item>
<item>Perseverance Silver</item>
<item>Glory Gold</item>
<item>Noble Platinum</item>
<item>Radiant Diamond</item>
<item>Transcendent Master</item>
<item>The Supreme King</item>
</string-array>
</resources>
Second Spinner's layout: itemspinhero.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="match_parent"
android:orientation="horizontal"
android:padding="5dp">
<ImageView
android:id="@+id/img_icon"
android:layout_width="48dp"
android:layout_height="48dp"
android:src="@mipmap/iv_lol_icon1" />
<TextView
android:id="@+id/txt_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginTop="15dp"
android:text="Demacia"
android:textSize="16sp" />
</LinearLayout>
Next, create an Entity class: Hero.java:
/**
* Created by Jay on 2015/9/24 0024.
*/
public class Hero {
private int hIcon;
private String hName;
public Hero() {
}
public Hero(int hIcon, String hName) {
this.hIcon = hIcon;
this.hName = hName;
}
public int gethIcon() {
return hIcon;
}
public String gethName() {
return hName;
}
public void sethIcon(int hIcon) {
this.hIcon = hIcon;
}
public void sethName(String hName) {
this.hName = hName;
}
}
Finally, the layout and Java code for MainActivity:
Layout file: activity_main.xml:
<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="5dp"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Select Your Ranking Tier"
android:textColor="#44BDED"
android:textSize="18sp" />
<Spinner
android:id="@+id/spin_one"
android:layout_width="100dp"
android:layout_height="64dp"
android:entries="@array/data"
android:prompt="@string/spin_title"
android:spinnerMode="dialog" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="Select Your Best Hero"
android:textColor="#F5684A"
android:textSize="18sp" />
<Spinner
android:id="@+id/spin_two"
android:layout_width="wrap_content"
android:layout_height="64dp" />
</LinearLayout>
MainActivity.java:
public class MainActivity extends AppCompatActivity implements AdapterView.OnItemSelectedListener {
private Spinner spin_one;
private Spinner spin_two;
private Context mContext;
// Flag to determine if initial selection is triggered
private boolean one_selected = false;
private boolean two_selected = false;
private ArrayList<Hero> mData = null;
private BaseAdapter myAdadpter = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mContext = MainActivity.this;
mData = new ArrayList<Hero>();
bindViews();
}
private void bindViews() {
spin_one = (Spinner) findViewById(R.id.spin_one);
spin_two = (Spinner) findViewById(R.id.spin_two);
mData.add(new Hero(R.mipmap.iv_lol_icon1,"Teemo"));
mData.add(new Hero(R.mipmap.iv_lol_icon2,"Darius"));
// Additional setup for spin_two
// ...
}
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
if (parent.getId() == R.id.spin_one) {
if (!one_selected) {
one_selected = true;
return;
}
// Handle spin_one selection
} else if (parent.getId() == R.id.spin_two) {
if (!two_selected) {
two_selected = true;
return;
}
// Handle spin_two selection
}
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
// Do nothing
}
}
mData.add(new Hero(R.mipmap.iv_lol_icon3, "Master Yi: The Wuju Bladesman (Yi)"));
mData.add(new Hero(R.mipmap.iv_lol_icon4, "Darius: The Hand of Noxus (Draven)"));
mData.add(new Hero(R.mipmap.iv_lol_icon5, "Xin Zhao: The Seneschal of Demacia (XinZhao)"));
mData.add(new Hero(R.mipmap.iv_lol_icon6, "Olaf: The Berserker (Olaf)"));
myAdadpter = new MyAdapter<Hero>(mData, R.layout.item_spin_hero) {
@Override
public void bindView(ViewHolder holder, Hero obj) {
holder.setImageResource(R.id.img_icon, obj.gethIcon());
holder.setText(R.id.txt_name, obj.gethName());
}
};
spin_two.setAdapter(myAdadpter);
spin_one.setOnItemSelectedListener(this);
spin_two.setOnItemSelectedListener(this);
}
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
switch (parent.getId()) {
case R.id.spin_one:
if (one_selected) {
Toast.makeText(mContext, "Your rank is~: " + parent.getItemAtPosition(position).toString(),
Toast.LENGTH_SHORT).show();
} else one_selected = true;
break;
case R.id.spin_two:
if (two_selected) {
TextView txt_name = (TextView) view.findViewById(R.id.txt_name);
Toast.makeText(mContext, "The hero you selected is~: " + txt_name.getText().toString(),
Toast.LENGTH_SHORT).show();
} else two_selected = true;
break;
}
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
}
Regarding the Spinner's OnItemSelectedListener and how to get the value of the selected item, please refer to the code above.
3. Code Example Download:
Summary of This Section
>
Alright, this section introduced the usage of Spinner (drop-down selection box), and the example is quite interesting, haha! Don't ask me which district or what rank I am, I am the king of AI simulations, but I struggle in the bronze rank. You know why.
-1.0 Android Basic Beginner Tutorial
-1.0.1 2015 Latest Android Basic Beginner Tutorial Table of Contents
-1.1 Background and System Architecture Analysis
-1.2 Development Environment Setup
-1.2.1 Using Eclipse + ADT + SDK to Develop Android APP
-1.2.2 Using Android Studio to Develop Android APP
-1.3 Solving SDK Update Issues
-1.4 Genymotion Emulator Installation
-1.5.1 Git Tutorial for Basic Local Repository Operations
-1.5.2 Git: Using GitHub to Set Up a Remote Repository
-1.6 How to Play with 9-Patch Images
-1.7 Interface Prototype Design
-1.8 Project Source Analysis (Various Files, Resource Access)
-1.9 Android Application Signing and Packaging
-1.11 Decompiling APK to Obtain Code & Resources
-2.1 Concepts of View and ViewGroup
-2.2.1 LinearLayout (Linear Layout)
-2.2.2 RelativeLayout (Relative Layout)
-2.2.3 TableLayout (Table Layout)
-2.2.4 FrameLayout (Frame Layout)
-2.2.5 GridLayout (Grid Layout)
-2.2.6 AbsoluteLayout (Absolute Layout)
-2.3.1 Detailed Explanation of TextView (Text Box)
-2.3.2 Detailed Explanation of EditText (Input Box)
-2.3.3 Button and ImageButton (Image Button)
-2.3.5.RadioButton (Radio Button) & Checkbox (Checkbox)
-2.3.6 ToggleButton and Switch (Switch Button)
-2.3.7 ProgressBar (Progress Bar)
-2.3.9 RatingBar (Star Rating Bar)
-2.4.1 ScrollView (Scroll Bar)
-2.4.2 Date & Time Components (Part 1)
-2.4.3 Date & Time Components (Part 2)
-2.4.4 Basic Explanation of Adapter
-2.4.5 Simple Usage of ListView
-2.4.6 Optimization of BaseAdapter
-2.4.7 Focus Issues with ListView
-2.4.8 Solving Checkbox Misalignment Issue in ListView
-2.4.9 Data Update Issues with ListView
-2.5.0 Building a Reusable Custom BaseAdapter
-2.5.1 Implementation of Multi-Layout ListView Items
-2.5.2 Basic Usage of GridView (Grid View)
- 2.5.3 Basic Usage of Spinner (List Selection Box)
-2.5.4 Basic Usage of AutoCompleteTextView (Auto-Complete Text Box)
-2.5.5 Basic Usage of ExpandableListView (Collapsible List)
-2.5.6 Basic Usage of ViewFlipper (Flip View)
-2.5.8 Detailed Explanation of Notification (Status Bar Notification) ```
- 2.5.9 Detailed Explanation of AlertDialog
- 2.6.0 Basic Usage of Other Common Dialogs
- 2.6.1 Basic Usage of PopupWindow
- 2.6.2 Menu
- 2.6.3 Simple Usage of ViewPager
- 2.6.4 Simple Usage of DrawerLayout
- 3.1.1 Event Handling Mechanism Based on Listeners
- 3.2 Event Handling Mechanism Based on Callbacks
- 3.3 Analysis of Handler Message Passing Mechanism
- 3.4 TouchListener vs OnTouchEvent + Multi-touch
- 3.5 Listening for Content Changes in EditText
- 3.6 Responding to System Setting Events (Configuration Class)
- 3.7 AsyncTask Asynchronous Tasks
- 3.8 Gestures
- 4.1.1 Introduction to Activity
- 4.1.2 Getting Started with Activity
- 4.1.3 Advanced Activity
- 4.2.1 Introduction to Service
- 4.2.2 Intermediate Service
- 4.2.3 Advanced Service
- 4.3.1 Introduction to BroadcastReceiver
- 4.3.2 In-depth BroadcastReceiver
- 4.4.1 Introduction to ContentProvider
- 4.4.2 Further Exploration of ContentProvider - Document Provider
- 4.5.1 Basic Usage of Intent
- 4.5.2 Passing Complex Data with Intent
- 5.1 Basic Overview of Fragment
- 5.2.1 Fragment Example - Bottom Navigation Bar Implementation (Method 1)
- 5.2.2 Fragment Example - Bottom Navigation Bar Implementation (Method 2)
- 5.2.3 Fragment Example - Bottom Navigation Bar Implementation (Method 3)
- 5.2.4 Fragment Example - Bottom Navigation Bar + ViewPager Page Swipe
- 5.2.5 Fragment Example - Simple Implementation of News/Shopping App List Fragment
- 6.1 Data Storage and Access - File Storage and Reading
- 6.2 Data Storage and Access - SharedPreferences for Saving User Preferences
- 6.3.1 Data Storage and Access - Introduction to SQLite Database
- 6.3.2 Data Storage and Access - Further Exploration of SQLite Database
- 7.1.1 Android Network Programming and Learning HTTP Protocol
- 7.1.2 Learning Android HTTP Request and Response Headers
- 7.1.3 Android HTTP Request Method: HttpURLConnection
- 7.1.4 Android HTTP Request Method: HttpClient
- 7.2.1 Android XML Data Parsing
- 7.2.2 Android JSON Data Parsing
- 7.3.1 Android File Upload
- 7.3.2 Android File Download (1)
- 7.3.3 Android File Download (2)
- 7.4 Android Calling WebService
- 7.5.1 Basic Usage of WebView
- 7.5.2 WebView and JavaScript Interaction Basics
- 7.5.3 WebView Considerations After Android 4.4
- 7.5.4 WebView File Download
- 7.5.5 WebView Cache Issues
- 7.5.6 WebView Handling Webpage Error Codes
- 7.6.1 Socket Learning Network Basics Preparation
- 7.6.2 TCP Protocol Based Socket Communication (1)
- 7.6.3 TCP Protocol Based Socket Communication (2)
- 7.6.4 UDP Protocol Based Socket Communication
- 8.1.1 Summary of 13 Drawable Types in Android Part 1
- 8.1.2 Summary of 13 Drawable Types in Android Part 2
- 8.1.3 Summary of 13 Drawable Types in Android Part 3
- 8.2.1 Comprehensive Analysis of Bitmap Part 1
- 8.2.2 OOM Issues Caused by Bitmap
- 8.3.1 Detailed Explanation of Three Drawing Tools
- 8.3.2 Drawing Class Practical Examples
- 8.3.3 Paint API - MaskFilter
- 8.3.4 Paint API - Xfermode and PorterDuff Detailed Explanation (Part 1)
- 8.3.5 Paint API - Xfermode and PorterDuff Detailed Explanation (Part 2)
- 8.3.6 Paint API - Xfermode and PorterDuff Detailed Explanation (Part 3)
- 8.3.7 Paint API - Xfermode and PorterDuff Detailed Explanation (Part 4)
- 8.3.8 Paint API - Xfermode and PorterDuff Detailed Explanation (Part 5)
- 8.3.9 Paint API - ColorFilter (Color Filter) (1/3)
- 8.3.10 Paint API - ColorFilter (Color Filter) (2/3)
- 8.3.11 Paint API - ColorFilter (Color Filter) (3/3)
- 8.3.12 Paint API - PathEffect (Path Effect)
- 8.3.13 Paint API - Shader (Image Rendering)
- 8.3.14 Paint Enum/Constants and ShadowLayer Shadow Effect
- 8.3.15 Paint API - Typeface (Font Style)
- 8.3.16 Canvas API Detailed Explanation (Part 1)
- 8.3.17 Canvas API Detailed Explanation (Part 2) - Clipping Methods Collection
- 8.3.18 Canvas API Detailed Explanation (Part 3) - Matrix and drawBitmapMesh
- 8.4.1 Android Animation Collection - Frame Animation
- 8.4.2 Android Animation Collection - Tween Animation
- 8.4.3 Android Animation Collection - Property Animation - Introduction
- 8.4.4 Android Animation Collection - Property Animation - Further Exploration
- 9.1 Using SoundPool to Play Sound Effects (Duang~)
- 9.2 MediaPlayer to Play Audio and Video
- 9.3 Using Camera to Take Photos
- 9.4 Using MediaRecord to Record Audio
- 10.1 TelephonyManager (Phone Manager)
- 10.2 SmsManager (SMS Manager)
- 10.3 AudioManager (Audio Manager)
- 10.4 Vibrator (Vibrator)
- 10.5 AlarmManager (Alarm Service)
- 10.6 PowerManager (Power Service)
- 10.7 WindowManager (Window Management Service)
- 10.8 LayoutInflater (Layout Service)
- 10.9 WallpaperManager (Wallpaper Manager)
- 10.10 Sensor Topic (1) - Introduction
- 10.11 Sensor Topic (2) - Orientation Sensor
- 10.12 Sensor Topic (3) - Accelerometer/Gyroscope Sensor
- 10.12 Sensor Topic (4) - Understanding Other Sensors
- 10.14 Android GPS Introduction
- 11.0《2015 Latest Android Basic Beginner's Tutorial》Completion Celebration~
- 12.1 Android Practice: DrySister Viewing Girls App (First Edition) - Project Setup and Simple Implementation
- 12.2 DrySister Viewing Girls App (First Edition) - 2. Parsing Backend Data
- 12.3 DrySister Viewing Girls App (First Edition) - 3. Image Loading Optimization (Writing an Image Caching Framework)
- 12.4 DrySister Viewing Girls App (First Edition) - 4. Adding Data Caching (Introducing SQLite)
- 12.5 DrySister Viewing Girls App (First Edition) - 5. Code Review, Adjustment, and Logging Class Writing
- 12.6 DrySister Viewing Girls App (First Edition) - 6. Icon Creation, Obfuscation, Signing, Packaging, APK Slimming, App Release