下面给您详细讲解“轻松实现可扩展自定义的Android滚轮时间选择控件”的完整攻略。
1. 需求明确与分析
在开始实现Android滚轮时间选择控件之前,我们需要先明确需求,并分析需要具备哪些功能。本次需求明确如下:
- 实现时间选择控件,能够快速选择时分。
- 时间可自定义,如自定义可选择时间范围、可设置最小、最大可选择时间等。
- 提供回调函数接口以便于获取用户选择结果。
2. 设计与实现
根据需求分析,我们可以设计并实现出一个具有可扩展自定义的Android滚轮时间选择控件,具体实现步骤如下:
2.1 自定义日期选择控件
首先我们需要自定义一个时间选择控件,用于用户选择所需的时间。我们可以通过Java代码及XML布局文件两种方式来自定义控件。这里我们采用XML布局文件的方式,具体实现步骤如下:
- 在项目的res/layout目录下,新建一个名为"my_time_picker.xml"的布局文件;
- 在该布局文件中添加一个"NumberPicker"(数字选择器)和一个"TextView"(文本标签),其中"NumberPicker"用于选择小时和分钟,"TextView"用于显示“小时”和“分钟”;
- 设定"NumberPicker"的最小值、最大值、当前值,设定"NumberPicker"的选择器属性;
- 在"NumberPicker"和"TextView"之间使用水平布局,使其水平排列。
my_time_picker.xml 文件代码示例如下:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<NumberPicker
android:id="@+id/np_time"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:maxValue="59"
android:minValue="0"
android:value="0" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="小时" />
</LinearLayout>
2.2 创建时间选择对话框
接下来,我们需要创建一个时间选择对话框,用于用户选择小时和分钟。具体实现步骤如下:
- 创建一个alertDialog,用于显示时间选择器;
- 设置对话框标题;
- 引入自定义的视图,即“my_time_picker.xml”中的布局文件,用于实现选择器界面;
- 给“OK”、“CANCEL”按钮设置监听器,用于处理用户选择结果。
代码示例如下:
public class TimePickerDialog extends DialogFragment implements DialogInterface.OnClickListener {
private OnTimeSelectedListener mListener;
private int mCurrentHour = 0;
private int mCurrentMinute = 0;
public interface OnTimeSelectedListener {
void onTimeSelected(int hour, int minute);
}
public TimePickerDialog() {
// Required empty public constructor
}
public static TimePickerDialog newInstance(int currentHour, int currentMinute) {
TimePickerDialog fragment = new TimePickerDialog();
Bundle args = new Bundle();
args.putInt("currentHour", currentHour);
args.putInt("currentMinute", currentMinute);
fragment.setArguments(args);
return fragment;
}
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
Bundle savedInstanceState1 = getArguments();
mCurrentHour = savedInstanceState1.getInt("currentHour");
mCurrentMinute = savedInstanceState1.getInt("currentMinute");
View view = getActivity().getLayoutInflater().inflate(R.layout.my_time_picker, null);
NumberPicker npTime = view.findViewById(R.id.np_time);
npTime.setMinValue(0);
npTime.setMaxValue(23);
npTime.setValue(mCurrentHour);
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle("请选择时间");
builder.setView(view);
builder.setPositiveButton(android.R.string.ok, this);
builder.setNegativeButton(android.R.string.cancel, null);
return builder.create();
}
@Override
public void onClick(DialogInterface dialog, int which) {
NumberPicker npTime = ((AlertDialog)dialog).findViewById(R.id.np_time);
int hour = npTime.getValue();
mListener.onTimeSelected(hour,mCurrentMinute);
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnTimeSelectedListener) {
mListener = (OnTimeSelectedListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnTimeSelectedListener");
}
}
@Override
public void onDetach() {
super.onDetach();
mListener = null;
}
}
2.3 展示时间选择对话框
最后,我们需要在当前Activity中展示时间选择对话框,并获取用户选择结果。具体实现步骤如下:
- 继承自本文定义的视图内部接口,用于显示时间选择对话框;
- 设置时间选择控件的监听器,用于处理用户的选择结果;
- 实现OnTimeSelectedListener接口,用于获取用户选择的时间结果。
代码示例如下:
public class MainActivity extends AppCompatActivity implements TimePickerDialog.OnTimeSelectedListener {
private TextView tv_result;
private int mHour = 0;
private int mMinute = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv_result = findViewById(R.id.tv_result);
findViewById(R.id.btn_show_timepicker).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
TimePickerDialog timePickerDialog = TimePickerDialog.newInstance(mHour, mMinute);
timePickerDialog.show(MainActivity.this.getSupportFragmentManager(), null);
}
});
}
@Override
public void onTimeSelected(int hour, int minute) {
mHour = hour;
mMinute = minute;
tv_result.setText(getString(R.string.your_choice, String.valueOf(mHour), String.valueOf(mMinute)));
}
}
至此,我们的时间选择控件已经构建完成,完整代码如下所示:
public class TimePickerDialog extends DialogFragment implements DialogInterface.OnClickListener {
private OnTimeSelectedListener mListener;
private int mCurrentHour = 0;
private int mCurrentMinute = 0;
public interface OnTimeSelectedListener {
void onTimeSelected(int hour, int minute);
}
public TimePickerDialog() {
// Required empty public constructor
}
public static TimePickerDialog newInstance(int currentHour, int currentMinute) {
TimePickerDialog fragment = new TimePickerDialog();
Bundle args = new Bundle();
args.putInt("currentHour", currentHour);
args.putInt("currentMinute", currentMinute);
fragment.setArguments(args);
return fragment;
}
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
Bundle savedInstanceState1 = getArguments();
mCurrentHour = savedInstanceState1.getInt("currentHour");
mCurrentMinute = savedInstanceState1.getInt("currentMinute");
View view = getActivity().getLayoutInflater().inflate(R.layout.my_time_picker, null);
NumberPicker npTime = view.findViewById(R.id.np_time);
npTime.setMinValue(0);
npTime.setMaxValue(23);
npTime.setValue(mCurrentHour);
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle("请选择时间");
builder.setView(view);
builder.setPositiveButton(android.R.string.ok, this);
builder.setNegativeButton(android.R.string.cancel, null);
return builder.create();
}
@Override
public void onClick(DialogInterface dialog, int which) {
NumberPicker npTime = ((AlertDialog)dialog).findViewById(R.id.np_time);
int hour = npTime.getValue();
mListener.onTimeSelected(hour,mCurrentMinute);
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnTimeSelectedListener) {
mListener = (OnTimeSelectedListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnTimeSelectedListener");
}
}
@Override
public void onDetach() {
super.onDetach();
mListener = null;
}
}
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<NumberPicker
android:id="@+id/np_time"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:maxValue="59"
android:minValue="0"
android:value="0" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="小时" />
</LinearLayout>
public class MainActivity extends AppCompatActivity implements TimePickerDialog.OnTimeSelectedListener {
private TextView tv_result;
private int mHour = 0;
private int mMinute = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv_result = findViewById(R.id.tv_result);
findViewById(R.id.btn_show_timepicker).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
TimePickerDialog timePickerDialog = TimePickerDialog.newInstance(mHour, mMinute);
timePickerDialog.show(MainActivity.this.getSupportFragmentManager(), null);
}
});
}
@Override
public void onTimeSelected(int hour, int minute) {
mHour = hour;
mMinute = minute;
tv_result.setText(getString(R.string.your_choice, String.valueOf(mHour), String.valueOf(mMinute)));
}
}
以上,我们就已经实现了一个可扩展自定义的Android滚轮时间选择控件。
示例说明1:自定义选择时间范围
我们可以在NumberPicker设置中添加setDisplayedValues()
函数,该函数的参数String[] values
可以以字符串数组的形式设置选择器显示的内容,从而实现自定义选择时间范围的功能。例如,我们可以设置只允许选择8:00AM到5:00PM之间的时间。代码示例如下:
public class customTimePick extends AppCompatActivity implements TimePickerDialog.OnTimeSelectedListener {
private TextView tv_result;
private final String[] HOURS = new String[]{"08", "09", "10", "11", "12", "13", "14", "15", "16", "17"};
private final String[] MINUTES = new String[]{"00", "15", "30", "45"};
private int mHour = 0;
private int mMinute = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_custom_time_pick);
tv_result = findViewById(R.id.tv_result);
findViewById(R.id.btn_show_custom_time_picker).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
TimePickerDialog timePickerDialog = TimePickerDialog.newInstance(mHour, mMinute, HOURS, MINUTES);
timePickerDialog.show(customTimePick.this.getSupportFragmentManager(), null);
}
});
}
@Override
public void onTimeSelected(int hour, int minute) {
mHour = hour;
mMinute = minute;
tv_result.setText(getString(R.string.your_choice, String.valueOf(mHour), String.valueOf(mMinute)));
}
}
需要注意,在上述代码中我添加了两个字符串数组HOURS
和MINUTES
,用于设置NumberPicker的显示范围。
my_custom_time_picker.xml 文件代码示例如下:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<NumberPicker
android:id="@+id/np_hour"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=":" />
<NumberPicker
android:id="@+id/np_minute"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center" />
</LinearLayout>
时间选择对话框的代码示例如下:
public class TimePickerDialog extends DialogFragment implements DialogInterface.OnClickListener {
private OnTimeSelectedListener mListener;
private int mCurrentHour = 0;
private int mCurrentMinute = 0;
private String[] mDisplayedHours;
private String[] mDisplayedMinutes;
public interface OnTimeSelectedListener {
void onTimeSelected(int hour, int minute);
}
public TimePickerDialog() {
// Required empty public constructor
}
public static TimePickerDialog newInstance(int currentHour, int currentMinute) {
return newInstance(currentHour, currentMinute, null, null);
}
public static TimePickerDialog newInstance(int currentHour, int currentMinute, String[] hours, String[] minutes) {
TimePickerDialog fragment = new TimePickerDialog();
Bundle args = new Bundle();
args.putInt("currentHour", currentHour);
args.putInt("currentMinute", currentMinute);
if (hours != null) {
args.putStringArray("hours", hours);
}
if (minutes != null) {
args.putStringArray("minutes", minutes);
}
fragment.setArguments(args);
return fragment;
}
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
Bundle savedInstanceState1 = getArguments();
mCurrentHour = savedInstanceState1.getInt("currentHour");
mCurrentMinute = savedInstanceState1.getInt("currentMinute");
mDisplayedHours = savedInstanceState1.getStringArray("hours");
mDisplayedMinutes = savedInstanceState1.getStringArray("minutes");
View view = getActivity().getLayoutInflater().inflate(R.layout.my_custom_time_picker, null);
NumberPicker npHour = view.findViewById(R.id.np_hour);
if (mDisplayedHours != null) {
npHour.setMinValue(0);
npHour.setMaxValue(mDisplayedHours.length - 1);
npHour.setDisplayedValues(mDisplayedHours);
} else {
npHour.setMinValue(0);
npHour.setMaxValue(23);
}
npHour.setValue(mCurrentHour);
NumberPicker npMinute = view.findViewById(R.id.np_minute);
if (mDisplayedMinutes != null) {
npMinute.setMinValue(0);
npMinute.setMaxValue(mDisplayedMinutes.length - 1);
npMinute.setDisplayedValues(mDisplayedMinutes);
} else {
npMinute.setMinValue(0);
npMinute.setMaxValue(59);
}
npMinute.setValue(mCurrentMinute);
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle("请选择时间");
builder.setView(view);
builder.setPositiveButton(android.R.string.ok, this);
builder.setNegativeButton(android.R.string.cancel, null);
return builder.create();
}
@Override
public void onClick(DialogInterface dialogInterface, int i) {
NumberPicker npHour = ((AlertDialog)dialogInterface).findViewById(R.id.np_hour);
NumberPicker npMinute = ((AlertDialog)dialogInterface).findViewById(R.id.np_minute);
int hour = npHour.getValue();
int minute = npMinute.getValue();
mListener.onTimeSelected(hour,minute);
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnTimeSelectedListener) {
mListener = (OnTimeSelectedListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnTimeSelectedListener");
}
}
@Override
public void onDetach() {
super.onDetach();
mListener = null;
}
}
需要注意,为了实现显示自定义时间范围,在时间选择对话框的构造函数中添加了两个参数传递String数组类型的时间范围。在相应位置中进行判断并设置显示时间范围即可。
示例说明2:自定义分钟间隔
我们可以在Activity中准备一个分钟间隔数组,从而自定义分钟间隔。例如,在此我们可以设置分钟间隔为15分钟,即允许用户选择“0”、“15”、“30”、“45”这4个数值。代码如下:
```java
public class customTimePick extends AppCompatActivity implements TimePickerDialog.OnTimeSelectedListener {
private TextView tv_result;
private final String[] HOURS = new String[]{"08", "09", "10", "11", "12", "13", "14", "15", "16", "17"};
private final String[] MINUTES = new String[]{"00", "15", "30", "45"};
private int mHour = 0;
private int mMinute = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_custom_time_pick);
tv_result = findViewById(R.id.tv_result);
findViewById(R.id.btn_show_custom_time_picker).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Time
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:轻松实现可扩展自定义的Android滚轮时间选择控件 - Python技术站