Android仿Boss直聘文本日期混合滾輪選擇器示例
1、需求分析
GitHub上面有一款iOS風(fēng)格的滾輪選擇器Android-PickerView,它分為時(shí)間選擇器代碼TimePickerView和選項(xiàng)選擇器OptionsPickerView,不但可以選擇時(shí)間日期,可以選擇我們自定義的數(shù)據(jù),比如性別、年齡等。我一直都用它。直到最近遇到了一個(gè)需求,它的選項(xiàng)里面既有文字也有時(shí)間,大體效果如Boss直聘添加項(xiàng)目經(jīng)驗(yàn)中的時(shí)間選擇功能:


從圖中我們可以看出,除了常規(guī)的年份和月份的選擇,選項(xiàng)中還包含了文本。其中,最新的時(shí)間是“至今”,而最早可供選擇的時(shí)間則是“1900以前”。所以看起來(lái)似乎TimePickerView和OptionsPickerView都無(wú)法實(shí)現(xiàn)這個(gè)功能。我們都沮喪地認(rèn)為這下要么得自定義控件,要么得修改Android-PickerView這個(gè)庫(kù)了。但我轉(zhuǎn)念一想,為什么要把“時(shí)間選擇”和“選項(xiàng)選擇”分得那么開(kāi)呢?時(shí)間選擇其實(shí)也是選項(xiàng)選擇的一種嘛。比如我要選擇2017年12月,那就是從年份中選擇2017,從月份中選擇12。只要設(shè)置好一級(jí)選項(xiàng)和二級(jí)選項(xiàng)就可以了。
2、選項(xiàng)結(jié)構(gòu)分析
有了思路之后,我們來(lái)分析一下選項(xiàng)的數(shù)據(jù)結(jié)構(gòu)。年份可以分為3種情況:
- 最新年份,其實(shí)也是最新的時(shí)間:“至今”;
- 常規(guī)的年份:1990~當(dāng)前年份(2018);
- 最早的年份,也就是最早的時(shí)間:“1990以前”。
我在Boss直聘的基礎(chǔ)上加了一些限制:當(dāng)前年份下對(duì)應(yīng)的可供選擇的月份范圍只能是從月到當(dāng)前月份,比如現(xiàn)在是2018年2月,那么選好年份為2018后,月份就只能選擇1和2。這樣一來(lái),月份就有四種情況了:
- 最新月份:“至今”;
- 當(dāng)前年份下對(duì)應(yīng)的月份范圍:1~當(dāng)前月份;
- 完整的月份,即1~12;
- 最早月份:“1990以前”。
可以總結(jié)為如下的表格:
| 年份 | 月份 |
|---|---|
| 最新年份“至今” | 最新年份“至今” |
| 當(dāng)前年份 | 1~當(dāng)前月份 |
| 1990~當(dāng)前年份-1 | 月份1~12 |
| 最早年份“1990以前” | 最早月份“1990以前” |
3、書(shū)寫(xiě)代碼
在開(kāi)始寫(xiě)代碼之前,我建議你先去GitHub上看看Android-PickerView的使用用法,它使用了構(gòu)造者模式,用起來(lái)很簡(jiǎn)單。
現(xiàn)在,就開(kāi)始寫(xiě)我們的代碼了。
3.1 界面布局
布局就是一個(gè)按鈕,點(diǎn)擊后彈出滾輪選擇器,選好后點(diǎn)擊確認(rèn)即將數(shù)據(jù)在TextView上顯示出來(lái)。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:textAllCaps="false"
android:text="顯示PickerView"
android:onClick="showPickerView"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/tv_time"
android:textSize="16sp"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
3.2 Activity代碼
借助強(qiáng)大的PickerView,我們實(shí)現(xiàn)起來(lái)很簡(jiǎn)單,請(qǐng)看如下的代碼:
public class MultipleOptionActivity extends AppCompatActivity {
private TextView tvTime;
/**
* 完整的月份數(shù)據(jù)1~12
*/
private List<String> monthList = new ArrayList<>();
/**
* 滾輪選擇器中年份的選項(xiàng)數(shù)據(jù)
*/
private List<String> optionYears = new ArrayList<>();
/**
* 滾輪選擇器中月份的選項(xiàng)數(shù)據(jù)
*/
private List<List<String>> optionMonths = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_multiple_option);
tvTime = (TextView) findViewById(R.id.tv_time);
initData();
}
/**
* 初始化數(shù)據(jù)
*/
private void initData() {
//設(shè)置完整的月份數(shù)據(jù),即1~12
for (int i = 1; i <= 12; i++) {
monthList.add(String.valueOf(i));
}
Calendar calendar = Calendar.getInstance();
int curYear = calendar.get(Calendar.YEAR);
//月份獲取到的數(shù)據(jù)是0~11,所以要加1
int curMonth = calendar.get(Calendar.MONTH) + 1;
for (int i = curYear + 1; i >= 1989; i--) {
//對(duì)應(yīng)年份的月份數(shù)據(jù)集合
List<String> tempMonths = new ArrayList<>();
if (i == curYear + 1) {
//設(shè)置最新時(shí)間“至今”
optionYears.add("至今");
tempMonths.add("至今");
optionMonths.add(tempMonths);
} else if (i == curYear) {
//設(shè)置當(dāng)前年份及其對(duì)應(yīng)的月份
optionYears.add(String.valueOf(i));
for (int j = 1; j <= curMonth; j++) {
tempMonths.add(String.valueOf(j));
}
optionMonths.add(tempMonths);
} else if (i == 1989) {
//設(shè)置最早時(shí)間“1900以前”
optionYears.add("1990以前");
tempMonths.add("1990以前");
optionMonths.add(tempMonths);
} else {
//設(shè)置常規(guī)時(shí)間
optionYears.add(String.valueOf(i));
optionMonths.add(monthList);
}
}
}
/**
* 顯示滾輪
*
* @param view
*/
public void showPickerView(View view) {
OptionsPickerView multipleOp = new OptionsPickerView.Builder(this, new OptionsPickerView.OnOptionsSelectListener() {
@Override
public void onOptionsSelect(int options1, int options2, int options3, View v) {
if (options1 == 0 || options1 == optionYears.size() - 1) {
//選中最新和最早時(shí)間時(shí)直接顯示文字,不需要拼接月份
tvTime.setText(optionYears.get(options1));
} else {
//常規(guī)的時(shí)間,需要拼接年份和月份
tvTime.setText(new StringBuffer(optionYears.get(options1)).append("—").append(monthList.get(options2)));
}
}
}).setTitleText("請(qǐng)選擇時(shí)間")
.build();
multipleOp.setPicker(optionYears, optionMonths);
multipleOp.show();
}
}
代碼很少,注釋我也寫(xiě)得很清楚了,相信大家很容易理解。我們重點(diǎn)關(guān)注OptionsPickerView的setPicker方法,它可以傳入三個(gè)參數(shù),每個(gè)參數(shù)都是集合,但每個(gè)參數(shù)的類型都不同。第一個(gè)參數(shù)是List,第二個(gè)參數(shù)是List<List>,第三個(gè)參數(shù)是List<List<list>>??吹竭@里你就明白了,我們每個(gè)年份對(duì)應(yīng)的月份數(shù)據(jù)就是一個(gè)集合(當(dāng)然,集合大小不相同),比如年份2017,對(duì)應(yīng)的月份就是有著12個(gè)元素的集合。理清楚這一點(diǎn)之后,也就理解initData方法里面對(duì)數(shù)據(jù)的設(shè)置了。
最后在TextView中顯示數(shù)據(jù)時(shí)自然也要分類了,對(duì)于“至今”和“1990以前”我們至今顯示文本,其他的再拼接一下,看起來(lái)像是時(shí)間就行了。
看看我們最后實(shí)現(xiàn)的效果圖:

4、總結(jié)
在項(xiàng)目中使用一些好的第三方庫(kù)是可以大大節(jié)省我們的開(kāi)發(fā)時(shí)間的,但是在使用過(guò)程中也要靈活一點(diǎn)。比如我們?cè)谝粋€(gè)頁(yè)面中需要多次用到滾輪選擇器(比如選擇開(kāi)始時(shí)間和結(jié)束時(shí)間),那么每次都要設(shè)置一遍滾輪的樣式和寫(xiě)一次點(diǎn)擊事件也太麻煩了。這時(shí),我們就可以將滾輪樣式的設(shè)置代碼抽取出來(lái):
/**
* 設(shè)置滾輪樣式
* @return
*/
private OptionsPickerView.Builder createBuilder(){
OptionsPickerView.Builder builder = new OptionsPickerView.Builder(MultipleOptionActivity.this,this)
.setBgColor(ContextCompat.getColor(this,R.color.colorAccent))
.setSubmitText("確定")
.setCancelText("取消");
//下面可以繼續(xù)設(shè)置樣式
return builder;
}
然后顯示滾輪的時(shí)候只要這樣寫(xiě):
OptionsPickerView op = createBuilder().build(); op.setPicker(數(shù)據(jù)1,數(shù)據(jù)2); op.show();
點(diǎn)擊事件也可以封裝起來(lái),讓我們的Activity繼承OptionsPickerView.OnOptionsSelectListener,然后實(shí)現(xiàn)點(diǎn)擊事件:
/**
* 滾輪的監(jiān)聽(tīng)事件
* @param options1
* @param options2
* @param options3
* @param v
*/
@Override
public void onOptionsSelect(int options1, int options2, int options3, View v) {
switch (v.getId()){
//根據(jù)所點(diǎn)擊的控件Id來(lái)區(qū)分點(diǎn)擊事件
case R.id.btn_show:
break;
default:
break;
}
}
那么OptionsPickerView怎么獲取到點(diǎn)擊View的id的呢?我們?cè)谡{(diào)用show方法的時(shí)候傳入點(diǎn)擊View的對(duì)象就可以了。以上是我個(gè)人的一點(diǎn)心得,希望對(duì)大家有所幫助。
最后給一下源碼吧:源碼
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Android 實(shí)現(xiàn)IOS 滾輪選擇控件的實(shí)例(源碼下載)
- Android滾輪選擇時(shí)間控件使用詳解
- Android高仿IOS 滾輪選擇控件
- 輕松實(shí)現(xiàn)可擴(kuò)展自定義的Android滾輪時(shí)間選擇控件
- Android實(shí)現(xiàn)底部圖片選擇Dialog
- Android 實(shí)現(xiàn)IOS選擇拍照相冊(cè)底部彈出的實(shí)例
- Android 仿京東商城底部布局的選擇效果(Selector 選擇器的實(shí)現(xiàn))
- Android開(kāi)發(fā)中實(shí)現(xiàn)IOS風(fēng)格底部選擇器(支持時(shí)間 日期 自定義)
- Android實(shí)現(xiàn)底部滾輪式選擇彈跳框
相關(guān)文章
TabLayout+ViewPager2的簡(jiǎn)單使用詳解
這篇文章主要為大家詳細(xì)介紹了TabLayout+ViewPager2的簡(jiǎn)單使用,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-09-09
Android實(shí)現(xiàn)觸發(fā)html頁(yè)面的Button控件點(diǎn)擊事件方式
這篇文章主要介紹了Android實(shí)現(xiàn)觸發(fā)html頁(yè)面的Button控件點(diǎn)擊事件方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-03-03
Android?Flutter實(shí)現(xiàn)評(píng)分組件的示例代碼
在很多應(yīng)用中,我們都需要收集用戶的評(píng)分,比如商品滿意度、配送滿意度、應(yīng)用使用體驗(yàn)等等。本文就利用flutter_rating_bar實(shí)現(xiàn)簡(jiǎn)易的評(píng)分組件,感興趣的可以2022-11-11
Android 5.0+ 屏幕錄制實(shí)現(xiàn)的示例代碼
這篇文章主要介紹了Android 5.0+ 屏幕錄制實(shí)現(xiàn)的示例代碼,從 5.0 開(kāi)始,系統(tǒng)提供給了 app 錄制屏幕的一系列方法,不需要 root 權(quán)限,只需要用戶授權(quán)即可錄屏,相對(duì)來(lái)說(shuō)較為簡(jiǎn)單,感興趣的小伙伴們可以參考一下2018-05-05
Android EditText實(shí)現(xiàn)關(guān)鍵詞批量搜索示例
本篇文章主要介紹了Android EditText實(shí)現(xiàn)關(guān)鍵詞批量搜索示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-02-02
實(shí)現(xiàn)qq中按返回鍵返回桌面不退出程序的實(shí)例
下面小編就為大家?guī)?lái)一篇實(shí)現(xiàn)qq中按返回鍵返回桌面不退出程序的實(shí)例。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-04-04
Android RecyclerView點(diǎn)擊事件
這篇文章主要為大家詳細(xì)介紹了Android RecyclerView點(diǎn)擊事件的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-02-02
android編程實(shí)現(xiàn)系統(tǒng)圖片剪裁的方法
這篇文章主要介紹了android編程實(shí)現(xiàn)系統(tǒng)圖片剪裁的方法,涉及Android針對(duì)圖片的獲取、修改、保存等操作的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-11-11
Android實(shí)現(xiàn)聯(lián)動(dòng)下拉框二級(jí)地市聯(lián)動(dòng)下拉框功能
這篇文章主要介紹了Android實(shí)現(xiàn)聯(lián)動(dòng)下拉框二級(jí)地市聯(lián)動(dòng)下拉框功能,本文給大家分享思路步驟,給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-12-12

