第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

全部開發(fā)者教程

Android 入門教程

菜單類控件
菜單:Menu
并發(fā)編程
多線程

本節(jié)我們將學(xué)習(xí) Android 提供的下拉選擇框——Spinner,它也是 Adapter 的??汀2粌H僅是在 Android 端,在 Windows 上我們也經(jīng)常會看到 Spinner 類型的樣式。通常它是以下拉的形式存在,Spinner 在下拉列表中包含很多可供用戶選擇的選項,用戶可以通過點擊 Spinner 完成選擇。

1. Spinner 的特性

Spinner 的功能是提供一個選擇框,默認情況下 Spinner 展示的是當前的選項,點擊 Spinner 控件將會展示所有可選項供用戶點擊選擇。Spinner 在很多情況下并不是獨立存在的,很有可能當前的 Spinner 的選項需要依賴于前一個 Spinner 的選擇結(jié)果。

比如我們常見的地址選擇頁面,首先一個 Spinner 展示所有的省份,在你選擇省份之后,第二個 Spinner 拿到你的選項生成相應(yīng)的城市選項,所以 Spinner 是一個常用并且非常靈活的控件,它的實現(xiàn)依然需要 Adapter。

2. Spinner 的基本用法

2.1 Spinner 的相關(guān)屬性

  • android:gravity:
    設(shè)置 Spinner 內(nèi)部 item 的對齊方式
  • android:dropDownHorizontalOffset:
    設(shè)置下拉選擇框的水平偏移距離
  • android:dropDownVerticalOffset:
    設(shè)置下拉選擇框的垂直偏移距離
  • android:dropDownWidth:
    設(shè)置下拉列表框的寬度
  • android:dropDownSelector:
    下拉選擇框被選中時的背景樣式
  • android:popupBackground:
    設(shè)置下拉選擇框的背景樣式
  • android:prompt:
    設(shè)置選擇框的提示信息,此屬性不能直接設(shè)置 String,而必須設(shè)置一個 string 資源
  • android:spinnerMode:
    選擇框的模式,有兩個可選值:
    • dialog: 對話框風(fēng)格
    • dropdown: 下拉列表風(fēng)格
  • android:entries:
    通過 string 資源的方式設(shè)置下拉選擇項

2.2 Spinner 選擇事件監(jiān)聽器

  • setOnItemSelectedListener:
    為 Spinner 設(shè)置選中事件回調(diào),該接口中包含兩個回調(diào)方法:

    • onItemSelected:
      當 Spinner 中某個選項被選中時回調(diào)該方法,在用戶選擇了 Spinner 中不同于當前已選中的選項或者當前沒有任何選項選中時,系統(tǒng)會回調(diào)該方法。此時可以通過getItemAtPosition(position)來獲取當前被選中的 item 對象,比如文章開頭提到的選城市的功能就需要通過此接口實時獲取用戶的選擇。
    • onNothingSelected:
      這個回調(diào)方法用的不較少,它是在選項消失的時候被系統(tǒng)回調(diào)的,選項消失通常發(fā)生在數(shù)據(jù)清空的時候

    特別說明: 雖然 Spinner 和 ListView、GridView 一樣都是 AdapterView,但是在 Spinner 中不能使用setOnItemClickListener,如果使用系統(tǒng)會拋出以下異常:

setOnItemClickListener cannot be used with a spinner

所以在 Spinner 中我們要用setOnItemSelectedListener來監(jiān)聽選擇事件。

3. Spinner 使用示例

本節(jié)仍然采用“水果列表”的示例,之前是通過 ListView、GridView 將水果類型和圖片直接羅列在屏幕上。而本節(jié)只會在屏幕上暴露出一個選項,在點擊水果的時候彈出所有的選擇項等待用戶選擇,由于 Adapter 完善的 MVC 模式,可以繼續(xù)在之前的代碼上簡單修改即可。

3.1 定義 Spinner 布局

布局文件很簡單,直接在根布局中放置一個 Spinner 即可:

<?xml version="1.0" encoding="utf-8"?>
<Spinner xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/spinner"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center" />

Spinner 的屬性都比較好理解,大家可以在閱讀的同時自行添加嘗試。

3.2 編寫 Adapter

和上一節(jié)的 GridView 一樣,我們通過修改 MyAdapter 的getCountgetView兩個回調(diào)方法來實現(xiàn)水果列表的擴展,代碼如下:

package com.emercy.myapplication;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;


public class MyAdapter extends BaseAdapter {

    private Context mContext;
    private String[] mName;
    private int[] mResId;

    public MyAdapter(Context context) {
        mContext = context;
    }

    public void setData(String[] name, int[] resId) {
        mName = name;
        mResId = resId;
    }


    @Override
    public int getCount() {
        return mName.length * 10;
    }

    @Override
    public Object getItem(int position) {
        return null;
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        // 針對convertView做一個簡單的優(yōu)化
        if (convertView == null) {
            convertView = LayoutInflater.from(mContext).inflate(R.layout.list_view, null);
        }
        TextView name = convertView.findViewById(R.id.textView);
        ImageView image = convertView.findViewById(R.id.imageView);
        name.setText(mName[position % mName.length]);
        image.setImageResource(mResId[position % mResId.length]);
        return convertView;
    }
}

細心的讀者可能會注意到,相比上一節(jié)的例子,在getView當中有一個小小的改動:

 // 針對convertView做一個簡單的優(yōu)化
        if (convertView == null) {
            convertView = LayoutInflater.from(mContext).inflate(R.layout.list_view, null);
        }

這個改動是一個簡單的優(yōu)化,可以減少每次 inflate 造成的性能消耗,這樣 Adapter 只會在第一次去做 inflate,而后續(xù)的getView()回調(diào)將直接復(fù)用之前的convertView。

3.3 定義數(shù)據(jù)源

數(shù)據(jù)源分兩部分:水果名稱和水果圖片,分別用一個 String 數(shù)組和 int 數(shù)組存放,如下:

String[] mDataName = {"蘋果", "梨", "香蕉", "桃子", "西瓜", "荔枝", "橘子"};
    int[] mDataImage = {R.drawable.apple, R.drawable.pear, R.drawable.banana, R.drawable.peach,
            R.drawable.watermelon, R.drawable.lychee, R.drawable.orange, R.drawable.orange};

然后通過 MyAdapter 提供的設(shè)置數(shù)據(jù)的接口設(shè)置給 Adapter:

        adapter.setData(mDataName, mDataImage);

3.4 完成 MainActivity

整體的 MainActivity 和之前的邏輯大體相同,但是在 2.2 中我們提到過,Spinner 不能使用setOnItemClickListener接口,所以我們將事件監(jiān)聽器改成setOnItemSelectedListener,最終代碼如下:

package com.emercy.myapplication;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Spinner;
import android.widget.Toast;

public class MainActivity extends Activity {

    Spinner mSpinner;
    String[] mDataName = {"蘋果", "梨", "香蕉", "桃子", "西瓜", "荔枝", "橘子"};
    int[] mDataImage = {R.drawable.apple, R.drawable.pear, R.drawable.banana, R.drawable.peach,
            R.drawable.watermelon, R.drawable.lychee, R.drawable.orange, R.drawable.orange};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mSpinner = findViewById(R.id.spinner);

        MyAdapter adapter = new MyAdapter(this);
        adapter.setData(mDataName, mDataImage);
        mSpinner.setAdapter(adapter);
        mSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                Toast.makeText(getApplicationContext(), mDataName[position / mDataImage.length], Toast.LENGTH_LONG).show();
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {
                Toast.makeText(getApplicationContext(), "onNothingSelected", Toast.LENGTH_LONG).show();
            }
        });
    }
}

運行之后頁面中只會有一個默認選項,點擊 Spinner 會彈出一個下拉框,任意選中一個會觸發(fā)onItemSelected回調(diào)方法并通過Toast打印當前選擇項。選擇完成之后,Spinner 會展示新選擇的水果名稱和圖片,效果如下:

Spinner示例

4. 小結(jié)

本節(jié)繼 ListView、GridView 之后又講解了一個采用 Adapter 實現(xiàn)的 UI 樣式,它主要適用的是下拉選擇的場景,相比 ListView、GridView 它更省空間,只會在頁面上展示已選項,用戶需要通過點擊才能調(diào)起所有的選項。

Spinner 的屬性也比較簡單,需要特別注意的是它不支持設(shè)置setOnItemClickListener接口,取而代之的是setOnItemSelectedListener接口,最后我們?nèi)匀徊捎谩八斜怼钡睦友菔玖艘粋€ Spinner 的用法,當然對于 Spinner 還有很多花哨的樣式,大家可以在自己的例子代碼中設(shè)置看看,會有驚喜哦!