編輯:關於Android編程
another NumberPicker with more flexible attributes on Android platform
https://github.com/Carbs0126/NumberPickerView
在平時開發中會用到NumberPicker組件,但是默認風格的NumberPicker
具有一些不靈活的屬性,且定制起來比較麻煩,且缺少一些過渡動效,因此在應用開發時,一般采用自定義的控件來完成選擇功能。
<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxwPmdpZrTz0KGzrLn9z97WxsHLo6y+38zl0Ke5+7/JvPujujxiciAvPg0KPGEgaHJlZj0="/uploadfile/2016/0630/20160630093223441.gif">/uploadfile/2016/0630/20160630093223441.gif
截屏有些問題,使得看上去有點卡頓且divider顏色不一致,實際效果很流暢。具體項目地址可見:
https://github.com/Carbs0126/GregorianLunarCalendar
NumberPickerView
是一款與android原生NumberPicker
具有類似界面以及類似功能的View
。
主要功能同樣是從多個候選項中通過上下滾動的方式選擇需要的選項,但是與NumberPicker
相比較,有幾個主要不同點,下面是兩者的不同之處。
setWrapSelectorWheel()
方法),會有“暫時顯示不出部分選項”的問題; 選中位置沒有文字說明; 代碼中不能控制選項滑動滾動到某一item;
wrap_content
,支持item的padding 提供多種屬性,優化UI效果 在滑動過程中不響應onValueChanged()
點擊上下單元格,可以自動滑動到對應的點擊對象。 兼容NumberPicker的重要方法和接口:
兼容的方法有:
setOnValueChangedListener()
setOnScrollListener()
setDisplayedValues()/getDisplayedValues()
setWrapSelectorWheel()/getWrapSelectorWheel()
setMinValue()/getMinValue()
setMaxValue()/getMaxValue()
setValue()/getValue()
兼容的內部接口有:
OnValueChangeListener
OnScrollListener
1.導入至工程
compile 'cn.carbswang.android:NumberPickerView:1.0.2'
或者
cn.carbswang.android
NumberPickerView
1.0.2
pom
2.通過布局聲明NumberPickerView
3.Java代碼中使用:
1)若設置的數據(String[] mDisplayedValues)不會再次改變,可以使用如下方式進行設置:(與NumberPicker的設置方式一致)
picker.setMinValue(minValue);
picker.setMaxValue(maxValue);
picker.setValue(value);
2)若設置的數據(String[] mDisplayedValues)會改變,可以使用如下組合方式進行設置:(與NumberPicker的更改數據方式一致)
int minValue = getMinValue();
int oldMaxValue = getMaxValue();
int oldSpan = oldMaxValue - minValue + 1;
int newMaxValue = display.length - 1;
int newSpan = newMaxValue - minValue + 1;
if (newSpan > oldSpan) {
setDisplayedValues(display);
setMaxValue(newMaxValue);
} else {
setMaxValue(newMaxValue);
setDisplayedValues(display);
}
或者直接使用NumberPickerView提供的方法:
refreshByNewDisplayedValues(String[] display)
使用此方法時需要注意保證數據改變前後的minValue值不變。
4.另外,NumberPickerView提供了平滑滾動的方法:
public void smoothScrollToValue(int fromValue, int toValue, boolean needRespond)
此方法與setValue(int)
方法相同之處是可以動態設置當前顯示的item,不同之處在於此方法可以使NumberPickerView
平滑的從滾動,即從fromValue
值挑選最近路徑滾動到toValue
,第三個參數needRespond
用來標識在滑動過程中是否響應onValueChanged
回調函數。因為多個NumberPickerView
在聯動時,很可能不同的NumberPickerView
的停止時間不同,如果在此時響應了onValueChanged
回調,就可能再次聯動,造成數據不准確,將needRespond
置為false
,可避免在滑動中響應回調函數。
另外,在使用此方法或者間接調用此方法時,需要注意最好不要在onCreate(Bundle savedInstanceState)
方法中調用,因為scroll動畫需要一定時間,如需確要在onCreate(Bundle savedInstanceState)
中調用,請使用如下方式:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//代碼省略
mNumberPickerView.post(new Runnable() {
@Override
public void run() {
//調用smoothScrollToValue()等方法的代碼
}
});
}
5.各項自定義屬性的說明
//顯示的條目個數,默認3個
//是否顯示兩條divider,默認顯示
//兩條divider的顏色
//divider距左側的距離
//divider距右側的距離
//divider的高度
//未選中文字的顏色
//選中文字的顏色
//中間偏右側說明文字的顏色
//未選中文字的大小
//選中文字的大小
//說明文字的大小
//文字內容,stringarray類型
//最小值,同setMinValue()
//最大值,同setMaxValue()
//設置是否wrap,同setWrapSelectorWheel
//設置說明文字
//空行的顯示文字,默認不顯示任何文字。只在WrapSelectorWheel==false是起作用
//說明文字距離左側的距離,"左側"是指文字array最寬item的右側
//說明文字距離右側的距離
//item的水平padding,用於wrap_content模式
//item的豎直padding,用於wrap_content模式
//以下屬性用於在wrap_content模式下,改變內容array並且又不想讓控件"跳動",那麼就可以設置所有改變的內容的最大寬度
//可能達到的最大寬度,包括說明文字在內,最大寬度只可能比此String的寬度更大
//可能達到的最大寬度,不包括說明文字在內,最大寬度只可能比此String的寬度+說明文字+說明文字marginstart +說明文字marginend 更大
//說明文字的最大寬度
一般情況下,我們只使用NumberPicker對文字進行選擇,很少涉及到添加不同的View甚至是圖片,因此,NumberPickerView只針對傳入的String[] 類型的內容通過onDraw(Canvas canvas)函數進行顯示。這裡主要涉及三個知識點:
Android的framework中帶有一個工具類Scroller,此類的功能是根據輸入值以及當前持續的時間,配合插值計算器,計算出當前的輸出值。輸入值一般是速度和坐標值,輸出值是坐標值,舉例來說,可以將其想像成高中物理根據初始速度、加速度和運行時間求取當前路程。Scroller的實現比較巧妙,它不會在startScroll()
後去計算當前“路程”,而是只記錄“出發”時的各種狀態,只有當外部需要知道此時滑動到的位置時,才會去根據時間以及插值來進行計算,這種設計避免了另起線程實時計算等問題。
那麼問題來了,什麼時候去獲取scroller中當前的坐標值呢?閱讀View類的源碼,我們可以看到在View的boolean draw(Canvas canvas, ViewGroup parent, long drawingTime)
函數中,有如下代碼:
if (!drawingWithRenderNode) {
computeScroll();
sx = mScrollX;
sy = mScrollY;
}
即在繪制view時,先調用computeScroll()
,因此我們可以在computeScroll()
函數重新設置或刷新當前的坐標,並在onDraw(Canvas canvas)
函數中根據當前的狀態重新繪制此view。
computeScroll()
的使用方法通常為:
@Override
public void computeScroll() {
//如果Scroller仍然在滾動
if (mScroller.computeScrollOffset()) {
//獲取mScroller中的值並計算和記錄,如 mGlobalY = mScroller.getCurrY();
//刷新
postInvalidate();
}
}
在NumberPickerView中,我使用一個globalY值來記錄當前滾動到的坐標,並通過與Item的高度相除,計算當前應該顯示的item的偏移值,從而畫出當前只在顯示區域的item。
繪制的思路明確了,再來看滑動跟隨手指移動以及fling效果。這兩者均是通過override onTouchEvent(MotionEvent event)
函數來實現的,不過實現的具體過程稍有不同:
(1). 跟隨手指滑動是復寫了MotionEvent.ACTION_MOVE
的情況,根據當前手指移動的坐標值,計算globalY值,並刷新顯示。
(2). fling效果是通過VelocityTracker
工具類實現的,此工具類可以根據接收的兩個連續發出的MotionEvent
來獲取當前的滑動速度,若速度大於阈值,則將初始坐標值、VelocityTracker
計算獲取的速度傳遞給Scroller.fling(...)
函數,此時再次刷新,即可通過computeScroll()
函數,獲取當前globalY值,進而更新繪圖。
為了實現自動校准,我在每次手指Up或者Scroller開始Fling時,均通過handler發送refresh消息,在接受到此消息時,計算當前位置是否處於被校准的位置,如果否,則計算需要滑動的位移,並將值傳遞給Scroller,進而進行校准滑動。當確保已經校准後,暫停發送refresh消息。
漸變UI效果同樣是通過計算當前滑動的坐標以及某個item與中間顯示位置的差值比例,來確定此item中的字體大小以及顏色。
要替代項目中使用的NumberPicker,只需要將涉及NumberPicker的代碼(如回調中傳入了NumberPicker、使用了NumberPicker的內部接口)改為NumberPickerView即可。
刷機精靈是Android手機一鍵刷機輔助工具,可以幫助玩家更快速完成刷機操作,很多用戶對刷機精靈的使用不是很了解,那麼刷機精靈應該如何操作呢,一起來和小編
本文實例為大家分享了Android app應用實現多語言切換功能,供大家參考,具體內容如下1.添加多語言文件 在不同的 value 文件夾下(例如 value 、valu
1、概述之前寫了一個Android 高仿 QQ5.0 側滑菜單效果 自定義控件來襲 ,恰逢QQ5.2又加了一個右側菜單,剛好看了下DrawerLayout,一方面官方的東
今天老大安排一個任務叫我獲取手機中應用耗電排行(時間是前天晚上7點到第二天早上10點),所以在網上各種搜索,沒想到這種資料還是很多的,發現了一個主要的類:PowerPro