You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Flutter中创建符合示例样式的自定义日历?

自定义日历实现方案(匹配目标样式)

不用依赖第三方包,直接用原生HTML+CSS+JS就能实现你要的样式,以下是完整实现方案:

1. 基础HTML结构

先搭建日历的核心结构,包含年月控制区、星期表头、日期网格:

<div class="custom-calendar">
  <div class="calendar-header">
    <button class="nav-btn" id="prev-month">&lt;</button>
    <h2 class="current-date" id="current-date"></h2>
    <button class="nav-btn" id="next-month">&gt;</button>
  </div>
  <div class="weekdays">
    <div class="weekday">日</div>
    <div class="weekday">一</div>
    <div class="weekday">二</div>
    <div class="weekday">三</div>
    <div class="weekday">四</div>
    <div class="weekday">五</div>
    <div class="weekday">六</div>
  </div>
  <div class="calendar-grid" id="calendar-grid"></div>
</div>

2. CSS样式定制

匹配示例里的视觉风格,包括选中高亮、周末样式、边框和间距:

.custom-calendar {
  max-width: 400px;
  margin: 20px auto;
  font-family: Arial, sans-serif;
  border: 1px solid #ddd;
  border-radius: 8px;
  overflow: hidden;
  box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}

.calendar-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 15px;
  background-color: #f5f5f5;
}

.nav-btn {
  background: none;
  border: none;
  font-size: 18px;
  cursor: pointer;
  padding: 5px 10px;
  border-radius: 4px;
  transition: background-color 0.2s;
}

.nav-btn:hover {
  background-color: #e0e0e0;
}

.current-date {
  margin: 0;
  font-size: 18px;
  font-weight: 600;
}

.weekdays {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  background-color: #f0f0f0;
  border-bottom: 1px solid #ddd;
}

.weekday {
  padding: 10px;
  text-align: center;
  font-weight: 500;
  font-size: 14px;
}

.calendar-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 1px;
  background-color: #ddd;
}

.calendar-day {
  padding: 12px;
  background-color: white;
  text-align: center;
  cursor: pointer;
  transition: background-color 0.2s;
  font-size: 14px;
}

.calendar-day.other-month {
  color: #ccc;
}

.calendar-day.weekend {
  color: #d9534f;
}

.calendar-day.selected {
  background-color: #0275d8;
  color: white;
  border-radius: 50%;
}

.calendar-day:hover {
  background-color: #f5f5f5;
}

3. JS逻辑实现

处理日期计算、年月切换、选中交互:

let currentDate = new Date();

function renderCalendar() {
  const year = currentDate.getFullYear();
  const month = currentDate.getMonth();
  
  // 更新年月显示
  document.getElementById('current-date').textContent = `${year}年${month + 1}月`;
  
  const firstDayOfMonth = new Date(year, month, 1);
  const lastDayOfMonth = new Date(year, month + 1, 0);
  const lastDayOfPrevMonth = new Date(year, month, 0);
  
  const daysInMonth = lastDayOfMonth.getDate();
  const daysInPrevMonth = lastDayOfPrevMonth.getDate();
  const startDay = firstDayOfMonth.getDay(); // 0=周日,6=周六
  
  const calendarGrid = document.getElementById('calendar-grid');
  calendarGrid.innerHTML = '';
  
  // 添加上个月的剩余日期
  for (let i = startDay - 1; i >= 0; i--) {
    const dayDiv = document.createElement('div');
    dayDiv.classList.add('calendar-day', 'other-month');
    dayDiv.textContent = daysInPrevMonth - i;
    calendarGrid.appendChild(dayDiv);
  }
  
  // 添加当月日期
  for (let day = 1; day <= daysInMonth; day++) {
    const dayDiv = document.createElement('div');
    dayDiv.classList.add('calendar-day');
    dayDiv.textContent = day;
    
    // 标记周末
    const dayOfWeek = new Date(year, month, day).getDay();
    if (dayOfWeek === 0 || dayOfWeek === 6) {
      dayDiv.classList.add('weekend');
    }
    
    // 标记今天
    if (year === new Date().getFullYear() && month === new Date().getMonth() && day === new Date().getDate()) {
      dayDiv.classList.add('selected');
    }
    
    // 点击选中日期
    dayDiv.addEventListener('click', () => {
      document.querySelectorAll('.calendar-day.selected').forEach(el => el.classList.remove('selected'));
      dayDiv.classList.add('selected');
    });
    
    calendarGrid.appendChild(dayDiv);
  }
  
  // 添加下个月的补充日期
  const totalCells = calendarGrid.children.length;
  const remainingCells = 42 - totalCells; // 6行*7列=42个格子
  for (let day = 1; day <= remainingCells; day++) {
    const dayDiv = document.createElement('div');
    dayDiv.classList.add('calendar-day', 'other-month');
    dayDiv.textContent = day;
    calendarGrid.appendChild(dayDiv);
  }
}

// 年月切换按钮事件
document.getElementById('prev-month').addEventListener('click', () => {
  currentDate.setMonth(currentDate.getMonth() - 1);
  renderCalendar();
});

document.getElementById('next-month').addEventListener('click', () => {
  currentDate.setMonth(currentDate.getMonth() + 1);
  renderCalendar();
});

// 初始化日历
renderCalendar();

关键说明

  • 完全自定义CSS,你可以根据示例图调整颜色、圆角、间距等细节,比如选中日期的背景色、周末文字颜色
  • 原生JS逻辑无依赖,避免第三方包的样式限制
  • 支持年月切换、日期选中、周末标记、跨月日期显示

内容的提问来源于stack exchange,提问作者Ãm̐ịť Śĩńğh Řâjpůť

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 10:05:31