记录学习Android基础的心得05:常用控件(基础篇)



功高成怨府,权盛是危机。——王迈《读渡江诸将传》


前言

在心得文章02里面介绍了控件的一些常识,本文书接上文,由易到难接着介绍常用控件的基础知识:复合按钮CompoundButton的常见子类:单选按钮RadioButton、复选框CheckBox、开关Switch;进度展示控件:进度条ProgressBar、拖动条SeekBar、评分条RatingBar;接着介绍编辑框EditText的定制使用,菜单Menu的用法;最后给出适配器视图AdapterView的初步认识和下拉框Spinner的使用。本文控件的描述方法为:默认的外形展示->类结构的分析->控件的作用及使用方法。

在这里插入图片描述

一、复合按钮CompoundButton的常见子类

查阅开发文档,首先了解一下复合按钮CompoundButton的类结构:
类结构的分析:
public abstract class CompoundButton
extends Button implements Checkable
已知的直接子类:
CheckBox, RadioButton, Switch, SwitchCompat, ToggleButton

其次,CompoundButton的两个重要XML属性:
button:指定按钮外形所使用的Drawable,若不指定则使用系统默认图标。在代码中可用 void setButtonDrawable (Drawable drawable) 来设置此属性。

checked:指定按钮选中状态,true表示选中,false未选中。在代码中可用:
①使用 void setChecked (boolean checked) 来设置此属性。
②使用 void toggle () 来翻转选中的状态。
③使用 boolean isChecked () 来查询是否选中状态。
④使用 void setOnCheckedChangeListener (CompoundButton.OnCheckedChangeListener listener) 为按钮注册一个回调方法,当这个按钮的选中状态改变时触发。
由此可知CompoundButton是一个抽象类,无法直接使用,故能使用的是有实际外形的5个子类。

1.单选按钮RadioButton

查阅单选按钮RadioButton的开发文档:
默认的外形展示:
在这里插入图片描述
类结构的分析:
public class RadioButton
extends CompoundButton
已知的直接子类:
AppCompatRadioButton

public class RadioGroup
extends LinearLayout
控件的作用及使用方法:
单选按钮是一个可以选中或不选中的双状态按钮,默认不选中。 当单选按钮未被选中时,用户可以点击它来选中。 但是用户选中按钮后,便不能通过再次点击来取消选中的状态了。
单选按钮通常结合RadioGroup一起使用RadioGroup是用来管理组合多个单选按钮的容器,用户在一个RadioGroup中只能选择其中一项,并且不能多选。RadioGroup的属性orientation可指定下级控件的排列方向,分别为水平排列horizontal,竖直排列vertical,实际上就相当于一个特殊的线性布局。有三个常用方法:
int getCheckedRadioButtonId () 返回此组合中所选单选按钮的id,若一个都没选中返回-1。
void check (int id) 选中指定id的单选按钮。
void setOnCheckedChangeListener (RadioGroup.OnCheckedChangeListener listener) 注册状态变化监听器。

单选按钮的选中事件一般不由自己处理,而是由父控件RadioGroup响应。故当布局好控件的位置后,需要在代码里为RadioGroup注册状态监听器。示例:

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_radio);
        // 从布局文件中获取名叫rg的单选组
        RadioGroup rg = findViewById(R.id.rg);
        // 给rg设置单选监听器
        rg.setOnCheckedChangeListener(new RadioListener());
    }
    // 定义一个单选监听器,它实现了接口RadioGroup.OnCheckedChangeListener
    class RadioListener implements RadioGroup.OnCheckedChangeListener{
        // 在用户点击组内的单选按钮时触发
        public void onCheckedChanged(RadioGroup group, int checkedId) {
            Toast.makeText(RadioActivity.this, "选中了控件"+checkedId, Toast.LENGTH_LONG).show();
        }
    }

若要改变单选按钮的默认外形,则可以设置其button或者drawableLeft属性为状态图形,根据选中状态来展示特定的外形。

2.复选框CheckBox

查阅复选框CheckBox的开发文档:
默认的外形展示:
在这里插入图片描述
类结构的分析:
public class CheckBox
extends CompoundButton
已知的直接子类:
AppCompatCheckBox
控件的作用及使用方法:
复选框是一种超级简单的双态按钮,点击勾选,再次点击取消勾选。
布局好控件后,在代码中使用 void setOnCheckedChangeListener (CompoundButton.OnCheckedChangeListener listener) 设置状态变化监听器。示例:

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_checkbox);
        // 从布局文件中获取名叫ck的复选框
        CheckBox ck = findViewById(R.id.ck);
        // 给ck设置勾选监听器,一旦用户点击复选框,就触发监听器的onCheckedChanged方法
        ck.setOnCheckedChangeListener(new CheckListener());
    }

    // 定义一个勾选监听器,它实现了接口CompoundButton.OnCheckedChangeListener
    private class CheckListener implements CompoundButton.OnCheckedChangeListener{
        // 在用户点击复选框时触发
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            String desc = String.format("您勾选了控件%d,状态为%b", buttonView.getId(), isChecked);
            Toast.makeText(CheckboxActivity.this, desc, Toast.LENGTH_LONG).show();
        }
    }

同样的,若要改变复选框的默认外形,则可以设置其button属性为状态图形,根据选中状态来展示特定的外形。

3.开关Switch

查阅开关Switch的开发文档:
默认的外形展示:
在这里插入图片描述
类结构的分析:
public class Switch
extends CompoundButton
控件的作用及使用方法:
开关Switch和复选框CheckBox功能一样,都是注册状态监听器来实现功能回调,只不过它们的外形有点差异,这就导致了Switch的几个XML属性需要单独设置。
①switchPadding:设置开关图标和左右两侧文本之间的距离,
②textOff:当开关处于未选中状态时要显示的文本,也即图标左侧的文本。
③textOn:选中状态时显示的文本,即右侧的文本。
④thumb:设置开关图标的背景
⑤track:设置开关的滑道,即图标的前景。
⑥thumbTextPadding:设置图标背景与左右两侧文本的距离,与switchPadding属性互斥。
通过设置button属性为@null,设置background属性为状态图形,那么可以得到个性化的开关外形
在这里插入图片描述

二、进度展示控件

1.进度条ProgressBar

查阅进度条ProgressBar的开发文档:
默认的外形展示:
在这里插入图片描述
类结构的分析:
public class ProgressBar
extends View
已知的直接子类
AbsSeekBar, ContentLoadingProgressBar
已知的间接子类
AppCompatRatingBar, AppCompatSeekBar, RatingBar, SeekBar
控件的作用及使用方法:
进度条用于直观的向用户表示操作进度。此控件有两种不同的显示风格,其style属性在XML文件里可以设置为:style="@style/Widget.AppCompat.ProgressBar"(圆圈形状)或者 style="?android:attr/progressBarStyleHorizontal"(水平进度条)。显然,圆圈风格用在不确定具体进度情况下,圆圈风格的进度条会显示循环动画,可以是一个旋转轮或一个水平条。如果显示具体数值进度,则必须使用水平条。
进度条的常用属性如下:
①max:定义进度可以达到的最大值,必须是整数值,例如“ 100 ”。代码使用方法:
int getMax ()void setMax (int max)
②progress:定义0到max之间的进度值,整数值。代码使用方法:
void setProgress (int progress)int getProgress ()
void incrementProgressBy (int diff) 用于设置当前进度的增量,diff 正值为增加,负值为减少
显然,这两个属性只能适用于有具体数值的水平进度条,用于圆圈形状则会无效
③secondaryProgress:定义0到max之间第二层次的进度值, 它适用于媒体场景,例如显示缓冲进度,而第一层的值代表播放进度,整数值。代码使用方法:
int getSecondaryProgress ()void setSecondaryProgress (int secondaryProgress)
void incrementSecondaryProgressBy (int diff) 用于设置第二进度的增量,diff 正值为增加,负值为减少
④progressDrawable:指定进度条填充的层次图形LayerDrawable(不能使用普通图形)。代码中使用:
void setProgressDrawable (Drawable d)
层次图形LayerDrawable在XML中定义,根节点为layer-list,在里面分别指定前景图片(进度条图层)和背景图片。示例如下:

<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
    <!-- 背景图层,定义了一个形状图形 -->
    <item android:id="@android:id/background">
        <shape>
            <solid android:color="#ffff00" />
        </shape>
    </item>
    <!-- 这是进度条图层,里面定义了一个.9图形 -->
    <item android:id="@android:id/progress">
        <clip>
            <nine-patch android:src="@drawable/green" />
        </clip>
    </item>
</layer-list>

注意,控件id形式为android:id="@android:id/xxx “为系统预定义的id,仔细区分

2.拖动条SeekBar

查阅拖动条SeekBar的开发文档:
默认的外形展示:
在这里插入图片描述
由图可知,这外观和进度条ProgressBar有差异,多了一个可拖动的图标。
类结构的分析:
public class SeekBar
extends AbsSeekBar
已知的直接子类
AppCompatSeekBar
控件的作用及使用方法:
SeekBar是ProgressBar的扩展,ProgressBar只能在代码里修改进度,而拖动条增加了一个可拖动的特性,用户可在屏幕上拖动来改变进度。由此引入四个额外方法:
void setThumb (Drawable thumb) 设置在SeekBar中当前进度图标。
void setThumbOffset (int thumbOffset) 设置进度图标的显示偏移量,一般设置为0或者不设置。
void setKeyProgressIncrement (int increment) 拖动一下所更改的进度值。
void setOnSeekBarChangeListener (SeekBar.OnSeekBarChangeListener l) 设置拖动变化事件的监听器。监听器需要实现如下方法:

    // 在进度变更时触发。第三个参数为true表示用户拖动,为false表示代码设置进度
    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {}
    // 在开始拖动进度时触发
    public void onStartTrackingTouch(SeekBar seekBar) {}
    // 在停止拖动进度时触发
    public void onStopTrackingTouch(SeekBar seekBar) {}

3.评分条RatingBar

查阅评分条RatingBar的开发文档:
默认的外形展示:
在这里插入图片描述
由图可知,评分条就是拖动条SeekBar换个外形而已,其实质功能都是一样的。
类结构的分析:
public class RatingBar
extends AbsSeekBar
已知的直接子类
AppCompatRatingBar
控件的作用及使用方法:
评分条拥有拖动条SeekBar的所有方法,并且把进度换成了五角星显示。故需要额外的XML属性及相关设置方法如下:
①isIndicator:是否作为指示器。如果是指示器,就不可通过触摸修改评级。在代码中使用:void setIsIndicator(boolean isIndicator)

②numStars:设置五角星的总个数,以代码中:
void setNumStars(int numStars)

③rating:设置点亮几个五角星。在代码中:
void setRating(float rating)

④stepSize:设置每次增减的大小。默认为总数的十分之一,比如星星总数为5,默认值为0.5。在代码中:
void setStepSize(float stepSize)

void setOnRatingBarChangeListener(RatingBar.OnRatingBarChangeListener listener) 设置评分监听器,需实现接口OnRatingBarChangeListener的onRatingChanged方法。
⑥style:RatingBar 提供了3种星星样式,用于不同业务场景时的评级展示。
style="?android:attr/ratingBarStyle",星星大小默认值,能通过触摸改变值。
style="?android:attr/ratingBarStyleIndicator",星星中等大小,不能通过触摸改变值。
style="?android:attr/ratingBarStyleSmall",星星很小,不能通过触摸改变值。

在这里插入图片描述

三、编辑框EditText的定制使用,菜单Menu的用法

1.编辑框EditText的定制使用

在前面的文章已经介绍了编辑框EditText的基本属性,这里给出它的定制使用方法:更换光标、边框,编辑结束后自动隐藏输入法,回车后自动换行。
①更换光标:EditText与光标有关的属性主要有两个:cursorVisible和textCursorDrawable,分别设置光标是否可见和指定光标的图形。

②更换边框:设置其background属性,隐藏边框将其设置为@null,若需要定制则将其设置为指定的图形。如设置为一个形状图形:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
    <solid android:color="#ffffff" />
    <stroke
        android:width="1dp"
        android:color="#ffaaaaaa" />
    <corners
        android:bottomLeftRadius="5dp"
        android:bottomRightRadius="5dp"
        android:topLeftRadius="5dp"
        android:topRightRadius="5dp" />
    <padding
        android:bottom="2dp"
        android:left="2dp"
        android:right="2dp"
        android:top="2dp" />
</shape>

③自动隐藏输入法
首先在打开含有编辑框的页面时,编辑框会自动获得焦点并立即启动输入法。为了避免这个情况,需要将此页面的根节点的属性focusable和focusableInTouchMode设置为true以此强制根节点获取焦点。

其次当编辑框输入指定的文本长度之后,需要自动关闭输入法,这个功能需要两个参数:编辑框允许输入的长度、当前已经输入的长度。接下来以输入6位和11位数字为例。
(1)由于编辑框的maxLength属性只能通过XML文件设置,而不能直接在代码中获取值,故需要通过反射获得其值:

    // 获取编辑框的最大长度,通过反射机制调用隐藏方法
    public static int getMaxLength(EditText et) {
        int length = 0;
        try {
            InputFilter[] inputFilters = et.getFilters();
            for (InputFilter filter : inputFilters) {
                Class<?> c = filter.getClass();
                if (c.getName().equals("android.text.InputFilter$LengthFilter")) {
                    Field[] f = c.getDeclaredFields();
                    for (Field field : f) {
                        if (field.getName().equals("mMax")) {
                            field.setAccessible(true);
                            length = (Integer) field.get(filter);
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return length;
    }

(2)监控当前输入的文本需要实现一个文本监听接口TextWatcher,实现其三个方法,然后对EditText对象调用addTextChangedListener方法注册监听器就行了:

    // 定义一个编辑框监听器,在输入文本达到指定长度时自动隐藏输入法
    private class HideTextWatcher implements TextWatcher {
        private EditText mView; // 声明一个编辑框对象
        private int mMaxLength; // 声明一个最大长度变量
        private CharSequence mStr; // 声明一个文本串

        public HideTextWatcher(EditText v) {
            super();
            mView = v;
            // 通过反射机制获取编辑框的最大长度
            mMaxLength = ViewUtil.getMaxLength(v);
        }

        // 在编辑框的输入文本变化前触发
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {}

        // 在编辑框的输入文本变化时触发
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            mStr = s;
        }

        // 在编辑框的输入文本变化后触发
        public void afterTextChanged(Editable s) {
            if (mStr == null || mStr.length() == 0)
                return;
            // 输入文本达到11位(如手机号码)时关闭输入法
            if (mStr.length() == 11 && mMaxLength == 11) {
                ViewUtil.hideAllInputMethod(EditHideActivity.this);
            }
            // 输入文本达到6位(如登录密码)时关闭输入法
            if (mStr.length() == 6 && mMaxLength == 6) {
                ViewUtil.hideOneInputMethod(EditHideActivity.this, mView);
            }
        }
    }

(3)输入法通过输入法管理器InputMethodManager管理,这里使用两种方式实现关闭输入法:

    public static void hideAllInputMethod(Activity act) {
        // 从系统服务中获取输入法管理器
        InputMethodManager imm = (InputMethodManager) act.getSystemService(Context.INPUT_METHOD_SERVICE);
        if (imm.isActive()) { // 如果已经打开则关闭之
            imm.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS);
        }
    }

    public static void hideOneInputMethod(Activity act, View v) {
        // 从系统服务中获取输入法管理器
        InputMethodManager imm = (InputMethodManager) act.getSystemService(Context.INPUT_METHOD_SERVICE);
        // 关闭屏幕上的输入法
        imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
    }

④回车自动换行的意思是在当前的编辑框按下回车符号后,则输入法的光标自动跳转到下一个编辑框内部,继续编辑。同样,此功能也需要实现文本监听接口来判断回车:

// 定义一个编辑框监听器,在输入回车符时自动跳到下一个控件
    private class JumpTextWatcher implements TextWatcher {
        private EditText mThisView;  // 声明当前的编辑框对象
        private View mNextView; // 声明下一个视图对象

        public JumpTextWatcher(EditText vThis, View vNext) {
            super();
            mThisView = vThis;
            if (vNext != null) {
                mNextView = vNext;
            }
        }

        // 在编辑框的输入文本变化前触发
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {}

        // 在编辑框的输入文本变化时触发
        public void onTextChanged(CharSequence s, int start, int before, int count) {}

        // 在编辑框的输入文本变化后触发
        public void afterTextChanged(Editable s) {
            String str = s.toString();
            // 发现输入回车符或换行符
            if (str.contains("\r") || str.contains("\n")) {
                // 去掉回车符和换行符
                mThisView.setText(str.replace("\r", "").replace("\n", ""));
                if (mNextView != null) {
                    // 让下一个视图获得焦点,即将光标移到下个视图
                    mNextView.requestFocus();
                    // 如果下一个视图是编辑框,则将光标自动移到编辑框的文本末尾
                    if (mNextView instanceof EditText) {
                        EditText et = (EditText) mNextView;
                        // 让光标自动移到编辑框内部的文本末尾
                        // 方式一:直接调用EditText的setSelection方法
                        et.setSelection(et.getText().length());
                        // 方式二:调用Selection类的setSelection方法
                        //Editable edit = et.getText();
                        //Selection.setSelection(edit, edit.length());
                    }
                }
            }
        }
    }

2.菜单Menu

查阅菜单Menu的开发文档:
类结构的分析:
public interface Menu
控件的作用及使用方法:
Menu作为一个接口,没有实际的外形,不能直接使用。Android的菜单主要有两种,一种是选项菜单OptionsMenu,一种是上下文菜单ContextMenu,使用方法大同小异:为菜单设置布局,并为菜单项设置相关的回调方法即可,菜单布局文件应放在res/menu目录下。菜单布局文件示例如下:

<menu xmlns:android="http://schemas.android.com/apk/res/android" >
    <item
        android:id="@+id/item1"
        android:orderInCategory="1"
        android:title="菜单项1"/>
    <item
        android:id="@+id/item2"
        android:orderInCategory="1"
        android:title="菜单项2"/>
</menu>

默认的外形展示:
在这里插入图片描述

①使用上下文菜单ContextMenu要求覆盖Activity的以下方法:
void onCreateContextMenu(ContextMenu, View, ContextMenu.ContextMenuInfo) 指定XML菜单布局文件。
boolean onContextItemSelected(MenuItem item) 响应不同菜单项被点击,即菜单项的功能函数。
接着需要在Activity的onResume方法里为需要的控件调用registerForContextMenu注册上下文菜单,在onPause里调用unregisterForContextMenu取消菜单。使用方法示例:

    // 在上下文菜单的菜单界面创建时调用
    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
        // 从menu_option.xml中构建菜单界面布局
        getMenuInflater().inflate(R.menu.menu, menu);
    }

    // 在上下文菜单的菜单项选中时调用
    @Override
    public boolean onContextItemSelected(MenuItem item) {
        int id = item.getItemId(); // 获取菜单项的编号
        //TODO:根据id处理不同菜单项
        Toast.makeText(this, "选中的菜单项id为:"+id, Toast.LENGTH_SHORT).show();
        return true;
    }

于是便可以通过长按该组件调出上下文菜单页面了,当然也可以调用 public void openContextMenu(View view) 打开。

选项菜单OptionsMenu并不是一个类或者接口,而是通过重写Activity的两个方法来实现菜单功能的。选项菜单分两种打开方式:按手机的菜单键(现在手机应该没有此键了吧)、在代码中调用 public void openOptionsMenu() 手动打开,调用 public void closeOptionsMenu() 手动关闭。Activity需要重写的两个方法: public boolean onCreateOptionsMenu(Menu menu)public boolean onOptionsItemSelected(MenuItem item) 分别设置菜单布局,注册菜单项的监听器,使用方式同上下文菜单,故不再赘述。

在这里插入图片描述

四、适配器视图AdapterView的初步认识和下拉框Spinner的使用

1.适配器视图AdapterView的初步认识

在日常生活中,我们会处理大量的列表或者网格类型的数据,他们的特征是数据项很多,并且每一个展示的数据项所用的格式一样,但是每一个数据项的具体内容又各不相同。基于以上特征,我们需要一种能展示多项数据,占用内存小,展示速度快,展示格式统一的方法。
适配器视图AdapterView是视图组ViewGroup的子类,它的间接子类有:AdapterViewFlipper,AppCompatSpinner,ExpandableListView,,Gallery,,GridView, ListView,Spinner,StackView,这些视图便能实现以上对于格式统一,数据不同的需求。
这些视图的展示内容由适配器 Adapter决定,它的间接子类有:ArrayAdapter, BaseAdapter, CursorAdapter, HeaderViewListAdapter, ListAdapter, ResourceCursorAdapter, SimpleAdapter, SimpleCursorAdapter, SpinnerAdapter, ThemedSpinnerAdapter, WrapperListAdapter。
适配器对象充当AdapterView与原始数据之间的桥梁。 适配器提供对未处理的原始数据的访问, 适配器还负责通过XML布局文件为每个原始数据包装具体外观。
在这里介绍三个适配器:
数组适配器ArrayAdapter
public class ArrayAdapter
extends BaseAdapter implements Filterable, ThemedSpinnerAdapter

数组适配器只适合于数据项只有文本的情况,它的使用方法很简单,常用的构造函数为:
ArrayAdapter(Context context, int resource, T[] objects) context为上下文;resource为选中的数据项的布局文件id,布局里面只有一个文本视图TextView;objects一般为String[]类型的数据。

简单适配器SimpleAdapter
public class SimpleAdapter
extends BaseAdapter implements Filterable, ThemedSpinnerAdapter

简单适配器适合于有图片和文本一起显示的情况,构造函数为:
SimpleAdapter(Context context, List<? extends Map
<String, ?>> data, int resource, String[] from, int[] to)
,共5个参数:
context为上下文。
data可以是ArrayList对象,ArrayList中的每个条目都对应于列表中的一行,用于保存图片和文本的配对信息。
resource是一个XML文件id,该文件用于显示每个条目的视图。
from是添加到与每个项目相关联的映射中的列名列表。
to是应该在“from”参数中显示列的视图。

基本适配器BaseAdapter
public abstract class BaseAdapter
extends Object implements ListAdapter, SpinnerAdapter

Adapter通用基类,可用于 ListView (通过实现专门的 ListAdapter接口)和 Spinner (通过实现专门的 SpinnerAdapter接口)。从它派生的类需要实现三个主要的方法:
构造函数:指定适配器需要处理的原始数据。
getCount:获取数据项总数。
getView:由XML布局文件包装数据项的展示视图,并对数据项内部控件做业务处理。

以上三个适配器的具体使用方法将通过下拉框Spinner展示。

2.下拉框Spinner

查阅下拉框Spinner的开发文档:
默认的外形展示:
Spinner的展示方式有两种,通过属性spinnerMode设置:
android:spinnerMode=“dialog” 以对话框的形式展示
android:spinnerMode=“dropdown” 以下拉列表形式展示
类结构的分析:
public class Spinner
extends AbsSpinner implements DialogInterface.OnClickListener
已知的直接子类
AppCompatSpinner
控件的作用及使用方法:
下拉框Spinner根据布局文件展示多个选项,用户便从其中选择,进而触发选项的回调方法,其功能和用法都与菜单类似。

下面介绍三个适配器的具体用法:
数组适配器:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initSpinner();
    }
         // 初始化下拉框
    private void initSpinner() {
        // 声明一个下拉框的数组适配器(item_select为蓝色字体)
        ArrayAdapter<String> dataAdapter = new ArrayAdapter<>(this,
                R.layout.item_select, dataArray);
        // 设置下拉框列表每一项数据的布局样式(item_dropdown为红色字体)
        dataAdapter.setDropDownViewResource(R.layout.item_dropdown);
        // 从布局文件中获取下拉框
        Spinner sp = findViewById(R.id.sp_dropdown);
        // 设置下拉框的标题
        sp.setPrompt("请选择数据");
        // 设置下拉框的数组适配器
        sp.setAdapter(dataAdapter);
        // 设置下拉框默认显示第一项
        sp.setSelection(0);
        // 给下拉框设置选择监听器,一旦用户选中某一项,就触发监听器的onItemSelected方法
        sp.setOnItemSelectedListener(new MySelectedListener());
    }

    // 定义下拉列表需要显示的文本数组
    private String[] dataArray = {"数据1", "数据2", "数据3", "数据4", "数据5", "数据6"};
    // 定义一个选择监听器,它实现了接口OnItemSelectedListener
    class MySelectedListener implements AdapterView.OnItemSelectedListener {
        // 选择事件的处理方法,其中arg2代表选择项的序号
        public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
            Toast.makeText(MainActivity.this, "您选择的是" + dataArray[arg2], Toast.LENGTH_LONG).show();
        }

        // 未选择时的处理方法,通常无需处理
        public void onNothingSelected(AdapterView<?> arg0) {}
    }
}

效果图:
在这里插入图片描述
简单适配器:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initSpinnerForSimpleAdapter();
    }


    // 定义下拉列表需要显示的文本数组
    private String[] dataArray = {"数据1:虎牙", "数据2:游览器", "数据3:QQ",
            "数据4:AD", "数据5:AS", "数据6:keil"};
    // 定义下拉列表需要显示的图标数组
    private int[] iconArray = {R.drawable.data1, R.drawable.data2, R.drawable.data3,
            R.drawable.data4, R.drawable.data5, R.drawable.data6};
    // 初始化下拉框,演示简单适配器
    private void initSpinnerForSimpleAdapter() {
        // 声明一个映射对象的队列,用于保存图标与名称配对信息
        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
        // iconArray是图标数组,starArray是名称数组
        for (int i = 0; i < iconArray.length; i++) {
            Map<String, Object> item = new HashMap<String, Object>();
            item.put("icon", iconArray[i]);
            item.put("name", dataArray[i]);
            // 把一个图标与名称的配对映射添加到队列当中
            list.add(item);
        }
        // 声明一个下拉列表的简单适配器,其中指定了图标与文本两组数据
        SimpleAdapter starAdapter = new SimpleAdapter(this, list,
                R.layout.item_simple, new String[]{"icon", "name"},
                new int[]{R.id.iv_icon, R.id.tv_name});
        // 设置简单适配器的布局样式
        starAdapter.setDropDownViewResource(R.layout.item_simple);
        // 从布局文件中获取名叫sp_icon的下拉框
        Spinner sp = findViewById(R.id.sp_icon);
        // 设置下拉框的标题
        sp.setPrompt("请选择数据");
        // 设置下拉框的简单适配器
        sp.setAdapter(starAdapter);
        // 设置下拉框默认显示第一项
        sp.setSelection(0);
        // 给下拉框设置选择监听器,一旦用户选中某一项,就触发监听器的onItemSelected方法
        sp.setOnItemSelectedListener(new MySelectedListener());
    }
    // 定义一个选择监听器,它实现了接口OnItemSelectedListener
    class MySelectedListener implements AdapterView.OnItemSelectedListener {
        // 选择事件的处理方法,其中arg2代表选择项的序号
        public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
            Toast.makeText(MainActivity.this, "您选择的是" + dataArray[arg2], Toast.LENGTH_LONG).show();
        }

        // 未选择时的处理方法,通常无需处理
        public void onNothingSelected(AdapterView<?> arg0) {}
    }
}

效果图
在这里插入图片描述

基本适配器: 限于篇幅,在以后的文章:常用控件(高级篇)再展示了。

在这里插入图片描述


总结

本文总结了常用控件的基础知识:复合按钮CompoundButton的常见子类;进度展示控件;编辑框EditText的定制使用,菜单Menu的用法;最后给出适配器视图AdapterView的初步认识和下拉框Spinner的使用。下一篇文章会把剩下的两大组件总结完,从而开始入门Android。

总算开始上班了,不过工资嘛,用委婉的话说是上升空间还很大🤣。。。最后问大家一个问题:你喜欢听5年前的老歌还是现在的新歌呢?

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 11
    评论
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

搬砖工人_0803号

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值