一、之前在项目里面做的选择器,都是一种弹窗的模式,后来在新项目中遇到一个新需求,需要把选择器布局到Activity或者fragment上面,当时有点蒙蔽了,因为以前都是用第三方框架直接集成。但是既然产品提出了需求,必须要做,所以特地研究了第三方框架Android-PickerView,发现里面有一个自定义类WheelView,可以单独拿出来用,这样的话就好办的多了。
二、先上效果图
条件选择器:
日期选择器:
三、实现过程
1.首先添加依赖,在app的build.bradle文件里面添加
compile 'com.contrarywind:Android-PickerView:4.1.6'
自定义条件选择器的view,代码过程如下
/**
* Created by zzf on 2018/8/15.
*/
public class SelectorView extends LinearLayout{
WheelView wv_room;
private List<String> listRoom = new ArrayList<>();
private ArrayWheelAdapter<String> roomAdapter;
private OnSelectListener mListener;
public SelectorView(Context context) {
this(context,null);
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
getParent().requestDisallowInterceptTouchEvent(true);
return super.dispatchTouchEvent(ev);
}
public SelectorView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
View mView = LayoutInflater.from(context).inflate(R.layout.selector_view, this);
wv_room = mView.findViewById(R.id.wv_selector);
wv_room.setDividerColor(getResources().getColor(R.color.orange_b79a54));
wv_room.setTextColorCenter(getResources().getColor(R.color.orange_b79a54));
/*日*/
resetListString(listRoom, 1, 30);
roomAdapter = new ArrayWheelAdapter<>(listRoom);
wv_room.setAdapter(roomAdapter);
wv_room.setCurrentItem(0);
wv_room.setCyclic(false);
wv_room.setOnItemSelectedListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(int index) {
String currentRoom = listRoom.get(wv_room.getCurrentItem());
mListener.selectRoom(currentRoom);
}
});
}
private void resetListString(List<String> list, int start, int end) {
if (list != null) {
list.clear();
}
for (int i = start; i < end + 1; i++) {
list.add(i + "室");
}
}
public void setList(List list) {
if (null != listRoom) {
listRoom.clear();
listRoom = list;
}
if (null != roomAdapter) {
roomAdapter = null;
roomAdapter = new ArrayWheelAdapter<>(listRoom);
wv_room.setAdapter(roomAdapter);
wv_room.setCurrentItem(0);
wv_room.setCyclic(false);
wv_room.setOnItemSelectedListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(int index) {
String currentRoom = listRoom.get(wv_room.getCurrentItem());
mListener.selectRoom(currentRoom);
}
});
}
}
public interface OnSelectListener {
void selectRoom(String room);
}
public void setOnSelectListener(OnSelectListener listener) {
this.mListener = listener;
}
}
2.在Activity的xml布局里面引用如下(fragment用法相同)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<TextView
android:id="@+id/textview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:text="hah" />
<com.example.administrator.pickviewforactivity.customview.SelectorView
android:id="@+id/selector_view"
android:layout_width="match_parent"
android:layout_height="120dp"
android:layout_gravity="center"
android:layout_marginTop="20dp"
android:gravity="center"></com.example.administrator.pickviewforactivity.customview.SelectorView>
</LinearLayout>
3.Activity里面的代码逻辑
代码中记得对SelectorView 添加监听事件,否则会报空指针错误
**
* Created by zzf on 2018/8/27.
*/
public class SelectorActivity extends Activity implements SelectorView.OnSelectListener {
private SelectorView mSelectorView;
private TextView mTextView;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_selector);
mSelectorView = findViewById(R.id.selector_view);
mTextView = findViewById(R.id.textview);
mSelectorView.setOnSelectListener(this);
}
@Override
public void selectRoom(String room) {
mTextView.setText(room);
}
}
4.日期选择器的逻辑跟条件选择器差不多,只贴上自定义的代码就可以了
/**
* Created by zzf on 2018/8/15.
*/
public class ChooseBrithdayView extends LinearLayout {
WheelView wv_year;
WheelView wv_month;
WheelView wv_day;
private List<String> listYear = new ArrayList<>();
private List<String> listMonth = new ArrayList<>();
private List<String> listDay = new ArrayList<>();
private ArrayWheelAdapter<String> adapter;
private ArrayWheelAdapter<String> adapterMonth;
private ArrayWheelAdapter<String> adapterDay;
private OnSelectListener mListener;
public Date date;
public ChooseBrithdayView(Context context) {
this(context, null);
}
public ChooseBrithdayView(Context context, AttributeSet attrs) {
super(context, attrs);
View mView = LayoutInflater.from(context).inflate(R.layout.choose_brithday, this);
wv_year = (WheelView) mView.findViewById(R.id.wv_year);
wv_month = (WheelView) mView.findViewById(R.id.wv_month);
wv_day = (WheelView) mView.findViewById(R.id.wv_day);
wv_year.setDividerColor(getResources().getColor(R.color.orange_b79a54));
wv_month.setDividerColor(getResources().getColor(R.color.orange_b79a54));
wv_day.setDividerColor(getResources().getColor(R.color.orange_b79a54));
wv_year.setTextColorCenter(getResources().getColor(R.color.orange_b79a54));
wv_month.setTextColorCenter(getResources().getColor(R.color.orange_b79a54));
wv_day.setTextColorCenter(getResources().getColor(R.color.orange_b79a54));
Calendar calendar = Calendar.getInstance();
if (date != null) {
calendar.setTime(date);
}
int year = calendar.get(Calendar.YEAR);
int month = calendar.get(Calendar.MONTH);
int day = calendar.get(Calendar.DAY_OF_MONTH);
/*年*/
resetListString(listYear, Constant.SELECT_YEAR_START, year);
adapter = new ArrayWheelAdapter<>(listYear);
wv_year.setAdapter(adapter);
wv_year.setCurrentItem(year - Constant.SELECT_YEAR_START - 27);
wv_year.setCyclic(false);
/*月*/
resetListString(listMonth, 1, 12);
adapterMonth = new ArrayWheelAdapter<>(listMonth);
wv_month.setAdapter(adapterMonth);
wv_month.setCurrentItem(0);
wv_month.setCyclic(false);
/*日*/
resetListString(listDay, 1, 30);
adapterDay = new ArrayWheelAdapter<>(listDay);
wv_day.setAdapter(adapterDay);
wv_day.setCurrentItem(0);
wv_day.setCyclic(false);
wv_year.setOnItemSelectedListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(int index) {
int currentMonth = Integer.parseInt(listMonth.get(wv_month.getCurrentItem()));
if (currentMonth == 2) {
//2月
if (DateUtils.isLeapYear(Constant.SELECT_YEAR_START + index)) {
changeDay(29);
} else {
changeDay(28);
}
} else {
//1,3,5,7,8,10,12
if (currentMonth == 1 ||
currentMonth == 3 ||
currentMonth == 5 ||
currentMonth == 7 ||
currentMonth == 8 ||
currentMonth == 10 ||
currentMonth == 12
) {
changeDay(31);
} else {
changeDay(30);
}
}
//滑动逻辑回调,
int selectYear = Constant.SELECT_YEAR_START + index;
mListener.selectYear(selectYear);
}
});
wv_month.setOnItemSelectedListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(int index) {
int currentYearIndex = wv_year.getCurrentItem();
index = index + 1;
if (index == 2) {
if (DateUtils.isLeapYear(Constant.SELECT_YEAR_START + currentYearIndex)) {
changeDay(29);
} else {
changeDay(28);
}
} else {
//1,3,5,7,8,10,12
if (index == 1 ||
index == 3 ||
index == 5 ||
index == 7 ||
index == 8 ||
index == 10 ||
index == 12
) {
changeDay(31);
} else {
changeDay(30);
}
}
int currentMonth = Integer.parseInt(listMonth.get(wv_month.getCurrentItem()));
mListener.selectMonth(currentMonth);
}
});
wv_day.setOnItemSelectedListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(int index) {
int currentDay = Integer.parseInt(listDay.get(wv_day.getCurrentItem()));
mListener.selectDay(currentDay);
}
});
}
/**
* 重新设置一个list
*
* @param list
* @param startIndex
* @param endIndex
*/
public void resetListString(List<String> list, int startIndex, int endIndex) {
list.clear();
for (int i = startIndex; i < endIndex + 1; i++) {
list.add(i + "");
}
}
/**
* 改变日滚轮
*
* @param maxDay 最大天数
*/
private void changeDay(int maxDay) {
if (listDay.size() != maxDay) {
resetListString(listDay, 1, maxDay);
adapterDay = new ArrayWheelAdapter<String>(listDay);
wv_day.setAdapter(adapterDay);
if (wv_day.getCurrentItem() >= maxDay) {
wv_day.setCurrentItem(maxDay - 1);
}
}
}
/**
* 获取已选择的日期
*
* @return
*/
public Date getDateAndTimeValue() {
Calendar calendar = Calendar.getInstance();
int year = wv_year.getCurrentItem() + Constant.SELECT_YEAR_START;
int month = wv_month.getCurrentItem();
int day = wv_day.getCurrentItem() + 1;
calendar.set(Calendar.YEAR, year);
calendar.set(Calendar.MONTH, month);
calendar.set(Calendar.DAY_OF_MONTH, day);
Date date = calendar.getTime();
return date;
}
public void setDate(Date date) {
this.date = date;
}
public interface OnSelectListener {
void selectYear(int year);
void selectMonth(int month);
void selectDay(int day);
}
public void setOnSelectListener(OnSelectListener listener) {
this.mListener = listener;
}
}
非常感谢Bigkoo提供这么优秀的开源框架,下面附上AndroidPickView传送门地址