2023年安卓日历界面完全指南:使用技巧与自定义教程
这是文章《安卓日历界面》的第1部分(共2部分)。
在本教程中,我们将使用日历视图类(CalendarView)讨论在Android应用程序中使用的日历小部件。
安卓日历视图
如其名,日历视图用于显示和选择日历日期。在XML布局中添加日历视图,按照以下步骤进行操作:
<CalendarView
android:id="@+id/calendarView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
在布局设计编辑器中,它的外观如下所示:当您在设备上运行上述应用时,它会显示当前日期。默认情况下,日历显示的是1970年1月1日的日期。android:maxDate和android:minDate用于在日历上设置自定义范围。指定的日期格式为MM/dd/yyyy。在Java中,我们使用setMaxDate()和setMinDate()方法,并传递long实例来完成同样的操作。对应的获取方法也是可用的。要设置当前日期,我们在日历视图实例上使用setDate(long date)方法。setDate方法还有另一个形式:setDate(long date, boolean animate, boolean center)。默认情况下,第二个和第三个参数为true。当您选择一个新日期时,它会以动画效果切换到该日期。要更改日期和星期文本样式,我们使用属性android:dateTextAppearance和android:weekTextAppearance,或其在Java中的等效设置器。日历视图包括以下监听器:
calendarView.setOnDateChangeListener(new CalendarView.OnDateChangeListener() {
@Override
public void onSelectedDayChange(@NonNull CalendarView calendarView, int i, int i1, int i2) {
}
});
每当用户更改日期时,该监听器就会被触发。
- i = 年
- i1 = 月
- i2 = 日
在接下来的部分,我们将创建一个具有自定义主题的Android应用,并在日历视图上添加一个自定义范围,同时展示动画和非动画日期变化之间的差异。
项目结构
代码
在styles.xml文件中添加以下三种样式:
<style name="CalenderViewCustom" parent="Theme.AppCompat">
<item name="colorAccent">@android:color/holo_blue_dark</item>
<item name="colorPrimary">@android:color/darker_gray</item>
<item name="android:textColorPrimary">@color/colorPrimary</item>
</style>
<style name="CalenderViewDateCustomText" parent="android:TextAppearance.DeviceDefault.Small">
<item name="android:textColor">@android:color/holo_orange_dark</item>
</style>
<style name="CalenderViewWeekCustomText" parent="android:TextAppearance.DeviceDefault.Small">
<item name="android:textColor">@android:color/holo_green_dark</item>
</style>
默认情况下,android:textColorPrimary的颜色为白色。该颜色被应用于月份日期以及左侧和右侧指示器。以下是activity_main.xml的代码:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:app="https://schemas.android.com/apk/res-auto"
xmlns:tools="https://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<CalendarView
android:id="@+id/calendarView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:dateTextAppearance="@style/CalenderViewDateCustomText"
android:theme="@style/CalenderViewCustom"
android:weekDayTextAppearance="@style/CalenderViewWeekCustomText"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/btnWithAnim"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:text="带动画\n切换"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/btnWithoutAnim"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/btnRange" />
<Button
android:id="@+id/btnWithoutAnim"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="无动画\n切换"
app:layout_constraintBaseline_toBaselineOf="@+id/btnWithAnim"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/btnWithAnim" />
<Button
android:id="@+id/btnRange"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="自定义\n范围"
app:layout_constraintEnd_toStartOf="@+id/btnWithAnim"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintHorizontal_chainStyle="spread"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/btnWithAnim" />
</android.support.constraint.ConstraintLayout>
我们已经在上面的布局中添加了所有自定义样式。三个按钮在约束布局中链接在一起。下面是MainActivity.java的代码。
package com.Olivia.androidcalendarview;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.CalendarView;
import android.widget.Toast;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
Calendar calendar;
CalendarView calendarView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
calendar = Calendar.getInstance();
calendar.set(Calendar.MONTH, Calendar.NOVEMBER);
calendar.set(Calendar.DAY_OF_MONTH, 9);
calendar.set(Calendar.YEAR, 2012);
calendar.add(Calendar.DAY_OF_MONTH, 1);
calendar.add(Calendar.YEAR, 1);
calendarView = findViewById(R.id.calendarView);
Button btnRange = findViewById(R.id.btnRange);
btnRange.setOnClickListener(this);
Button btnWithoutAnim = findViewById(R.id.btnWithoutAnim);
btnWithoutAnim.setOnClickListener(this);
Button btnWithAnim = findViewById(R.id.btnWithAnim);
btnWithAnim.setOnClickListener(this);
calendarView.setOnDateChangeListener(new CalendarView.OnDateChangeListener() {
@Override
public void onSelectedDayChange(@NonNull CalendarView calendarView, int i, int i1, int i2) {
String msg = "选择的日期: " + i2 + " 日, " + (i1 + 1) + " 月, " + i + " 年";
Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_SHORT).show();
}
});
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.btnWithAnim:
calendarView.setDate(calendar.getTimeInMillis(), true, true);
break;
case R.id.btnWithoutAnim:
calendar.set(Calendar.DAY_OF_MONTH, 12);
calendar.set(Calendar.YEAR, 2016);
calendar.add(Calendar.MONTH, Calendar.MARCH);
calendarView.setDate(calendar.getTimeInMillis(), false, false);
break;
case R.id.btnRange:
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.DATE, calendar.getActualMaximum(Calendar.DATE));
long endOfMonth = calendar.getTimeInMillis();
calendar = Calendar.getInstance();
calendar.set(Calendar.DATE, 1);
calendar.set(Calendar.HOUR_OF_DAY, 0);
long startOfMonth = calendar.getTimeInMillis();
calendarView.setMaxDate(endOfMonth);
calendarView.setMinDate(startOfMonth);
String minDateString = new SimpleDateFormat("MM/dd/yyyy").format(new Date(calendarView.getMinDate()));
String maxDateString = new SimpleDateFormat("MM/dd/yyyy").format(new Date(calendarView.getMaxDate()));
Toast.makeText(getApplicationContext(), "月/日/年 最小日期 - " + minDateString + " 最大日期: " + maxDateString, Toast.LENGTH_LONG).show();
break;
}
}
}
calendar.getActualMaximum(Calendar.DATE)函数可以获取当前日期所在月份的最后一天。我们使用SimpleDateFormat将日期转换成自定义格式。以下是应用程序的输出情况:在第一种情况下,我们使用动画切换到另一个日期。在最后一种情况下,自定义范围只显示当前月份。指示器被禁用。本教程到此结束。您可以从下面的链接下载该项目。
安卓日历视图
Github 项目链接。