Back to project page android-festival-timetable.
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.
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; } }