Refactor custom views

pull/30/head
Alinson S. Xavier 10 years ago
parent e6a5751959
commit 0e5764cf5d

@ -22,52 +22,93 @@ import android.graphics.Color;
import android.graphics.Paint; import android.graphics.Paint;
import android.graphics.Paint.Align; import android.graphics.Paint.Align;
import android.graphics.Rect; import android.graphics.Rect;
import android.support.v4.view.MotionEventCompat;
import android.view.MotionEvent;
import android.view.View;
import org.isoron.helpers.ColorHelper; import org.isoron.helpers.ColorHelper;
import org.isoron.helpers.DateHelper; import org.isoron.helpers.DateHelper;
import org.isoron.uhabits.R;
import org.isoron.uhabits.models.Habit; import org.isoron.uhabits.models.Habit;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Calendar; import java.util.Calendar;
import java.util.GregorianCalendar; import java.util.GregorianCalendar;
public class HabitHistoryView extends View public class HabitHistoryView extends ScrollableDataView
{ {
private Habit habit; private Habit habit;
private int[] checks; private int[] checkmarks;
private Context context;
private Paint pSquareBg, pSquareFg, pTextHeader; private Paint pSquareBg, pSquareFg, pTextHeader;
private int squareSpacing;
private int squareSize, squareSpacing; private float squareTextOffset;
private int nColumns, offsetWeeks; private float headerTextOffset;
private int colorPrimary, colorPrimaryBrighter, grey;
private Float prevX, prevY;
private String wdays[]; private String wdays[];
private SimpleDateFormat dfMonth;
private SimpleDateFormat dfYear;
private Calendar baseDate;
private int nDays;
private int todayWeekday;
private int colors[];
public HabitHistoryView(Context context, Habit habit, int squareSize) public HabitHistoryView(Context context, Habit habit, int baseSize)
{ {
super(context); super(context);
this.habit = habit; this.habit = habit;
this.context = context;
this.squareSize = squareSize;
colorPrimary = habit.color; setDimensions(baseSize);
colorPrimaryBrighter = ColorHelper.mixColors(colorPrimary, Color.WHITE, 0.5f); createPaints();
grey = Color.rgb(230, 230, 230); createColors();
wdays = DateHelper.getShortDayNames();
dfMonth = new SimpleDateFormat("MMM");
dfYear = new SimpleDateFormat("yyyy");
}
private void updateDate()
{
baseDate = new GregorianCalendar();
baseDate.add(Calendar.DAY_OF_YEAR, -(dataOffset - 1) * 7);
nDays = nColumns * 7;
todayWeekday = new GregorianCalendar().get(Calendar.DAY_OF_WEEK) % 7;
baseDate.add(Calendar.DAY_OF_YEAR, -nDays);
baseDate.add(Calendar.DAY_OF_YEAR, -todayWeekday);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh)
{
super.onSizeChanged(w, h, oldw, oldh);
updateDate();
}
private void createColors()
{
int primaryColor = habit.color;
int primaryColorBright = ColorHelper.mixColors(primaryColor, Color.WHITE, 0.5f);
int grey = Color.rgb(230, 230, 230);
colors = new int[3];
colors[0] = grey;
colors[1] = primaryColorBright;
colors[2] = primaryColor;
}
private void setDimensions(int baseSize)
{
columnWidth = baseSize;
columnHeight = 8 * baseSize;
squareSpacing = 2; squareSpacing = 2;
}
private void createPaints()
{
pTextHeader = new Paint(); pTextHeader = new Paint();
pTextHeader.setColor(Color.LTGRAY); pTextHeader.setColor(Color.LTGRAY);
pTextHeader.setTextAlign(Align.LEFT); pTextHeader.setTextAlign(Align.LEFT);
pTextHeader.setTextSize(squareSize * 0.5f); pTextHeader.setTextSize(columnWidth * 0.5f);
pTextHeader.setAntiAlias(true); pTextHeader.setAntiAlias(true);
pSquareBg = new Paint(); pSquareBg = new Paint();
@ -76,179 +117,123 @@ public class HabitHistoryView extends View
pSquareFg = new Paint(); pSquareFg = new Paint();
pSquareFg.setColor(Color.WHITE); pSquareFg.setColor(Color.WHITE);
pSquareFg.setAntiAlias(true); pSquareFg.setAntiAlias(true);
pSquareFg.setTextSize(squareSize * 0.5f); pSquareFg.setTextSize(columnWidth * 0.5f);
pSquareFg.setTextAlign(Align.CENTER); pSquareFg.setTextAlign(Align.CENTER);
wdays = DateHelper.getShortDayNames(); squareTextOffset = pSquareFg.getFontSpacing() * 0.4f;
headerTextOffset = pTextHeader.getFontSpacing() * 0.3f;
} }
@Override protected void fetchData()
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
setMeasuredDimension(getMeasuredWidth(), 8 * squareSize);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh)
{
nColumns = (w / squareSize) - 1;
fetchReps();
}
private void fetchReps()
{ {
Calendar currentDate = new GregorianCalendar(); Calendar currentDate = new GregorianCalendar();
currentDate.add(Calendar.DAY_OF_YEAR, -offsetWeeks * 7); currentDate.add(Calendar.DAY_OF_YEAR, -dataOffset * 7);
int dayOfWeek = currentDate.get(Calendar.DAY_OF_WEEK) % 7; int dayOfWeek = currentDate.get(Calendar.DAY_OF_WEEK) % 7;
long dateTo = DateHelper.getStartOfToday(); long dateTo = DateHelper.getStartOfToday();
for (int i = 0; i < 7 - dayOfWeek; i++) for (int i = 0; i < 7 - dayOfWeek; i++)
dateTo += DateHelper.millisecondsInOneDay; dateTo += DateHelper.millisecondsInOneDay;
for (int i = 0; i < offsetWeeks * 7; i++) for (int i = 0; i < dataOffset * 7; i++)
dateTo -= DateHelper.millisecondsInOneDay; dateTo -= DateHelper.millisecondsInOneDay;
long dateFrom = dateTo; long dateFrom = dateTo;
for (int i = 0; i < nColumns * 7; i++) for (int i = 0; i < nColumns * 7; i++)
dateFrom -= DateHelper.millisecondsInOneDay; dateFrom -= DateHelper.millisecondsInOneDay;
checks = habit.getCheckmarks(dateFrom, dateTo); checkmarks = habit.getCheckmarks(dateFrom, dateTo);
updateDate();
} }
private String previousMonth;
private String previousYear;
private boolean justPrintedYear;
@Override @Override
protected void onDraw(Canvas canvas) protected void onDraw(Canvas canvas)
{ {
super.onDraw(canvas); super.onDraw(canvas);
Rect square = new Rect(0, 0, squareSize - squareSpacing, squareSize - squareSpacing); Rect location = new Rect(0, 0, columnWidth - squareSpacing, columnWidth - squareSpacing);
Calendar currentDate = new GregorianCalendar(); previousMonth = "";
currentDate.add(Calendar.DAY_OF_YEAR, -(offsetWeeks - 1) * 7); previousYear = "";
justPrintedYear = false;
int nDays = nColumns * 7;
int todayWeekday = new GregorianCalendar().get(Calendar.DAY_OF_WEEK) % 7;
currentDate.add(Calendar.DAY_OF_YEAR, -nDays);
currentDate.add(Calendar.DAY_OF_YEAR, -todayWeekday);
SimpleDateFormat dfMonth = new SimpleDateFormat("MMM"); GregorianCalendar currentDate = (GregorianCalendar) baseDate.clone();
SimpleDateFormat dfYear = new SimpleDateFormat("yyyy");
String previousMonth = ""; for (int column = 0; column < nColumns - 1; column++)
String previousYear = ""; {
drawColumn(canvas, location, currentDate, column);
location.offset(columnWidth, -columnHeight);
}
int colors[] = {grey, colorPrimaryBrighter, colorPrimary}; drawAxis(canvas, location);
String markers[] = }
{context.getString(R.string.fa_times), context.getString(R.string.fa_check),
context.getString(R.string.fa_check)};
float squareTextOffset = pSquareFg.getFontSpacing() * 0.4f; private void drawColumn(Canvas canvas, Rect location, GregorianCalendar date, int column)
float headerTextOffset = pTextHeader.getFontSpacing() * 0.3f; {
boolean justPrintedYear = false; drawColumnHeader(canvas, location, date);
location.offset(0, columnWidth);
int k = nDays; for (int j = 0; j < 7; j++)
for (int i = 0; i < nColumns; i++)
{ {
String month = dfMonth.format(currentDate.getTime()); if (!(column == nColumns - 2 && dataOffset == 0 && j > todayWeekday))
String year = dfYear.format(currentDate.getTime());
if (!month.equals(previousMonth))
{ {
int offset = 0; int checkmarkOffset = nDays - 7 * column - j;
if (justPrintedYear) offset += squareSize; drawSquare(canvas, location, date, checkmarkOffset);
canvas.drawText(month, square.left + offset, square.bottom - headerTextOffset,
pTextHeader);
previousMonth = month;
justPrintedYear = false;
}
else if (!year.equals(previousYear))
{
canvas.drawText(year, square.left, square.bottom - headerTextOffset, pTextHeader);
previousYear = year;
justPrintedYear = true;
}
else
{
justPrintedYear = false;
} }
date.add(Calendar.DAY_OF_MONTH, 1);
location.offset(0, columnWidth);
}
}
square.offset(0, squareSize); private void drawSquare(Canvas canvas, Rect location, GregorianCalendar date,
int checkmarkOffset)
for (int j = 0; j < 7; j++) {
{ if (checkmarkOffset >= checkmarks.length) pSquareBg.setColor(colors[0]);
if (!(i == nColumns - 1 && offsetWeeks == 0 && j > todayWeekday)) else pSquareBg.setColor(colors[checkmarks[checkmarkOffset]]);
{
if (k >= checks.length) pSquareBg.setColor(colors[0]);
else pSquareBg.setColor(colors[checks[k]]);
canvas.drawRect(square, pSquareBg);
canvas.drawText(Integer.toString(currentDate.get(Calendar.DAY_OF_MONTH)),
square.centerX(), square.centerY() + squareTextOffset, pSquareFg);
}
currentDate.add(Calendar.DAY_OF_MONTH, 1);
square.offset(0, squareSize);
k--;
}
square.offset(squareSize, -8 * squareSize); canvas.drawRect(location, pSquareBg);
} String text = Integer.toString(date.get(Calendar.DAY_OF_MONTH));
canvas.drawText(text, location.centerX(), location.centerY() + squareTextOffset, pSquareFg);
}
private void drawAxis(Canvas canvas, Rect location)
{
for (int i = 0; i < 7; i++) for (int i = 0; i < 7; i++)
{ {
square.offset(0, squareSize); location.offset(0, columnWidth);
canvas.drawText(wdays[i], square.left + headerTextOffset, canvas.drawText(wdays[i], location.left + headerTextOffset,
square.bottom - headerTextOffset, pTextHeader); location.bottom - headerTextOffset, pTextHeader);
} }
} }
@Override private void drawColumnHeader(Canvas canvas, Rect location, GregorianCalendar date)
public boolean onTouchEvent(MotionEvent event)
{ {
int action = event.getAction(); String month = dfMonth.format(date.getTime());
String year = dfYear.format(date.getTime());
int pointerIndex = MotionEventCompat.getActionIndex(event);
final float x = MotionEventCompat.getX(event, pointerIndex);
final float y = MotionEventCompat.getY(event, pointerIndex);
if (action == MotionEvent.ACTION_DOWN) if (!month.equals(previousMonth))
{ {
prevX = x; int offset = 0;
prevY = y; if (justPrintedYear) offset += columnWidth;
}
if (action == MotionEvent.ACTION_MOVE) canvas.drawText(month, location.left + offset, location.bottom - headerTextOffset,
pTextHeader);
previousMonth = month;
justPrintedYear = false;
}
else if (!year.equals(previousYear))
{ {
float dx = x - prevX; canvas.drawText(year, location.left, location.bottom - headerTextOffset, pTextHeader);
float dy = y - prevY; previousYear = year;
justPrintedYear = true;
if (Math.abs(dy) > Math.abs(dx)) return false;
getParent().requestDisallowInterceptTouchEvent(true);
if (move(dx))
{
prevX = x;
prevY = y;
}
} }
else
return true;
}
private boolean move(float dx)
{
int newOffsetWeeks = offsetWeeks + (int) (dx / squareSize);
newOffsetWeeks = Math.max(0, newOffsetWeeks);
if (newOffsetWeeks != offsetWeeks)
{ {
offsetWeeks = newOffsetWeeks; justPrintedYear = false;
fetchReps();
invalidate();
return true;
} }
else return false;
} }
} }

@ -21,9 +21,6 @@ import android.graphics.Canvas;
import android.graphics.Color; import android.graphics.Color;
import android.graphics.Paint; import android.graphics.Paint;
import android.graphics.RectF; import android.graphics.RectF;
import android.support.v4.view.MotionEventCompat;
import android.view.MotionEvent;
import android.view.View;
import org.isoron.helpers.ColorHelper; import org.isoron.helpers.ColorHelper;
import org.isoron.helpers.DateHelper; import org.isoron.helpers.DateHelper;
@ -33,30 +30,23 @@ import org.isoron.uhabits.models.Score;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.List; import java.util.List;
public class HabitScoreView extends View public class HabitScoreView extends ScrollableDataView
{ {
public static final int BUCKET_SIZE = 7; public static final int BUCKET_SIZE = 7;
private final Paint pGrid; private final Paint pGrid;
private final float em; private final float em;
private Habit habit; private Habit habit;
private int columnWidth, columnHeight, nColumns;
private Paint pText, pGraph; private Paint pText, pGraph;
private int dataOffset;
private int barHeaderHeight;
private int[] colors; private int[] colors;
private float prevX;
private float prevY;
private List<Score> scores; private List<Score> scores;
public HabitScoreView(Context context, Habit habit, int columnWidth) public HabitScoreView(Context context, Habit habit, int columnWidth)
{ {
super(context); super(context);
this.habit = habit; this.habit = habit;
this.columnWidth = columnWidth;
pText = new Paint(); pText = new Paint();
pText.setColor(Color.LTGRAY); pText.setColor(Color.LTGRAY);
@ -75,8 +65,11 @@ public class HabitScoreView extends View
pGrid.setAntiAlias(true); pGrid.setAntiAlias(true);
pGrid.setStrokeWidth(columnWidth * 0.05f); pGrid.setStrokeWidth(columnWidth * 0.05f);
this.columnWidth = columnWidth;
columnHeight = 8 * columnWidth; columnHeight = 8 * columnWidth;
barHeaderHeight = columnWidth; headerHeight = columnWidth;
footerHeight = columnWidth;
em = pText.getFontSpacing(); em = pText.getFontSpacing();
colors = new int[4]; colors = new int[4];
@ -87,7 +80,7 @@ public class HabitScoreView extends View
colors[2] = ColorHelper.mixColors(colors[0], colors[3], 0.33f); colors[2] = ColorHelper.mixColors(colors[0], colors[3], 0.33f);
} }
private void fetchScores() protected void fetchData()
{ {
long toTimestamp = DateHelper.getStartOfToday(); long toTimestamp = DateHelper.getStartOfToday();
@ -102,31 +95,15 @@ public class HabitScoreView extends View
BUCKET_SIZE * DateHelper.millisecondsInOneDay, toTimestamp); BUCKET_SIZE * DateHelper.millisecondsInOneDay, toTimestamp);
} }
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
setMeasuredDimension(getMeasuredWidth(), columnHeight + 2 * barHeaderHeight);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh)
{
super.onSizeChanged(w, h, oldw, oldh);
nColumns = w / columnWidth;
fetchScores();
}
@Override @Override
protected void onDraw(Canvas canvas) protected void onDraw(Canvas canvas)
{ {
super.onDraw(canvas); super.onDraw(canvas);
float lineHeight = pText.getFontSpacing(); float lineHeight = pText.getFontSpacing();
float barHeaderOffset = lineHeight * 0.4f;
RectF rGrid = new RectF(0, 0, nColumns * columnWidth, columnHeight); RectF rGrid = new RectF(0, 0, nColumns * columnWidth, columnHeight);
rGrid.offset(0, barHeaderHeight); rGrid.offset(0, headerHeight);
drawGrid(canvas, rGrid); drawGrid(canvas, rGrid);
SimpleDateFormat dfMonth = new SimpleDateFormat("MMM"); SimpleDateFormat dfMonth = new SimpleDateFormat("MMM");
@ -150,7 +127,7 @@ public class HabitScoreView extends View
RectF r = new RectF(0, 0, columnWidth, columnWidth); RectF r = new RectF(0, 0, columnWidth, columnWidth);
r.offset(offset * columnWidth, r.offset(offset * columnWidth,
barHeaderHeight + columnHeight - height - columnWidth / 2); headerHeight + columnHeight - height - columnWidth / 2);
if (prevR != null) if (prevR != null)
{ {
@ -163,15 +140,11 @@ public class HabitScoreView extends View
prevR = r; prevR = r;
r = new RectF(0, 0, columnWidth, columnHeight); r = new RectF(0, 0, columnWidth, columnHeight);
r.offset(offset * columnWidth, barHeaderHeight); r.offset(offset * columnWidth, headerHeight);
if (!month.equals(previousMonth)) if (!month.equals(previousMonth))
{
canvas.drawText(month, r.centerX(), r.bottom + lineHeight * 1.2f, pText); canvas.drawText(month, r.centerX(), r.bottom + lineHeight * 1.2f, pText);
}
else else
{
canvas.drawText(day, r.centerX(), r.bottom + lineHeight * 1.2f, pText); canvas.drawText(day, r.centerX(), r.bottom + lineHeight * 1.2f, pText);
}
previousMonth = month; previousMonth = month;
@ -180,10 +153,6 @@ public class HabitScoreView extends View
private void drawGrid(Canvas canvas, RectF rGrid) private void drawGrid(Canvas canvas, RectF rGrid)
{ {
// pGrid.setColor(Color.rgb(230, 230, 230));
// pGrid.setStyle(Paint.Style.STROKE);
// canvas.drawRect(rGrid, pGrid);
int nRows = 5; int nRows = 5;
float rowHeight = rGrid.height() / nRows; float rowHeight = rGrid.height() / nRows;
@ -220,51 +189,4 @@ public class HabitScoreView extends View
pGraph.setColor(Color.WHITE); pGraph.setColor(Color.WHITE);
canvas.drawOval(rect, pGraph); canvas.drawOval(rect, pGraph);
} }
@Override
public boolean onTouchEvent(MotionEvent event)
{
int action = event.getAction();
int pointerIndex = MotionEventCompat.getActionIndex(event);
final float x = MotionEventCompat.getX(event, pointerIndex);
final float y = MotionEventCompat.getY(event, pointerIndex);
if (action == MotionEvent.ACTION_DOWN)
{
prevX = x;
prevY = y;
}
if (action == MotionEvent.ACTION_MOVE)
{
float dx = x - prevX;
float dy = y - prevY;
if (Math.abs(dy) > Math.abs(dx)) return false;
getParent().requestDisallowInterceptTouchEvent(true);
if (move(dx))
{
prevX = x;
prevY = y;
}
}
return true;
}
private boolean move(float dx)
{
int newDataOffset = dataOffset + (int) (dx / columnWidth);
newDataOffset = Math.max(0, newDataOffset);
if (newDataOffset != dataOffset)
{
dataOffset = newDataOffset;
fetchScores();
invalidate();
return true;
}
else return false;
}
} }

@ -21,9 +21,6 @@ import android.graphics.Canvas;
import android.graphics.Color; import android.graphics.Color;
import android.graphics.Paint; import android.graphics.Paint;
import android.graphics.Rect; import android.graphics.Rect;
import android.support.v4.view.MotionEventCompat;
import android.view.MotionEvent;
import android.view.View;
import org.isoron.helpers.ColorHelper; import org.isoron.helpers.ColorHelper;
import org.isoron.uhabits.models.Habit; import org.isoron.uhabits.models.Habit;
@ -32,29 +29,43 @@ import org.isoron.uhabits.models.Streak;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.List; import java.util.List;
public class HabitStreakView extends View public class HabitStreakView extends ScrollableDataView
{ {
private Habit habit; private Habit habit;
private int columnWidth, columnHeight, nColumns;
private Paint pText, pBar; private Paint pText, pBar;
private List<Streak> streaks; private List<Streak> streaks;
private int dataOffset;
private long maxStreakLength; private long maxStreakLength;
private int barHeaderHeight;
private int[] colors; private int[] colors;
private float prevX;
private float prevY;
public HabitStreakView(Context context, Habit habit, int columnWidth) public HabitStreakView(Context context, Habit habit, int columnWidth)
{ {
super(context); super(context);
this.habit = habit; this.habit = habit;
this.columnWidth = columnWidth;
setDimensions(columnWidth);
createPaints();
createColors();
}
private void setDimensions(int baseSize)
{
this.columnWidth = baseSize;
columnHeight = 8 * baseSize;
headerHeight = baseSize;
footerHeight = baseSize;
}
private void createColors()
{
colors = new int[4];
colors[0] = Color.rgb(230, 230, 230);
colors[3] = habit.color;
colors[1] = ColorHelper.mixColors(colors[0], colors[3], 0.66f);
colors[2] = ColorHelper.mixColors(colors[0], colors[3], 0.33f);
}
private void createPaints()
{
pText = new Paint(); pText = new Paint();
pText.setColor(Color.LTGRAY); pText.setColor(Color.LTGRAY);
pText.setTextAlign(Paint.Align.CENTER); pText.setTextAlign(Paint.Align.CENTER);
@ -65,21 +76,9 @@ public class HabitStreakView extends View
pBar.setTextAlign(Paint.Align.CENTER); pBar.setTextAlign(Paint.Align.CENTER);
pBar.setTextSize(columnWidth * 0.5f); pBar.setTextSize(columnWidth * 0.5f);
pBar.setAntiAlias(true); pBar.setAntiAlias(true);
columnHeight = 8 * columnWidth;
barHeaderHeight = columnWidth;
colors = new int[4];
colors[0] = Color.rgb(230, 230, 230);
colors[3] = habit.color;
colors[1] = ColorHelper.mixColors(colors[0], colors[3], 0.66f);
colors[2] = ColorHelper.mixColors(colors[0], colors[3], 0.33f);
fetchStreaks();
} }
private void fetchStreaks() protected void fetchData()
{ {
streaks = habit.getStreaks(); streaks = habit.getStreaks();
@ -87,19 +86,6 @@ public class HabitStreakView extends View
maxStreakLength = Math.max(maxStreakLength, s.length); maxStreakLength = Math.max(maxStreakLength, s.length);
} }
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
setMeasuredDimension(getMeasuredWidth(), columnHeight + 2 * barHeaderHeight);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh)
{
super.onSizeChanged(w, h, oldw, oldh);
nColumns = w / columnWidth;
}
@Override @Override
protected void onDraw(Canvas canvas) protected void onDraw(Canvas canvas)
@ -126,7 +112,7 @@ public class HabitStreakView extends View
int height = (int) (columnHeight * lRelative); int height = (int) (columnHeight * lRelative);
Rect r = new Rect(0, 0, columnWidth - 2, height); Rect r = new Rect(0, 0, columnWidth - 2, height);
r.offset(offset * columnWidth, barHeaderHeight + columnHeight - height); r.offset(offset * columnWidth, headerHeight + columnHeight - height);
canvas.drawRect(r, pBar); canvas.drawRect(r, pBar);
canvas.drawText(Long.toString(l), r.centerX(), r.top - barHeaderOffset, pBar); canvas.drawText(Long.toString(l), r.centerX(), r.top - barHeaderOffset, pBar);
@ -137,50 +123,4 @@ public class HabitStreakView extends View
previousMonth = month; previousMonth = month;
} }
} }
@Override
public boolean onTouchEvent(MotionEvent event)
{
int action = event.getAction();
int pointerIndex = MotionEventCompat.getActionIndex(event);
final float x = MotionEventCompat.getX(event, pointerIndex);
final float y = MotionEventCompat.getY(event, pointerIndex);
if (action == MotionEvent.ACTION_DOWN)
{
prevX = x;
prevY = y;
}
if (action == MotionEvent.ACTION_MOVE)
{
float dx = x - prevX;
float dy = y - prevY;
if (Math.abs(dy) > Math.abs(dx)) return false;
getParent().requestDisallowInterceptTouchEvent(true);
if (move(dx))
{
prevX = x;
prevY = y;
}
}
return true;
}
private boolean move(float dx)
{
int newDataOffset = dataOffset + (int) (dx / columnWidth);
newDataOffset = Math.max(0, Math.min(streaks.size() - nColumns, newDataOffset));
if (newDataOffset != dataOffset)
{
dataOffset = newDataOffset;
invalidate();
return true;
}
else return false;
}
} }

@ -0,0 +1,105 @@
/*
* Copyright (C) 2016 Alinson Santos Xavier
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
package org.isoron.uhabits.views;
import android.content.Context;
import android.support.v4.view.MotionEventCompat;
import android.view.MotionEvent;
import android.view.View;
public abstract class ScrollableDataView extends View
{
protected int dataOffset;
protected int nColumns;
protected int columnWidth, columnHeight;
protected int headerHeight, footerHeight;
private float prevX, prevY;
public ScrollableDataView(Context context)
{
super(context);
}
protected abstract void fetchData();
protected boolean move(float dx)
{
int newDataOffset = dataOffset + (int) (dx / columnWidth);
newDataOffset = Math.max(0, newDataOffset);
if (newDataOffset != dataOffset)
{
dataOffset = newDataOffset;
fetchData();
invalidate();
return true;
}
else return false;
}
@Override
public boolean onTouchEvent(MotionEvent event)
{
int action = event.getAction();
int pointerIndex = MotionEventCompat.getActionIndex(event);
final float x = MotionEventCompat.getX(event, pointerIndex);
final float y = MotionEventCompat.getY(event, pointerIndex);
if (action == MotionEvent.ACTION_DOWN)
{
prevX = x;
prevY = y;
}
if (action == MotionEvent.ACTION_MOVE)
{
float dx = x - prevX;
float dy = y - prevY;
if (Math.abs(dy) > Math.abs(dx)) return false;
getParent().requestDisallowInterceptTouchEvent(true);
if (move(dx))
{
prevX = x;
prevY = y;
}
}
return true;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
setMeasuredDimension(getMeasuredWidth(), columnHeight + headerHeight + footerHeight);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh)
{
super.onSizeChanged(w, h, oldw, oldh);
nColumns = w / columnWidth;
fetchData();
}
}
Loading…
Cancel
Save