Android仿ios年龄、生日、性别滚轮效果

作者:王虎的博客 时间:2022-02-22 11:59:03 

新项目Android和ios要做成统一样式,年龄,性别,时间,要做成滚轮效果,Android没有原生控件,只能自己定义,于是我较劲脑汁,终于写出来,本着分享精神,贴出部分代码,直接拷贝就能用。

先看效果图,如果符合你的需求,再采纳

时间

Android仿ios年龄、生日、性别滚轮效果

年龄

Android仿ios年龄、生日、性别滚轮效果

性别

Android仿ios年龄、生日、性别滚轮效果

废话不多说,直接上代码

布局

activity_main.xml


<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android:id="@+id/activity_main"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
>

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
android:id="@+id/textView"/>

<Button
android:text="生日"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/textView"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:id="@+id/button"
android:onClick="date"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"/>

<Button
android:text="时间"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/button"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:id="@+id/button2"
android:onClick="time"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"/>

<Button
android:text="性别"
android:onClick="zidingyi"

android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/button2"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:id="@+id/button3"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"/>
</RelativeLayout>

MainActivity


public class MainActivity extends AppCompatActivity {

private Dialog dateDialog, timeDialog, chooseDialog;
private TextView mTextView;
private List<String> list = new ArrayList<>();

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextView = (TextView) findViewById(R.id.textView);
String[] data = getResources().getStringArray(R.array.list);
for (String str : data) {
 list.add(str);
}
}

/**
* chooseDialog
*/
private void showChooseDialog(List<String> mlist) {
DataPickerDialog.Builder builder = new DataPickerDialog.Builder(this);
chooseDialog = builder.setData(mlist).setSelection(1).setTitle("取消")
 .setOnDataSelectedListener(new DataPickerDialog.OnDataSelectedListener() {
  @Override
  public void onDataSelected(String itemValue, int position) {
  mTextView.setText(itemValue);

}

@Override
  public void onCancel() {

}
 }).create();

chooseDialog.show();
}

private void showDateDialog(List<Integer> date) {
DatePickerDialog.Builder builder = new DatePickerDialog.Builder(this);
builder.setOnDateSelectedListener(new DatePickerDialog.OnDateSelectedListener() {
 @Override
 public void onDateSelected(int[] dates) {

mTextView.setText(dates[0] + "-" + (dates[1] > 9 ? dates[1] : ("0" + dates[1])) + "-"
  + (dates[2] > 9 ? dates[2] : ("0" + dates[2])));

}

@Override
 public void onCancel() {

}
})

.setSelectYear(date.get(0) - 1)
 .setSelectMonth(date.get(1) - 1)
 .setSelectDay(date.get(2) - 1);

builder.setMaxYear(DateUtil.getYear());
builder.setMaxMonth(DateUtil.getDateForString(DateUtil.getToday()).get(1));
builder.setMaxDay(DateUtil.getDateForString(DateUtil.getToday()).get(2));
dateDialog = builder.create();
dateDialog.show();
}

private void showTimePick() {

if (timeDialog == null) {

TimePickerDialog.Builder builder = new TimePickerDialog.Builder(this);
 timeDialog = builder.setOnTimeSelectedListener(new TimePickerDialog.OnTimeSelectedListener() {
 @Override
 public void onTimeSelected(int[] times) {

mTextView.setText(times[0] + ":" + times[1]);

}
 }).create();
}

timeDialog.show();

}

public void time(View v) {

showTimePick();

}

public void date(View v) {
showDateDialog(DateUtil.getDateForString("1990-01-01"));

}

public void zidingyi(View v) {

showChooseDialog(list);

}
}

DataPickerDialog


public class DataPickerDialog extends Dialog {

private Params params;

public DataPickerDialog(Context context, int themeResId) {
super(context, themeResId);
}

private void setParams(DataPickerDialog.Params params) {
this.params = params;
}

public void setSelection(String itemValue) {
if (params.dataList.size() > 0) {
 int idx = params.dataList.indexOf(itemValue);
 if (idx >= 0) {
 params.initSelection = idx;
 params.loopData.setCurrentItem(params.initSelection);
 }
}
}

public interface OnDataSelectedListener {
void onDataSelected(String itemValue, int position);
void onCancel();
}

private static final class Params {
private boolean shadow = true;
private boolean canCancel = true;
private LoopView loopData;
private String title;
private String unit;
private int initSelection;
private OnDataSelectedListener callback;
private final List<String> dataList = new ArrayList<>();
}

public static class Builder {
private final Context context;
private final DataPickerDialog.Params params;

public Builder(Context context) {
 this.context = context;
 params = new DataPickerDialog.Params();
}

private final String getCurrDateValue() {
 return params.loopData.getCurrentItemValue();
}

public Builder setData(List<String> dataList) {
 params.dataList.clear();
 params.dataList.addAll(dataList);
 return this;
}

public Builder setTitle(String title) {
 params.title = title;
 return this;
}

public Builder setUnit(String unit) {
 params.unit = unit;
 return this;
}

public Builder setSelection(int selection) {
 params.initSelection = selection;
 return this;
}

public Builder setOnDataSelectedListener(OnDataSelectedListener onDataSelectedListener) {
 params.callback = onDataSelectedListener;
 return this;
}

public DataPickerDialog create() {
 final DataPickerDialog dialog = new DataPickerDialog(context, params.shadow ? R.style.Theme_Light_NoTitle_Dialog : R.style.Theme_Light_NoTitle_NoShadow_Dialog);
 View view = LayoutInflater.from(context).inflate(R.layout.layout_picker_data, null);

if (!TextUtils.isEmpty(params.title)) {
 TextView txTitle = (TextView) view.findViewById(R.id.tx_title);
 txTitle.setText(params.title);
 txTitle.setOnClickListener(new View.OnClickListener() {
  @Override
  public void onClick(View view) {
  dialog.dismiss();
  params.callback.onCancel();
  }
 });
 }
 if (!TextUtils.isEmpty(params.unit)) {
 TextView txUnit = (TextView) view.findViewById(R.id.tx_unit);
 txUnit.setText(params.unit);
 }

final LoopView loopData = (LoopView) view.findViewById(R.id.loop_data);
 loopData.setArrayList(params.dataList);
 loopData.setNotLoop();
 if (params.dataList.size() > 0) loopData.setCurrentItem(params.initSelection);
 view.findViewById(R.id.tx_finish).setOnClickListener(new View.OnClickListener() {
 @Override
 public void onClick(View v) {
  dialog.dismiss();
  params.callback.onDataSelected(getCurrDateValue(),loopData.getCurrentItem());
 }
 });

Window win = dialog.getWindow();
 win.getDecorView().setPadding(0, 0, 0, 0);
 WindowManager.LayoutParams lp = win.getAttributes();
 lp.width = WindowManager.LayoutParams.MATCH_PARENT;
 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
 win.setAttributes(lp);
 win.setGravity(Gravity.BOTTOM);
 win.setWindowAnimations(R.style.Animation_Bottom_Rising);

dialog.setContentView(view);
 dialog.setCanceledOnTouchOutside(params.canCancel);
 dialog.setCancelable(params.canCancel);

params.loopData = loopData;
 dialog.setParams(params);

return dialog;
}
}
}

DatePickerDialog


public class DatePickerDialog extends Dialog {

private static int MIN_YEAR = 1900;
private static int MAX_YEAR = 2100;
private Params params;

public DatePickerDialog(Context context, int themeResId) {
super(context, themeResId);
}

private void setParams(DatePickerDialog.Params params) {
this.params = params;
}

public interface OnDateSelectedListener {
 void onDateSelected(int[] dates);
 void onCancel();
}

private static final class Params {
private boolean shadow = true;
private boolean canCancel = true;
private LoopView loopYear, loopMonth, loopDay;
private OnDateSelectedListener callback;
}

public static class Builder {
private final Context context;
private final DatePickerDialog.Params params;
private Integer minYear;
private Integer maxYear;
private Integer selectYear;
private Integer selectMonth;
private Integer selectDay;
private Integer minMonth;
private Integer maxMonth;
private Integer minDay;
private Integer maxDay;

public Builder(Context context) {
 this.context = context;
 params = new DatePickerDialog.Params();
}

public Builder setMinYear(int year){
 minYear=year;
 return this;
}

public Builder setMaxYear(int year){
 maxYear=year;
 return this;
}

public Builder setMinMonth(int month){
 minMonth=month;
 return this;
}

public Builder setMaxMonth(int month){
 maxMonth=month;
 return this;
}

public Builder setMinDay(int day){
 minDay=day;
 return this;
}

public Builder setMaxDay(int day){
 maxDay=day;
 return this;
}

public Builder setSelectYear(int year){
 this.selectYear=year;
 return this;
}

public Builder setSelectMonth(int month){
 this.selectMonth=month;
 return this;
}

public Builder setSelectDay(int day){
 this.selectDay=day;
 return this;
}

/**
 * 获取当前选择的日期
 *
 * @return int[]数组形式返回。例[1990,6,15]
 */
private final int[] getCurrDateValues() {
 int currYear = Integer.parseInt(params.loopYear.getCurrentItemValue());
 int currMonth = Integer.parseInt(params.loopMonth.getCurrentItemValue());
 int currDay = Integer.parseInt(params.loopDay.getCurrentItemValue());
 return new int[]{currYear, currMonth, currDay};
}

public Builder setOnDateSelectedListener(OnDateSelectedListener onDateSelectedListener) {
 params.callback = onDateSelectedListener;
 return this;
}

public DatePickerDialog create() {
 final DatePickerDialog dialog = new DatePickerDialog(context, params.shadow ? R.style.Theme_Light_NoTitle_Dialog : R.style.Theme_Light_NoTitle_NoShadow_Dialog);
 View view = LayoutInflater.from(context).inflate(R.layout.layout_picker_date, null);

view.findViewById(R.id.tv_cancel).setOnClickListener(new View.OnClickListener() {
 @Override
 public void onClick(View view) {
  dialog.dismiss();
  params.callback.onCancel();
 }
 });

Calendar c = Calendar.getInstance();

final LoopView loopDay = (LoopView) view.findViewById(R.id.loop_day);
 loopDay.setArrayList(d(1, 30));
 if(selectDay!=null){
 loopDay.setCurrentItem(selectDay);
 }else{
 loopDay.setCurrentItem(c.get(Calendar.DATE));
 }
 //loopDay.setNotLoop();

final LoopView loopYear = (LoopView) view.findViewById(R.id.loop_year);
 loopYear.setArrayList(d(MIN_YEAR, MAX_YEAR - MIN_YEAR + 1));
 if(selectYear!=null){
 loopYear.setCurrentItem(selectYear-MIN_YEAR+1);
 }else{
 loopYear.setCurrentItem(MAX_YEAR);
 }
 loopYear.setNotLoop();

final LoopView loopMonth = (LoopView) view.findViewById(R.id.loop_month);
 loopMonth.setArrayList(d(1, 12));
 if(selectMonth!=null){
 loopMonth.setCurrentItem(selectMonth);
 }else{
 loopMonth.setCurrentItem(c.get(Calendar.MONTH));
 }
 loopMonth.setNotLoop();

final LoopListener maxDaySyncListener = new LoopListener() {
 @Override
 public void onItemSelect(int item) {
  Calendar c = Calendar.getInstance();
  boolean needFixed=true;
  if(minYear!=null){
  if(Integer.parseInt(loopYear.getCurrentItemValue())==minYear ){
   if(minMonth!=null){
   if(Integer.parseInt(loopMonth.getCurrentItemValue())<minMonth){
    loopMonth.setCurrentItem(minMonth - 1);
   }
   }
  }else if(Integer.parseInt(loopYear.getCurrentItemValue())<minYear){
   loopYear.setCurrentItem(minYear-MIN_YEAR);
  }
  }

if(maxYear!=null){
  if(Integer.parseInt(loopYear.getCurrentItemValue())==maxYear ){
   if(maxMonth!=null){
   if(Integer.parseInt(loopMonth.getCurrentItemValue())>maxMonth){
    loopMonth.setCurrentItem(maxMonth - 1);
   }
   }
  }else if(Integer.parseInt(loopYear.getCurrentItemValue())>maxYear){
   loopYear.setCurrentItem(maxYear-MIN_YEAR);
  }
  }

c.set(Integer.parseInt(loopYear.getCurrentItemValue()), Integer.parseInt(loopMonth.getCurrentItemValue()) - 1, 1);
  c.roll(Calendar.DATE, false);

if(needFixed){
  int maxDayOfMonth = c.get(Calendar.DATE);
  int fixedCurr = loopDay.getCurrentItem();
  loopDay.setArrayList(d(1, maxDayOfMonth));
  // 修正被选中的日期最大值
  if (fixedCurr > maxDayOfMonth) fixedCurr = maxDayOfMonth - 1;
  loopDay.setCurrentItem(fixedCurr);
  }
 }
 };

final LoopListener dayLoopListener=new LoopListener() {
 @Override
 public void onItemSelect(int item) {
  if(minYear!=null && minMonth!=null && minDay!=null
   && Integer.parseInt(loopYear.getCurrentItemValue())==minYear
   && Integer.parseInt(loopMonth.getCurrentItemValue())==minMonth
   && Integer.parseInt(loopDay.getCurrentItemValue())<minDay
   ){
  loopDay.setCurrentItem(minDay-1);
  }

if(maxYear!=null && maxMonth!=null && maxDay!=null
   && Integer.parseInt(loopYear.getCurrentItemValue())==maxYear
   && Integer.parseInt(loopMonth.getCurrentItemValue())==maxMonth
   && Integer.parseInt(loopDay.getCurrentItemValue())>maxDay
   ){
  loopDay.setCurrentItem(maxDay-1);
  }
 }
 };
 loopYear.setListener(maxDaySyncListener);
 loopMonth.setListener(maxDaySyncListener);
 loopDay.setListener(dayLoopListener);

view.findViewById(R.id.tx_finish).setOnClickListener(new View.OnClickListener() {
 @Override
 public void onClick(View v) {
  dialog.dismiss();
  params.callback.onDateSelected(getCurrDateValues());
 }
 });

Window win = dialog.getWindow();
 win.getDecorView().setPadding(0, 0, 0, 0);
 WindowManager.LayoutParams lp = win.getAttributes();
 lp.width = WindowManager.LayoutParams.MATCH_PARENT;
 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
 win.setAttributes(lp);
 win.setGravity(Gravity.BOTTOM);
 win.setWindowAnimations(R.style.Animation_Bottom_Rising);

dialog.setContentView(view);
 dialog.setCanceledOnTouchOutside(params.canCancel);
 dialog.setCancelable(params.canCancel);

params.loopYear = loopYear;
 params.loopMonth = loopMonth;
 params.loopDay = loopDay;
 dialog.setParams(params);

return dialog;
}

/**
 * 将数字传化为集合,并且补充0
 *
 * @param startNum 数字起点
 * @param count 数字个数
 * @return
 */
private static List<String> d(int startNum, int count) {
 String[] values = new String[count];
 for (int i = startNum; i < startNum + count; i++) {
 String tempValue = (i < 10 ? "0" : "") + i;
 values[i - startNum] = tempValue;
 }
 return Arrays.asList(values);
}

}
}

代码太多就不一一贴出来了,有需要直接下载:完整demo地址

来源:https://blog.csdn.net/wangxiaohuhu1314/article/details/76020489

标签:Android,ios,滚轮
0
投稿

猜你喜欢

  • Java对XML文件增删改查操作示例

    2021-10-28 08:46:29
  • 基于springboot2集成jpa,创建dao的案例

    2021-08-02 00:40:46
  • Java ThreadLocal的使用详解

    2023-11-29 04:48:43
  • 深入解析JVM对dll文件和对类的装载过程

    2023-06-14 23:23:33
  • Java 注解学习笔记

    2022-12-25 02:40:54
  • Android开发实现圆形图片功能示例

    2023-07-12 08:43:54
  • C#实现装箱与拆箱操作简单实例

    2023-09-10 15:37:28
  • Java网络编程之TCP通信完整代码示例

    2022-10-18 21:42:57
  • swagger中如何给请求添加header

    2023-05-15 14:27:52
  • Java string类型转换成map代码实例

    2021-06-07 12:19:29
  • 深入多线程之:用Wait与Pulse模拟一些同步构造的应用详解

    2021-07-09 06:14:19
  • Android仿微信选择图片和拍照功能

    2023-08-18 05:22:50
  • Android实现简单MD5加密的方法

    2021-10-06 19:51:04
  • SpringBoot结合Redis配置工具类实现动态切换库

    2022-04-15 14:14:13
  • Spring JPA之save方法示例详解

    2023-09-06 15:50:35
  • Fastjson 常用API介绍及下载地址(推荐)

    2023-03-18 23:48:47
  • Android Studio 通过登录功能介绍SQLite数据库的使用流程

    2023-09-22 00:37:29
  • java集合求和最大值最小值示例分享

    2022-10-11 04:15:10
  • C#多态详解

    2023-06-25 13:42:20
  • C#中倒序输出字符串的方法示例

    2023-10-27 21:45:13
  • asp之家 软件编程 m.aspxhome.com