Carbs0126 / NumberPickerView
- суббота, 2 июля 2016 г. в 03:12:23
Java
another NumberPicker with more flexible attributes on Android platform
another NumberPicker with more flexible attributes on Android platform
在Android项目的开发中会用到NumberPicker组件,但是默认风格的NumberPicker
具有一些不灵活的属性,且定制起来比较麻烦,且缺少一些过渡动效,因此在应用开发时,一般采用自定义的控件来完成选择功能。
NumberPickerView的实际应用,一款可以选择公历/农历日期的View,且公农历自由切换。
截屏有些问题,使得看上去有点卡顿且divider颜色不一致,实际效果很流畅。具体项目地址可见:
https://github.com/Carbs0126/GregorianLunarCalendar
NumberPickerView
是一款与android原生NumberPicker
具有类似界面以及类似功能的View
。
主要功能同样是从多个候选项中通过上下滚动的方式选择需要的选项,但是与NumberPicker
相比较,有几个主要不同点,下面是两者的不同之处。
setWrapSelectorWheel()
方法),会有“暂时显示不出部分选项”的问题;wrap_content
,支持item的paddingonValueChanged()
兼容的方法有:
setOnValueChangedListener()
setOnScrollListener()
setDisplayedValues()/getDisplayedValues()
setWrapSelectorWheel()/getWrapSelectorWheel()
setMinValue()/getMinValue()
setMaxValue()/getMaxValue()
setValue()/getValue()
兼容的内部接口有:
OnValueChangeListener
OnScrollListener
1.导入至工程
compile 'cn.carbswang.android:NumberPickerView:1.0.2'
或者
<dependency>
<groupId>cn.carbswang.android</groupId>
<artifactId>NumberPickerView</artifactId>
<version>1.0.2</version>
<type>pom</type>
</dependency>
2.通过布局声明NumberPickerView
<cn.carbswang.android.numberpickerview.library.NumberPickerView
android:id="@+id/picker"
android:layout_width="wrap_content"
android:layout_height="240dp"
android:layout_centerHorizontal="true"
android:layout_marginTop="20dp"
android:background="#11333333"
android:contentDescription="test_number_picker_view"
app:npv_ItemPaddingHorizental="5dp"
app:npv_ItemPaddingVertical="5dp"
app:npv_ShowCount="5"
app:npv_TextSizeNormal="16sp"
app:npv_TextSizeSelected="20sp"
app:npv_WrapSelectorWheel="true"/>
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.各项自定义属性的说明
<declare-styleable name="NumberPickerView">
<attr name="npv_ShowCount" format="reference|integer" />//显示的条目个数,默认3个
<attr name="npv_ShowDivider" format="reference|boolean" />//是否显示两条divider,默认显示
<attr name="npv_DividerColor" format="reference|color" />//两条divider的颜色
<attr name="npv_DividerMarginLeft" format="reference|dimension" />//divider距左侧的距离
<attr name="npv_DividerMarginRight" format="reference|dimension" />//divider距右侧的距离
<attr name="npv_DividerHeight" format="reference|dimension" />//divider的高度
<attr name="npv_TextColorNormal" format="reference|color" />//未选中文字的颜色
<attr name="npv_TextColorSelected" format="reference|color" />//选中文字的颜色
<attr name="npv_TextColorHint" format="reference|color" />//中间偏右侧说明文字的颜色
<attr name="npv_TextSizeNormal" format="reference|dimension" />//未选中文字的大小
<attr name="npv_TextSizeSelected" format="reference|dimension" />//选中文字的大小
<attr name="npv_TextSizeHint" format="reference|dimension" />//说明文字的大小
<attr name="npv_TextArray" format="reference" />//文字内容,stringarray类型
<attr name="npv_MinValue" format="reference|integer" />//最小值,同setMinValue()
<attr name="npv_MaxValue" format="reference|integer" />//最大值,同setMaxValue()
<attr name="npv_WrapSelectorWheel" format="reference|boolean" />//设置是否wrap,同setWrapSelectorWheel
<attr name="npv_HintText" format="reference|string" />//设置说明文字
<attr name="npv_EmptyItemHint" format="reference|string" />//空行的显示文字,默认不显示任何文字。只在WrapSelectorWheel==false是起作用
<attr name="npv_MarginStartOfHint" format="reference|dimension" />//说明文字距离左侧的距离,"左侧"是指文字array最宽item的右侧
<attr name="npv_MarginEndOfHint" format="reference|dimension" />//说明文字距离右侧的距离
<attr name="npv_ItemPaddingHorizental" format="reference|dimension" />//item的水平padding,用于wrap_content模式
<attr name="npv_ItemPaddingVertical" format="reference|dimension" />//item的竖直padding,用于wrap_content模式
//以下属性用于在wrap_content模式下,改变内容array并且又不想让控件"跳动",那么就可以设置所有改变的内容的最大宽度
<!--just used to measure maxWidth for wrap_content without hint,
the string array will never be displayed.
you can set this attr if you want to keep the wraped numberpickerview
width unchanged when alter the content list-->
<attr name="npv_AlternativeTextArrayWithMeasureHint" format="reference" />//可能达到的最大宽度,包括说明文字在内,最大宽度只可能比此String的宽度更大
<attr name="npv_AlternativeTextArrayWithoutMeasureHint" format="reference" />//可能达到的最大宽度,不包括说明文字在内,最大宽度只可能比此String的宽度+说明文字+说明文字marginstart +说明文字marginend 更大
<!--the max length of hint content-->
<attr name="npv_AlternativeHint" format="reference|string" />//说明文字的最大宽度
</declare-styleable>
Scroller
+ VelocityTracker
+ onDraw(Canvas canvas)
Handler
刷新当前位置
渐变UI效果同样是通过计算当前滑动的坐标以及某个item与中间显示位置的差值比例,来确定此item中的字体大小以及颜色。
要替代项目中使用的NumberPicker,只需要将涉及NumberPicker的代码(如回调中传入了NumberPicker、使用了NumberPicker的内部接口)改为NumberPickerView即可。
万水千山总是情,来个Star行不行?
欢迎大家不吝指教。 email: yeah0126@yeah.net
Copyright 2016 Carbs.Wang (NumberPickerView)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.