Android Open Source - android-festival-timetable Mmt Timetable






From Project

Back to project page android-festival-timetable.

License

The source code is released under:

MIT License

If you think the Android project android-festival-timetable listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package com.mymusictaste.festival;
//ww  w .  j a  v a  2  s. c  o  m
import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.support.v7.widget.GridLayout;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.*;
import android.widget.*;
import com.google.gson.reflect.TypeToken;
import com.mymusictaste.festival.type.Schedule;
import com.mymusictaste.festival.type.Stage;
import org.json.JSONArray;
import com.google.gson.Gson;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.TimeZone;

/**
 * Created by JKtheUnique on 14. 3. 11.
 */
public class MmtTimetable extends LinearLayout{
  private final long oneDay = 24L*60L*60L*1000L;
  private final String BRICK_TAG_FORMAT = "%dx%d";

  private Context context;

  private int FESTIVAL_DAYS = 1;
  private int STAGE_COUNT = 1;
    private int BRICK_COUNT_IN_AN_HOUR = 60/10;
    private boolean STRETCH_MODE = false;
  private int BRICK_WIDTH = getPxfromDp(130);
  private int BRICK_HEIGHT = getPxfromDp(20);
  private int TIME_AXIS_WIDTH = getPxfromDp(40);
  private int TIME_AXIS_HEIGHT = BRICK_HEIGHT*BRICK_COUNT_IN_AN_HOUR;
    private int ROW_COUNT = 24*BRICK_COUNT_IN_AN_HOUR;
  private long START_TIME;

  private LinearLayout timetableContainer;
    private LinearLayout festivalDaysLayout;
  private ScrollView vScrollView;
  private HorizontalScrollView hScrollView;
  private LinearLayout gridContent;
  private LinearLayout timeAxisLayout;
  private HorizontalScrollView placeScrollView;
  private LinearLayout placeLayout;

  private ArrayList<Schedule> allSchedules = new ArrayList<Schedule>();
  private ArrayList<Stage> allStages = new ArrayList<Stage>();
    private ArrayList<RelativeLayout> festivalDays = new ArrayList<RelativeLayout>();
  private ArrayList<GridLayout> timetables = new ArrayList<GridLayout>();

  private LayoutInflater mInflater;

  public MmtTimetable(Context context, AttributeSet attrs){
    super(context, attrs);
    this.context = context;
        parseAttributes(context.obtainStyledAttributes(attrs,R.styleable.Timetable));
    initLayout();
        scrollToDay(0);
  }

  public MmtTimetable(Context context, AttributeSet attrs,long startTime, int festivalDays, ArrayList<Stage> stages, ArrayList<Schedule> schedules ){
    super(context, attrs);
    this.context = context;
    initLayout();
        parseAttributes(context.obtainStyledAttributes(attrs,R.styleable.Timetable));
    setData(startTime, festivalDays, stages, schedules);
  }

  public MmtTimetable(Context context, long startTime, int festivalDays, ArrayList<Stage> stages, ArrayList<Schedule> schedules){
    super(context);
    this.context = context;
    initLayout();
    setData(startTime, festivalDays, stages, schedules);
  }

  public void setData(long startTime, int festivalDays, ArrayList<Stage> stages, ArrayList<Schedule> schedules){
    START_TIME = startTime;
    allStages = stages;
    allSchedules = schedules;
        FESTIVAL_DAYS = festivalDays;
    createGrid(stages);
    populateTimetable(allSchedules);
        scrollToDay(0);
  }

    public void setData(ArrayList<Stage> stages, ArrayList<Schedule> schedules){
        allSchedules = schedules;
        allStages = stages;
        createGrid(stages);
        populateTimetable(allSchedules);
        scrollToDay(0);
    }

    public void setStartTime(long startTime){
        START_TIME = startTime;
    }

    public long getStartTime(){
        return START_TIME;
    }

    public void setFestivalDays(int days){
        FESTIVAL_DAYS = days;
    }

    public int getFestivalDays(){
        return FESTIVAL_DAYS;
    }

    public void setStageCount(int count){
        STAGE_COUNT = count;
    }

    public int getStageCount(){
        return STAGE_COUNT;
    }

    public void setSchedule(ArrayList<Schedule> schedules){
        allSchedules = schedules;
    }

    public ArrayList<Schedule> getSchedule(){
        return allSchedules;
    }

    public String getScheduleJSON(){
        return new Gson().toJson(allSchedules);
    }

    public void setScheduleJSON(String scheduleJSON){
        allSchedules = new Gson().fromJson(scheduleJSON, new TypeToken<ArrayList<Schedule>>(){}.getType());
    }

    public void setStage(ArrayList<Stage> stages){
        allStages = stages;
    }

    public ArrayList<Stage> getStage(){
        return allStages;
    }

    public String getStageJSON(){
        return new Gson().toJson(allStages);
    }

    public void setStageJSON(String stageJSON){
        allSchedules = new Gson().fromJson(stageJSON, new TypeToken<ArrayList<Stage>>() {}.getType());
    }

    public void setStretchMode(boolean stretchMode){
        STRETCH_MODE = stretchMode;
    }

    public boolean isStretch(){
        return STRETCH_MODE;
    }


  private void initLayout(){
    mInflater =  (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
//    mInflater = LayoutInflater.from(context);
    timetableContainer = (LinearLayout) mInflater.inflate(R.layout.mmt_timetable, null);
    addView(timetableContainer,new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT));

        festivalDaysLayout = (LinearLayout) timetableContainer.findViewById(R.id.timetable_date_layout);
    vScrollView = (ScrollView) timetableContainer.findViewById(R.id.vscrollview);
    hScrollView = (HorizontalScrollView) timetableContainer.findViewById(R.id.hscrollview);
    timeAxisLayout = (LinearLayout) timetableContainer.findViewById(R.id.time_axis_layout);
    placeScrollView = (HorizontalScrollView) timetableContainer.findViewById(R.id.place_scroll);
    placeLayout = (LinearLayout) timetableContainer.findViewById(R.id.place_layout);
    gridContent = (LinearLayout) timetableContainer.findViewById(R.id.grid_content);

    placeScrollView.setHorizontalScrollBarEnabled(false);
    placeScrollView.setVerticalScrollBarEnabled(false);
    placeScrollView.setHorizontalFadingEdgeEnabled(false);
    placeScrollView.setVerticalFadingEdgeEnabled(false);
    vScrollView.setHorizontalFadingEdgeEnabled(false);
    vScrollView.setVerticalFadingEdgeEnabled(false);
    hScrollView.setHorizontalFadingEdgeEnabled(false);
    hScrollView.setVerticalFadingEdgeEnabled(false);
    setScrollListener();
  }
  private void setScrollListener(){
    placeScrollView.setOnTouchListener(new View.OnTouchListener() {

      @Override
      public boolean onTouch(View v, MotionEvent event) {
        return false;
      }
    });
    hScrollView.setOnTouchListener(new View.OnTouchListener() {
      float mx, curX;
      boolean started = false;

      @Override
      public boolean onTouch(View v, MotionEvent event) {
        curX = event.getX();
        int dx = (int) (mx - curX);
        switch (event.getAction()) {
          case MotionEvent.ACTION_MOVE:
            if (started) {
              placeScrollView.scrollBy(dx, 0);
            } else {
              started = true;
            }
            mx = curX;
            break;
          case MotionEvent.ACTION_UP:
            placeScrollView.scrollBy(dx, 0);
            started = false;
            break;
        }
        return false;
      }
    });
    vScrollView.setOnTouchListener(new View.OnTouchListener() {
      float mx, my, curX, curY;
      boolean started = false;
      @Override
      public boolean onTouch(View v, MotionEvent event) {
        curX = event.getX();
        curY = event.getY();
        int dx = (int) (mx - curX);
        int dy = (int) (my - curY);
        switch (event.getAction()) {
          case MotionEvent.ACTION_MOVE:
            if (started) {
              vScrollView.scrollBy(0, dy);
              hScrollView.scrollBy(dx, 0);
              placeScrollView.scrollBy(dx, 0);
            } else {
              started = true;
            }
            mx = curX;
            my = curY;
            break;
          case MotionEvent.ACTION_UP:
            vScrollView.scrollBy(0, dy);
            hScrollView.scrollBy(dx, 0);
            placeScrollView.scrollBy(dx, 0);
            started = false;
//            checkCurrentDate();
            break;
        }
        return true;
      }
    });
  }

  private void createGrid(ArrayList<Stage> stages){
        if(FESTIVAL_DAYS>0){
            festivalDaysLayout.removeAllViews();
            festivalDays.clear();
            for(int currentDay = 0; currentDay<FESTIVAL_DAYS;currentDay++) {
                RelativeLayout dateLayout = (RelativeLayout) mInflater.inflate(R.layout.layout_timetable_date, null);
                TextView dateText = (TextView) dateLayout.findViewById(R.id.date_text);
                LinearLayout.LayoutParams params = new LayoutParams(0,getPxfromDp(48));
                params.weight=1f;
                dateLayout.setLayoutParams(params);
                if (START_TIME > 0)
                    dateText.setText(getDateString(new Date((START_TIME + (long)currentDay*60L*60L*24L)*1000L)));
                dateLayout.setOnClickListener(new OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        if(festivalDays.size()>0) {
                            scrollToDay(festivalDays.indexOf(v));
                        }
                    }
                });
                festivalDays.add(currentDay, dateLayout);
                festivalDaysLayout.addView(dateLayout);
            }
        }else
            festivalDaysLayout.removeAllViews();

    STAGE_COUNT = stages.size();
    for(int currentGrid = 0; currentGrid<FESTIVAL_DAYS; currentGrid++){
      GridLayout gridLayout = new GridLayout(context);
      gridLayout.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
      gridLayout.setColumnCount(STAGE_COUNT);
      gridLayout.setRowCount(ROW_COUNT);
      timetables.add(currentGrid,gridLayout);
    }
    initGrid();
  }

  private void initGrid(){
        if(STRETCH_MODE)
            BRICK_WIDTH = (((Activity)context).getWindowManager().getDefaultDisplay().getWidth()-TIME_AXIS_WIDTH)/STAGE_COUNT;
    boolean border;
    for(int currentColumn = 0; currentColumn<STAGE_COUNT; currentColumn++){
      TextView placeText = new TextView(context);
      placeText.setText(allStages.get(currentColumn).getStageName());
      placeText.setWidth(BRICK_WIDTH);
      placeText.setHeight(TIME_AXIS_WIDTH);
      placeText.setBackgroundColor(Color.parseColor("#333333"));
      placeText.setTextSize(TypedValue.COMPLEX_UNIT_SP, 11);
      placeText.setTextColor(Color.WHITE);
      placeText.setGravity(Gravity.CENTER);
      placeLayout.addView(placeText);
    }
    for(int currentTime = 0; currentTime<(ROW_COUNT/BRICK_COUNT_IN_AN_HOUR)*FESTIVAL_DAYS; currentTime++){
      TextView timeText = new TextView(context);
      timeText.setText(getTimeStringOnlyHour(new Date((START_TIME + (long)currentTime*60L*60L)*1000L )));
      timeText.setTextSize(TypedValue.COMPLEX_UNIT_SP, 11);
      timeText.setTextColor(Color.WHITE);
      timeText.setWidth(TIME_AXIS_WIDTH);
      timeText.setHeight(TIME_AXIS_HEIGHT);
      timeText.setGravity(Gravity.CENTER_HORIZONTAL);
      timeText.setBackgroundColor(Color.parseColor("#555555"));
      timeAxisLayout.addView(timeText);
    }
    for(int currentColumn=0; currentColumn<STAGE_COUNT; currentColumn++){
      for(int currentRow=0; currentRow<ROW_COUNT; currentRow++){
        if(currentRow%BRICK_COUNT_IN_AN_HOUR==BRICK_COUNT_IN_AN_HOUR-1) border = true;
        else border = false;
        for(int currentGrid=0; currentGrid<FESTIVAL_DAYS;currentGrid++)
            addBrick(timetables.get(currentGrid), currentColumn,currentRow,border);
      }
    }
  }
  private void addBrick(GridLayout lineupTable,int column, int row, boolean border){
    addBrick(lineupTable, column, row, 1, border, null);
  }

  private void addBrick(GridLayout lineupTable,int column, int row, int rowSpan, boolean border, Schedule schedule){
    if(schedule==null){
      View brick = new View(context);
      String tag = String.format(BRICK_TAG_FORMAT,column,row);
      GridLayout.Spec columnSpec = GridLayout.spec(column);
      GridLayout.Spec rowSpec = GridLayout.spec(row, GridLayout.BASELINE);
      GridLayout.LayoutParams gParams = new GridLayout.LayoutParams(new ViewGroup.LayoutParams(BRICK_WIDTH,BRICK_HEIGHT));
      if(border)
        brick.setBackgroundResource(R.drawable.bg_timetable_6th);
      else
        brick.setBackgroundResource(R.drawable.bg_timetable);
      brick.setTag(tag);
      gParams.rowSpec= rowSpec;
      gParams.columnSpec = columnSpec;
      lineupTable.addView(brick, gParams);
    }
    else{
      GridLayout.Spec columnSpec = GridLayout.spec(column);
      GridLayout.Spec  rowSpec = GridLayout.spec(row, rowSpan,GridLayout.BASELINE);
      GridLayout.LayoutParams gParams = new GridLayout.LayoutParams(new ViewGroup.LayoutParams(BRICK_WIDTH,BRICK_HEIGHT*rowSpan));
      RelativeLayout brick = (RelativeLayout) mInflater.inflate(R.layout.layout_timetable_cell, null);
      TextView brickText = (TextView)brick.findViewById(R.id.timetable_cell_text);
      brickText.setText(schedule.getScheduleTitle());
      brickText.setTag(schedule);

      gParams.rowSpec= rowSpec;
      gParams.columnSpec = columnSpec;
      lineupTable.addView(brick, gParams);
    }
  }

  private void populateTimetable(ArrayList<Schedule> schedules){
    for (Schedule schedule : schedules){
      int day = calculatePosition(schedule);
      long dayStart = START_TIME + (oneDay*(long)day);
      addConcertBrick(timetables.get(day),schedule,dayStart);
    }
    for(int currentDay = 0; currentDay<FESTIVAL_DAYS; currentDay++){
      gridContent.addView(timetables.get(currentDay));
    }
  }

  private int calculatePosition(Schedule schedule){
    long interval = schedule.getScheduleStartTime()-START_TIME;
    int day = (int)(interval/oneDay);
    return day;
  }

  private void addConcertBrick(GridLayout lineupTable, Schedule schedule,long dayStart){
    int startRow = calculateRow(dayStart,schedule.getScheduleStartTime());
    int rowSpan = calculateRow(schedule.getScheduleStartTime(),schedule.getScheduleEndTime());
    int column = calculateColumn(schedule.getScheduleStageId());

    if((startRow+rowSpan)%BRICK_COUNT_IN_AN_HOUR == 0&&startRow+rowSpan<ROW_COUNT){
      View view = lineupTable.findViewWithTag(String.format(BRICK_TAG_FORMAT,column,startRow+rowSpan));
      view.setBackgroundResource(R.drawable.bg_timetable_1st);
    }
        if(startRow+rowSpan<ROW_COUNT)
            addBrick(lineupTable, column, startRow,rowSpan,true, schedule);
        else
            addBrick(lineupTable, column, startRow,ROW_COUNT-startRow,true, schedule);

  }

  private int calculateRow(long start, long end){
    int row = 0;
    if(end<start) {
//            Toast.makeText(context, "wrong time sequence error", Toast.LENGTH_SHORT).show();
        }else
      row = (int)((end-start)/(10L*60L*1000L));
    return row;
  }

  private int calculateColumn(int stageId){
    int column = 0;
    for(Stage stage : allStages){
      if(stageId == stage.getStageId())
        column = allStages.indexOf(stage);
    }
    return column;
  }

  public void scrollToDay(int dayNumber){
    if(dayNumber<=FESTIVAL_DAYS&&festivalDays.size()>0) {
            vScrollView.smoothScrollTo(0, BRICK_HEIGHT * ROW_COUNT * dayNumber);
            for (RelativeLayout currentLayout : festivalDays) {
                if (dayNumber == festivalDays.indexOf(currentLayout))
                    currentLayout.findViewById(R.id.date_state).setVisibility(View.VISIBLE);
                else
                    currentLayout.findViewById(R.id.date_state).setVisibility(View.GONE);
            }
        }
  }

  private int getPxfromDp(int dp){
    return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, Resources.getSystem().getDisplayMetrics());
  }

  private String getTimeStringOnlyHour(Date date){
    SimpleDateFormat dateformat= new SimpleDateFormat("HH:mm");
    dateformat.setTimeZone(TimeZone.getDefault());
    return dateformat.format(date);
  }

    private String getDateString(Date date){
        SimpleDateFormat dateformat= new SimpleDateFormat("MM.dd.");
        dateformat.setTimeZone(TimeZone.getDefault());
        return dateformat.format(date);
    }

    private void parseAttributes(TypedArray a) {
        START_TIME = (long) a.getInteger(R.styleable.Timetable_start_time,0);
        FESTIVAL_DAYS = a.getInt(R.styleable.Timetable_festival_days,FESTIVAL_DAYS);
        STRETCH_MODE = a.getBoolean(R.styleable.Timetable_stretch_mode,false);
        BRICK_WIDTH = (int) a.getDimension(R.styleable.Timetable_cell_width,BRICK_WIDTH);
        BRICK_HEIGHT = (int) a.getDimension(R.styleable.Timetable_cell_height,BRICK_HEIGHT);
        TIME_AXIS_WIDTH = (int) a.getDimension(R.styleable.Timetable_time_axis_width,TIME_AXIS_WIDTH);
        TIME_AXIS_HEIGHT = BRICK_HEIGHT*BRICK_COUNT_IN_AN_HOUR;
    }

}




Java Source Code List

com.mymusictaste.festival.MmtTimetable.java
com.mymusictaste.festival.SampleActivity.java
com.mymusictaste.festival.type.Schedule.java
com.mymusictaste.festival.type.Stage.java