package org.lntu.online.ui.adapter; import android.content.Context; import android.content.Intent; import android.support.v4.view.PagerAdapter; import android.text.Spannable; import android.text.SpannableString; import android.text.TextUtils; import android.text.style.ForegroundColorSpan; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ScrollView; import android.widget.TextView; import org.joda.time.LocalDate; import org.joda.time.Period; import org.joda.time.PeriodType; import org.lntu.online.R; import org.lntu.online.model.entity.ClassTable; import org.lntu.online.model.entity.DayInWeek; import org.lntu.online.model.entity.WeekMode; import org.lntu.online.model.util.EntityUtils; import org.lntu.online.ui.activity.ClassTableCourseActivity; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import butterknife.BindView; import butterknife.BindViews; import butterknife.ButterKnife; import butterknife.OnClick; public class ClassTablePageAdapter extends PagerAdapter { private Context context; private LayoutInflater inflater; private List<View> busyPool = new ArrayList<>(); private List<View> idelPool = new ArrayList<>(); private LocalDate startDate; private LocalDate endDate; private LocalDate firstWeekMonday; private LocalDate today; private ClassTable classTable; private Map<String, List<ClassTable.CourseWrapper>> classTableMap; private Map<String, String> openStateMap = new HashMap<>(); public ClassTablePageAdapter(Context context, int year, String term, LocalDate today) { this.context = context; inflater = LayoutInflater.from(context); if ("春".equals(term)) { startDate = new LocalDate(year, 2, 1); endDate = new LocalDate(year, 8, 1); } else { startDate = new LocalDate(year, 8, 1); endDate = new LocalDate(year + 1, 2, 1); } this.today = today; } public LocalDate getStartDate() { return startDate; } public LocalDate getEndDate() { return endDate; } public void updateDataSet(ClassTable classTable, Map<String, List<ClassTable.CourseWrapper>> classTableMap) { this.classTable = classTable; this.classTableMap = classTableMap; firstWeekMonday = new LocalDate(classTable.getFirstWeekMondayAt()); if (firstWeekMonday.isBefore(startDate) || firstWeekMonday.isAfter(endDate)) { // 第一周周一不在时间区域,重新定义第一周周一 if ("春".equals(classTable.getTerm())) { firstWeekMonday = new LocalDate(classTable.getYear(), 3, 1); } else { firstWeekMonday = new LocalDate(classTable.getYear(), 9, 1); } firstWeekMonday = firstWeekMonday.plusDays((7 - firstWeekMonday.getDayOfWeek() + 1) % 7); } else { // 第一周周一在时间区域 firstWeekMonday = firstWeekMonday.minusDays(firstWeekMonday.getDayOfWeek() - 1); } notifyDataSetChanged(); } @Override public int getCount() { Period period = new Period(startDate, endDate, PeriodType.days()); return period.getDays(); } @Override public boolean isViewFromObject(View view, Object object) { return view == object; } public int getPositionFromDate(LocalDate date) { if (date == null || date.isBefore(startDate) || date.isAfter(endDate)) { return 0; } else { Period period = new Period(startDate, date, PeriodType.days()); return period.getDays(); } } public LocalDate getDateAt(int position) { return startDate.plusDays(position); } public int getWeekOfTerm(LocalDate date) { if (firstWeekMonday == null || firstWeekMonday.isBefore(startDate) || firstWeekMonday.isAfter(endDate)) { return -1; } else { Period period = new Period(firstWeekMonday, date, PeriodType.days()); int days = period.getDays(); return days < 0 ? 0 : days / 7 + 1; } } @Override public CharSequence getPageTitle(int position) { LocalDate currentDate = getDateAt(position); String title = currentDate.getMonthOfYear() + "月" + currentDate.getDayOfMonth() + "日 " + DayInWeek.getFromIndex(currentDate.getDayOfWeek()).value(); int weekOfTerm = getWeekOfTerm(currentDate); if (weekOfTerm > 0) { title += "(第" + getWeekOfTerm(currentDate) + "周)"; } if (currentDate.equals(today)) { // 是今天-主题色标注 SpannableString spanString = new SpannableString(title); ForegroundColorSpan span = new ForegroundColorSpan(context.getResources().getColor(R.color.color_primary)); spanString.setSpan(span, 0, spanString.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); return spanString; } else { return title; } } @Override public Object instantiateItem(ViewGroup container, int position) { View convertView; if (idelPool.size() <= 0) { // 没有空闲view convertView = inflater.inflate(R.layout.activity_class_table_page_item, container, false); convertView.setTag(new ViewHolder(convertView)); } else { convertView = idelPool.get(0); idelPool.remove(convertView); } busyPool.add(convertView); ViewHolder holder = (ViewHolder) convertView.getTag(); holder.update(position); container.addView(convertView); return convertView; } @Override public void destroyItem(ViewGroup container, int position, Object object) { View convertView = (View) object; ViewHolder holder = (ViewHolder) convertView.getTag(); holder.scrollView.scrollTo(0, 0); container.removeView(convertView); busyPool.remove(convertView); idelPool.add(convertView); } @Override public void notifyDataSetChanged() { for (View view : busyPool) { ViewHolder holder = (ViewHolder) view.getTag(); if (holder.position >= 0) { holder.update(holder.position); } } super.notifyDataSetChanged(); } protected class ViewHolder { @BindView(R.id.scroll_view) protected ScrollView scrollView; @BindViews({ R.id.tv_stage_1, R.id.tv_stage_2, R.id.tv_stage_3, R.id.tv_stage_4, R.id.tv_stage_5 }) protected List<TextView> tvStageList; @BindViews({ R.id.layout_stage_1_show, R.id.layout_stage_2_show, R.id.layout_stage_3_show, R.id.layout_stage_4_show, R.id.layout_stage_5_show }) protected List<ViewGroup> layoutStageShowList; @BindViews({ R.id.layout_stage_1_hide, R.id.layout_stage_2_hide, R.id.layout_stage_3_hide, R.id.layout_stage_4_hide, R.id.layout_stage_5_hide }) protected List<ViewGroup> layoutStageHideList; @BindViews({ R.id.icon_stage_1, R.id.icon_stage_2, R.id.icon_stage_3, R.id.icon_stage_4, R.id.icon_stage_5 }) protected List<View> iconStageList; @BindViews({ R.id.btn_stage_1, R.id.btn_stage_2, R.id.btn_stage_3, R.id.btn_stage_4, R.id.btn_stage_5, }) protected List<View> btnStageList; protected int position = -1; protected LocalDate currentDate; public ViewHolder(View convertView) { ButterKnife.bind(this, convertView); } protected void update(int position) { this.position = position; currentDate = getDateAt(position); int weekOfTerm = getWeekOfTerm(currentDate); if (classTableMap == null) { return; } for (int stage = 1; stage <= 5; stage++) { // 设置上课时间 tvStageList.get(stage - 1).setText(ClassTable.getStageTimeString(stage, currentDate)); // 获取今天这一大节的课程列表 List<ClassTable.CourseWrapper> courseWrapperList = classTableMap.get(currentDate.getDayOfWeek() + "-" + stage); ViewGroup layoutStageShow = layoutStageShowList.get(stage - 1); ViewGroup layoutStageHide = layoutStageHideList.get(stage - 1); View iconStage = iconStageList.get(stage - 1); View btnStage = btnStageList.get(stage - 1); // 清除布局 layoutStageShow.removeAllViews(); layoutStageHide.removeAllViews(); // 更新布局显示 int showCount = 0; int hideCount = 0; for (int i = 0; i < (courseWrapperList == null ? 0 : courseWrapperList.size()); i++) { ClassTable.CourseWrapper courseWrapper = courseWrapperList.get(i); boolean isCurrent = weekOfTerm >= courseWrapper.getTimeAndPlace().getStartWeek() && weekOfTerm <= courseWrapper.getTimeAndPlace().getEndWeek() && (courseWrapper.getTimeAndPlace().getWeekMode() == null || courseWrapper.getTimeAndPlace().getWeekMode() == WeekMode.ALL || courseWrapper.getTimeAndPlace().getWeekMode() == WeekMode.ODD && weekOfTerm % 2 == 1 || courseWrapper.getTimeAndPlace().getWeekMode() == WeekMode.EVEN && weekOfTerm % 2 == 0); View viewCourse = isCurrent ? layoutStageShow.getChildAt(showCount) : layoutStageHide.getChildAt(hideCount); if (viewCourse == null) { viewCourse = inflater.inflate(R.layout.activity_class_table_page_item_course, isCurrent ? layoutStageShow : layoutStageHide, false); viewCourse.setTag(new CourseViewHolder(viewCourse)); if (isCurrent) { layoutStageShow.addView(viewCourse); showCount++; } else { layoutStageHide.addView(viewCourse); hideCount++; } } CourseViewHolder holder = (CourseViewHolder) viewCourse.getTag(); holder.update(courseWrapper, isCurrent); } // 更新整体布局状态 layoutStageShow.setVisibility(showCount > 0 ? View.VISIBLE : View.GONE); iconStage.setVisibility(showCount > 0 ? View.GONE : View.VISIBLE); layoutStageHide.setVisibility(TextUtils.isEmpty(openStateMap.get(currentDate.toString() + "-" + stage)) ? View.GONE : View.VISIBLE); btnStage.setVisibility(layoutStageHide.getChildCount() > 0 ? View.VISIBLE : View.GONE); } } @OnClick({ R.id.btn_stage_1, R.id.btn_stage_2, R.id.btn_stage_3, R.id.btn_stage_4, R.id.btn_stage_5, }) protected void onBtnStage1Click(View view) { switch (view.getId()) { case R.id.btn_stage_1: toggleLayout(1); break; case R.id.btn_stage_2: toggleLayout(2); break; case R.id.btn_stage_3: toggleLayout(3); break; case R.id.btn_stage_4: toggleLayout(4); break; case R.id.btn_stage_5: toggleLayout(5); break; } } private void toggleLayout(int stage) { ViewGroup layoutStageHide = layoutStageHideList.get(stage - 1); layoutStageHide.setVisibility(layoutStageHide.getVisibility() == View.VISIBLE ? View.GONE : View.VISIBLE); openStateMap.put(currentDate.toString() + "-" + stage, layoutStageHide.getVisibility() == View.VISIBLE ? "true" : null); } } protected class CourseViewHolder { @BindView(R.id.tv_name) protected TextView tvName; @BindView(R.id.tv_teacher) protected TextView tvTeacher; @BindView(R.id.tv_place) protected TextView tvPlace; @BindView(R.id.icon_not_current) protected View iconNotCurrent; protected ClassTable.CourseWrapper courseWrapper; public CourseViewHolder(View convertView) { ButterKnife.bind(this, convertView); } public void update(ClassTable.CourseWrapper courseWrapper, boolean isCurrent) { this.courseWrapper = courseWrapper; tvName.setText(courseWrapper.getCourse().getName()); tvTeacher.setText(courseWrapper.getCourse().getTeacher()); tvPlace.setText(courseWrapper.getTimeAndPlace().getRoom()); iconNotCurrent.setVisibility(isCurrent ? View.GONE : View.VISIBLE); } @OnClick(R.id.btn_card) protected void onBtnCardClick() { if (courseWrapper != null) { Intent intent = new Intent(context, ClassTableCourseActivity.class); intent.putExtra("course", EntityUtils.gson.toJson(courseWrapper.getCourse())); intent.putExtra("year", classTable.getYear()); intent.putExtra("term", classTable.getTerm()); context.startActivity(intent); } } } }