I'm Having a design where I need to show like this:
I am finished with all changes but I need to scroll to the position I clicked and it's not working
public class CircularLayoutManager extends LinearLayoutManager {
private static final int CIRCLE = 0;
private static final int ELLIPSE = 1;
private static final int MILLISECONDS_PER_INCH = 30;
private RecyclerView recyclerView;
private Rect recyclerBounds;
private int topOfFirstChild;
private Rect childDecoratedBoundsWithMargin;
private int verticalCenter;
private boolean scrolled;
private float radius;
private float majorRadius, minorRadius;
private float centerX;
private #LayoutPath int layoutPath;
#IntDef({CIRCLE, ELLIPSE})
#interface LayoutPath {
}
public CircularLayoutManager(Context context, int radius, int centerX) {
super(context);
this.radius = Utils.dpToPx(context, radius);
this.centerX = Utils.dpToPx(context, centerX);
layoutPath = ELLIPSE;
}
public CircularLayoutManager(Context context, int majorRadius, int minorRadius, int centerX) {
super(context);
this.majorRadius = Utils.dpToPx(context, majorRadius);
this.minorRadius = Utils.dpToPx(context, minorRadius);
this.centerX = Utils.dpToPx(context, centerX);
layoutPath = ELLIPSE;
}
#Override
public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
if (getItemCount() == 0) {
detachAndScrapAttachedViews(recycler);
return;
}
if (recyclerBounds == null) {
recyclerBounds = new Rect();
recyclerView.getHitRect(recyclerBounds);
verticalCenter = (recyclerBounds.height() / 2);
}
if (getChildCount() == 0) {
fill(0, recycler);
}
}
private void fill(int indexToStartFill, RecyclerView.Recycler recycler) {
if (indexToStartFill < 0) {
indexToStartFill = 0;
}
int childTop = topOfFirstChild;
detachAndScrapAttachedViews(recycler);
for (int i = indexToStartFill; i < getItemCount(); i++) {
View child = recycler.getViewForPosition(i);
measureChildWithMargins(child, 0, 0);
int sumOfHorizontalMargins = ((RecyclerView.LayoutParams) child.getLayoutParams()).leftMargin
+ ((RecyclerView.LayoutParams) child.getLayoutParams()).rightMargin;
int sumOfVerticalMargins = ((RecyclerView.LayoutParams) child.getLayoutParams()).topMargin
+ ((RecyclerView.LayoutParams) child.getLayoutParams()).bottomMargin;
int childLeft = 0;
switch (layoutPath) {
case CIRCLE:
childLeft = calculateCircleXFromY(childTop + (getDecoratedMeasuredHeight(child) +
getTopDecorationHeight(child) - getBottomDecorationHeight(child) + sumOfVerticalMargins) / 2);
break;
case ELLIPSE:
childLeft = calculateEllipseXFromY(childTop + (getDecoratedMeasuredHeight(child) +
getTopDecorationHeight(child) - getBottomDecorationHeight(child) + sumOfVerticalMargins) / 2);
break;
}
if (!(recyclerBounds.intersects(recyclerBounds.left + childLeft, recyclerBounds.top + childTop,
recyclerBounds.left + childLeft + getDecoratedMeasuredWidth(child) + sumOfHorizontalMargins,
recyclerBounds.top + childTop + getDecoratedMeasuredHeight(child) + sumOfVerticalMargins)
|| recyclerBounds.contains(recyclerBounds.left + childLeft, recyclerBounds.top + childTop,
recyclerBounds.left + childLeft + getDecoratedMeasuredWidth(child) + sumOfHorizontalMargins,
recyclerBounds.top + childTop + getDecoratedMeasuredHeight(child) + sumOfVerticalMargins))) {
break;
}
addView(child);
layoutDecoratedWithMargins(child, childLeft, childTop, childLeft + getDecoratedMeasuredWidth(child)
+ sumOfHorizontalMargins, childTop + getDecoratedMeasuredHeight(child) + sumOfVerticalMargins);
getDecoratedBoundsWithMargins(child, childDecoratedBoundsWithMargin);
scaleChild(child);
childTop += childDecoratedBoundsWithMargin.height();
}
List<RecyclerView.ViewHolder> scrapList = recycler.getScrapList();
for (int i = 0; i < scrapList.size(); i++) {
View viewRemoved = scrapList.get(i).itemView;
recycler.recycleView(viewRemoved);
}
if (!scrolled) {
stabilize();
}
}
#Override
public int scrollVerticallyBy(int dy, RecyclerView.Recycler recycler, RecyclerView.State state) {
if (!scrolled) {
scrolled = true;
}
int delta = dy;
if (delta > 50) {
delta = 50;
}
if (delta < -50) {
delta = -50;
}
if (getChildCount() == 0) {
return dy;
}
System.out.println("Dy:"+dy);
if (getPosition(getChildAt(getChildCount() - 1)) == getItemCount() - 1) {
View child = getChildAt(getChildCount() - 1); getDecoratedBoundsWithMargins(child, childDecoratedBoundsWithMargin);
if (childDecoratedBoundsWithMargin.bottom - delta < recyclerBounds.height()) {
int position = recyclerBounds.height();
int indexToStartFill = getPosition(getChildAt(0));
for (int i = getChildCount() - 1; i >= 0; i--) {
getDecoratedBoundsWithMargins(getChildAt(i), childDecoratedBoundsWithMargin);
position -= childDecoratedBoundsWithMargin.height();
if (position <= 0) {
topOfFirstChild = position;
if (topOfFirstChild <= -childDecoratedBoundsWithMargin.height()) {
topOfFirstChild += childDecoratedBoundsWithMargin.height();
}
indexToStartFill = getPosition(getChildAt(i));
if (indexToStartFill >= getItemCount()) {
indexToStartFill = getItemCount() - 1;
}
break;
}
}
fill(indexToStartFill, recycler);
return 0;
}
}
topOfFirstChild -= delta;
getDecoratedBoundsWithMargins(getChildAt(0), childDecoratedBoundsWithMargin);
int indexToStartFill = getPosition(getChildAt(0));
if (topOfFirstChild > 0) {
topOfFirstChild -= childDecoratedBoundsWithMargin.height();
indexToStartFill--;
if (indexToStartFill == -1) {
topOfFirstChild = 0;
fill(0, recycler);
return 0;
}
} else if (topOfFirstChild <= -childDecoratedBoundsWithMargin.height()) {
topOfFirstChild += childDecoratedBoundsWithMargin.height();
indexToStartFill++;
}
fill(indexToStartFill, recycler);
return dy;
}
}
And main content like this:
recyclerView.setAdapter(new RecyclerViewAdapter(getApplicationContext(), list));
recyclerView.addItemDecoration(new RecyclerItemDecoration());
layoutManager = new CircularLayoutManager(getApplicationContext(), 350, 0);
recyclerView.setLayoutManager(layoutManager);
Full Source Code
I need to remove the top padding at first time loading and when user clicks the list i need to move item to the center.
Related
I'm doing a Canvas to draw a squares on a board in Canvas in Android Studio,
I need to know what path was clicked in my onTouchEvent
but all i can take out from there is an event.x and event.y,
because I have a pretty complicated shape it will be very hard to calculate only based on x and y what path was clicked.
Is there another way I can check the clicked path on the screen ?
Here is my canvas:
public class PianoKeysWidget extends View {
public class ChessSlice extends Path {
public ChessSlice() {
key = "C";
octave = 0;
isKeyBlack = false;
}
public String key;
public int octave;
public boolean isKeyBlack;
}
Paint WhiteKeyPaint, BlackKeyPaint, OuterRimPaint;
Boolean isTouching = false;
float touchY, touchX;
int globalKeyWidth = 20;
PianoKeysInterface mainInterface;
ChessSlice framePath;
ArrayList<ChessSlice> pianoPathsArray = new ArrayList<ChessSlice>();
int width = 340; // default numbers until the screen will change it when it gets the actuall view
int height = 1200; // default numbers until the screen will change it when it gets the actuall view
String TAG = "alignmentWidget";
/**
* construuctor
*
* #param context
*/
public PianoKeysWidget(Context context) {
super(context);
this.postInvalidate();
init();
}
/**
* constructor
*
* #param context
* #param attrs
*/
public PianoKeysWidget(Context context, AttributeSet attrs) {
super(context, attrs);
this.postInvalidate();
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
width = getWidth();
height = getHeight();
init();
}
/**
* constructor
*
* #param context
* #param attrs
* #param defStyleAttr
*/
public PianoKeysWidget(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.postInvalidate();
}
#TargetApi(Build.VERSION_CODES.LOLLIPOP)
private static Bitmap getBitmap(VectorDrawable vectorDrawable) {
Bitmap bitmap = Bitmap.createBitmap(vectorDrawable.getIntrinsicWidth(),
vectorDrawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
vectorDrawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
vectorDrawable.draw(canvas);
return bitmap;
}
private static Bitmap getBitmap(Context context, int drawableId) {
Drawable drawable = ContextCompat.getDrawable(context, drawableId);
if (drawable instanceof BitmapDrawable) {
return BitmapFactory.decodeResource(context.getResources(), drawableId);
} else if (drawable instanceof VectorDrawable) {
return getBitmap((VectorDrawable) drawable);
} else {
throw new IllegalArgumentException("unsupported drawable type");
}
}
//////////////////////////////////
//////////////On Draw//////////////
//////////////////////////////////
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Bitmap bitmap = getBitmap(getContext(), R.drawable.ic_accessibility_black_24dp);
if (pianoPathsArray.size() == 0) { // initlizes the init
init();
}
// draws the first circle
////////////////////////////////////////////
//go through the array and paints the corisponding cells
///////////////////////////////////////////
for (int i = 0; i < pianoPathsArray.size(); i++) {
canvas.drawPath(pianoPathsArray.get(i), WhiteKeyPaint);
if (pianoPathsArray.get(i).isKeyBlack) {
canvas.drawPath(pianoPathsArray.get(i), BlackKeyPaint);
}
canvas.drawPath(pianoPathsArray.get(i), OuterRimPaint);
// if (pianoPathsArray.get(i).color.equals("white")) {
// canvas.drawPath(pianoPathsArray.get(i), WhiteKeyPaint);
// } else {
// canvas.drawPath(pianoPathsArray.get(i), BlackKeyPaint);
// }
//
//
//
// //draw the queens
// if (pianoPathsArray.get(i).isOcupied) {
// canvas.drawBitmap(bitmap, pianoPathsArray.get(i).centerX - 40, pianoPathsArray.get(i).centerY - 45, BlackKeyPaint);
// }
}
//draw the frame
canvas.drawPath(framePath, OuterRimPaint);
}
private void activateErrorAnimationTimer(final ChessSlice chessSlice) {
}
private void init() {
if (pianoPathsArray.size() > 0) { // initlizes the init
return;
}
//gets teh width and height, initlized only after ondraw happend so it wouldn't be 0 0
width = getWidth();
height = getHeight();
//defining paints
///////////////////////////////////////////
WhiteKeyPaint = new Paint();
WhiteKeyPaint.setColor(getResources().getColor(R.color.lightKeyColor));
WhiteKeyPaint.setStyle(Paint.Style.FILL_AND_STROKE);
BlackKeyPaint = new Paint();
BlackKeyPaint.setColor(getResources().getColor(R.color.darkKeyColor));
BlackKeyPaint.setStyle(Paint.Style.FILL_AND_STROKE);
OuterRimPaint = new Paint();
OuterRimPaint.setStrokeWidth(10f);
OuterRimPaint.setColor(getResources().getColor(R.color.colorAccent));
OuterRimPaint.setStyle(Paint.Style.STROKE);
// applyes hardware Acceleration
///////////////////////////////////////////
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
setLayerType(LAYER_TYPE_SOFTWARE, BlackKeyPaint);
}
int overAllKeys = Globals.getInstance().numberOfPianoKeys;
int numberWhiteKeys = getWhiteKeysCount(overAllKeys)-1;
int numberBlackKeys = getBlackKeysCount(overAllKeys);
Log.d ("testings", "whitekeys: "+numberWhiteKeys);
Log.d ("testings", "blackKeys: "+numberBlackKeys);
// gets the main slices paths
///////////////////////////////////////////
for (int i = 0; i <= numberWhiteKeys; i++) {
pianoPathsArray.add(getSlicesPathsWhite(i, numberWhiteKeys));
}
for (int i = 0; i <= numberBlackKeys; i++) {
pianoPathsArray.add(getSlicesPathsBlack(i, numberBlackKeys, numberWhiteKeys));
}
//draw frame
framePath = new ChessSlice();
framePath.moveTo(0, 0);
framePath.lineTo(width, 0);
framePath.lineTo(width, height);
framePath.lineTo(0, height);
framePath.lineTo(0, 0);
}
private int getBlackKeysCount(int overAllKeys) {
int allKeys = overAllKeys;
int blackKeys = 0;
while (allKeys > 12) {
blackKeys = blackKeys + 5;
allKeys = allKeys - 12;
}
if (allKeys == 12) {
blackKeys = blackKeys + 5;
} else if (allKeys == 11) {
blackKeys = blackKeys + 5;
} else if (allKeys == 10) {
blackKeys = blackKeys + 4;
}else if (allKeys == 9) {
blackKeys = blackKeys + 4;
}else if (allKeys == 8) {
blackKeys = blackKeys + 3;
}else if (allKeys == 7) {
blackKeys = blackKeys + 3;
}else if (allKeys == 6) {
blackKeys = blackKeys + 2;
}else if (allKeys == 5) {
blackKeys = blackKeys + 2;
}else if (allKeys == 4) {
blackKeys = blackKeys + 2;
}else if (allKeys == 3) {
blackKeys = blackKeys + 1;
}else if (allKeys == 2) {
blackKeys = blackKeys + 1;
}else if (allKeys == 1) {
blackKeys = blackKeys + 0;
}
return blackKeys;
}
private int getWhiteKeysCount(int overAllKeys) {
int allKeys = overAllKeys;
int whiteKeys = 0;
while (allKeys > 12) {
whiteKeys = whiteKeys + 7;
allKeys = allKeys - 12;
}
if (allKeys == 12) {
whiteKeys = whiteKeys + 8;
} else if (allKeys == 11) {
whiteKeys = whiteKeys + 7;
} else if (allKeys == 10) {
whiteKeys = whiteKeys + 6;
}else if (allKeys == 9) {
whiteKeys = whiteKeys + 6;
}else if (allKeys == 8) {
whiteKeys = whiteKeys + 5;
}else if (allKeys == 7) {
whiteKeys = whiteKeys + 5;
}else if (allKeys == 6) {
whiteKeys = whiteKeys + 4;
}else if (allKeys == 5) {
whiteKeys = whiteKeys + 3;
}else if (allKeys == 4) {
whiteKeys = whiteKeys + 2;
}else if (allKeys == 3) {
whiteKeys = whiteKeys + 2;
}else if (allKeys == 2) {
whiteKeys = whiteKeys + 1;
}else if (allKeys == 1) {
whiteKeys = whiteKeys + 1;
}
return whiteKeys;
}
public ChessSlice getSlicesPathsWhite(int i, int numberWhiteKeys) {
int KeyWidth = width / numberWhiteKeys;
int rowHeight = height;
int startX = 0+(i*KeyWidth);
int startY = 0;
ChessSlice segmentPath = new ChessSlice();
segmentPath.moveTo(startX, startY);
segmentPath.lineTo(startX+KeyWidth, startY);
segmentPath.lineTo(startX+KeyWidth, startY+rowHeight);
segmentPath.lineTo(startX, startY+rowHeight);
segmentPath.lineTo(startX, startY);
segmentPath.key = getCorrectKeyForNumber(i);
segmentPath.octave = getCorrectOctavForNumber(i);
segmentPath.isKeyBlack = false;
return segmentPath;
}
public ChessSlice getSlicesPathsBlack(int i, int numberBlackeys, int numberWhiteKeys) {
int KeyWidth = width / numberWhiteKeys;
int rowHeight = height/2;
int modifierForBlackKeys = getBlackKeyModifier(i);
int startX = (KeyWidth/2)+(i*KeyWidth)+(modifierForBlackKeys*KeyWidth);
int startY = 0;
ChessSlice segmentPath = new ChessSlice();
segmentPath.moveTo(startX, startY);
segmentPath.lineTo(startX+KeyWidth, startY);
segmentPath.lineTo(startX+KeyWidth, startY+rowHeight);
segmentPath.lineTo(startX, startY+rowHeight);
segmentPath.lineTo(startX, startY);
segmentPath.key = getCorrectBlackKeyForNumber(i);
segmentPath.octave = getCorrectBlackOctavForNumber(i);
segmentPath.isKeyBlack = true;
return segmentPath;
}
private int getBlackKeyModifier(int i) {
int modifier = 0;
if (i >= 10) {
modifier = 4;
}else if (i >= 7) {
modifier = 3;
} else if (i >= 5) {
modifier = 2;
} else if (i >= 2) {
modifier = 1;
}
return modifier;
}
private String getCorrectKeyForNumber (int number) {
int functionNum = number;
String key = "C";
while (functionNum > 6) {
functionNum = functionNum - 7;
}
if (functionNum == 0) {
key = "C";
}else if (functionNum == 1) {
key = "D";
}else if (functionNum == 2) {
key = "E";
}else if (functionNum == 3) {
key = "F";
}else if (functionNum == 4) {
key = "G";
}else if (functionNum == 5) {
key = "A";
}else if (functionNum == 6) {
key = "B";
}
return key;
}
private String getCorrectBlackKeyForNumber (int number) {
int functionNum = number;
String key = "C#";
while (functionNum > 4) {
functionNum = functionNum - 5;
}
if (functionNum == 0) {
key = "C#";
}else if (functionNum == 1) {
key = "D#";
}else if (functionNum == 2) {
key = "F#";
}else if (functionNum == 3) {
key = "G#";
}else if (functionNum == 4) {
key = "A#";
}
return key;
}
private int getCorrectOctavForNumber (int number) {
int functionNum = number;
int octave = 0;
while (functionNum > 6) {
octave = octave + 1;
functionNum = functionNum - 7;
}
return octave;
}
private int getCorrectBlackOctavForNumber (int number) {
int functionNum = number;
int octave = 0;
while (functionNum > 4) {
octave = octave + 1;
functionNum = functionNum - 5;
}
return octave;
}
// private TouchModel calculateTouchKey (Float touchX, Float touchY) {
//
// int columWidth = width/COLUMS_COUNT;
// int rowHeight = height/ROWS_COUNT;
//
// int selectectColum = (int) Math.floor(touchX/columWidth)+1;
// int selectectRow = (int) Math.floor(touchY/rowHeight)+1;
//
// TouchModel touchModel = new TouchModel(selectectColum, selectectRow);
//
//
// mainInterface.widgetTouched(selectectColum, selectectRow);
//
// return touchModel;
// }
#Override
public boolean onTouchEvent(MotionEvent event) {
int action = event.getAction();
switch(action){
case MotionEvent.ACTION_MOVE:
case MotionEvent.ACTION_DOWN:
touchX = event.getX();
touchY = event.getY();
isTouching = true;
// Log.d ("Testings", "Touch Event: "+event);
// calculateTouchKey(touchX, touchY);
// Log.d (TAG, "touched: "+touchX+" and: "+touchY);
// Log.d (TAG, "x: "+selectedCells.touchX+" y: "+selectedCells.touchY);
break;
default:
isTouching = false;
}
invalidate();
return true;
}
public void initlizeWidgetVars (PianoKeysInterface chessBoardInterface) {
mainInterface = chessBoardInterface;
mainInterface.setChessArray(pianoPathsArray);
}
public void updateChessArray(ArrayList<ChessSlice> localChessArray) {
pianoPathsArray = localChessArray;
this.postInvalidate();
}
}
fixed it by :
for (int i = 0; i < pianoPathsArray.size(); i++) {
RectF boundrySlice=new RectF();
pianoPathsArray.get(i).computeBounds(boundrySlice, true);
if(boundrySlice.contains(touchX,touchY)){
selectedPath= pianoPathsArray.get(i);// where selectedPath is declared Globally.
}
}
I made a custom view that is has 12 circles along a circular path. I would like to implement an onClick listener for each circle. How would I implement that in my custom view? I have also uploaded my code for the custom view. It just extends a View.
public class WatchView extends View {
private Paint mCircleTickPaint;
private Paint mHourPaint;
private Paint mMinutePaint;
private Paint mSecondPaint;
private boolean mShouldTick;
private int mTickSize;
private int mHourColor;
private int mMinuteColor;
private int mSecondColor;
private int mSeconds = 0;
private int mMinutes = 0;
private int mHours = 0;
private Handler handler = new Handler(Looper.getMainLooper());
public WatchView(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray a = context.getTheme().obtainStyledAttributes(
attrs,
R.styleable.watchface,
0, 0);
try {
mShouldTick = a.getBoolean(R.styleable.watchface_shouldTick, true);
mTickSize = a.getInt(R.styleable.watchface_tickSize, 40);
mHourColor = a.getColor(R.styleable.watchface_hourColor, Color.RED);
mMinuteColor = a.getColor(R.styleable.watchface_minuteColor, Color.GREEN);
mSecondColor = a.getColor(R.styleable.watchface_secondColor, Color.BLUE);
} finally {
a.recycle();
}
init();
}
public void init() {
mCircleTickPaint = new Paint();
mCircleTickPaint.setAntiAlias(true);
mCircleTickPaint.setColor(Color.WHITE);
mHourPaint = new Paint();
mHourPaint.setAntiAlias(true);
mHourPaint.setColor(mHourColor);
mMinutePaint = new Paint();
mMinutePaint.setAntiAlias(true);
mMinutePaint.setColor(mMinuteColor);
mSecondPaint = new Paint();
mSecondPaint.setAntiAlias(true);
mSecondPaint.setColor(mSecondColor);
long now = System.currentTimeMillis();
SimpleDateFormat hh = new SimpleDateFormat("hh");
SimpleDateFormat mm = new SimpleDateFormat("mm");
SimpleDateFormat ss = new SimpleDateFormat("ss");
int hours = Integer.parseInt(hh.format(new Date(now)));
int minutes = Integer.parseInt(mm.format(new Date(now)));
int seconds = Integer.parseInt(ss.format(new Date(now)));
int mappedMinutes = (int) Utils.map(minutes, 1, 60, 1, 12);
int reverseSeconds = (60 - seconds) % 12;
int mappedSeconds = (int) Utils.map(reverseSeconds, 1, 60, 1, 12);
this.mHours = hours;
this.mMinutes = mappedMinutes;
this.mSeconds = mappedSeconds;
if (mShouldTick) {
if (null != handler) {
handler.removeCallbacks(mUpdateRunnable);
}
handler.post(mUpdateRunnable);
}
Log.d("WatchView", "Setting the time at: " + mHours + ":" + mMinutes + ":" + mSeconds);
}
#Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
int centerX = canvas.getWidth() / 2;
int centerY = canvas.getHeight() / 2;
float innerTickRadius = centerX / 2;
for (int tickIndex = 0; tickIndex < 12; tickIndex++) {
float tickRot = (float) (tickIndex * Math.PI * 2 / 12);
float innerX = (float) Math.sin(tickRot) * innerTickRadius;
float innerY = (float) -Math.cos(tickRot) * innerTickRadius;
int reverseSeconds = (60 - mSeconds) % 12;
int mappedSeconds = (int) Utils.map(reverseSeconds, 0, 11, 11, 0);
if (mHours == tickIndex) {
canvas.drawCircle(innerX + centerX, innerY + centerY, mTickSize, mHourPaint);
} else if (mMinutes == tickIndex) {
canvas.drawCircle(innerX + centerX, innerY + centerY, mTickSize, mMinutePaint);
} else if (mappedSeconds == tickIndex) {
canvas.drawCircle(innerX + centerX, innerY + centerY, mTickSize, mSecondPaint);
} else {
canvas.drawCircle(innerX + centerX, innerY + centerY, mTickSize, mCircleTickPaint);
}
}
}
private Runnable mUpdateRunnable = new Runnable() {
#Override public void run() {
mSeconds += 1;
if (mSeconds > 59) {
mSeconds = 0;
mMinutes += 1;
}
if (mMinutes > 59) {
mMinutes = 0;
mHours += 1;
}
if (mHours > 11) {
mHours = 0;
}
invalidate();
handler.postDelayed(mUpdateRunnable, 1000);
}
};
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
final int intrinsicSize = ScreenUtils.getScreenWidth(getContext());
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int width;
int height;
if (widthMode == MeasureSpec.EXACTLY) {
width = widthSize;
} else if (widthMode == MeasureSpec.AT_MOST) {
width = Math.min(intrinsicSize, widthSize);
} else {
width = intrinsicSize;
}
if (heightMode == MeasureSpec.EXACTLY) {
height = heightSize;
} else if (heightMode == MeasureSpec.AT_MOST) {
height = Math.min(intrinsicSize, heightSize);
} else {
height = intrinsicSize;
}
int min = Math.min(width, height);
setMeasuredDimension(min, min);
}
}
Hi i have created custom view "Number Bar" which is working fine. I just want to add labels on each indicator. I tried that but when i draw text it is not visible because view is not getting height for that. Please check image below thanks.
View onDraw Source Code
protected void onDraw(Canvas canvas) {
int indicatorWidthHeight = Utils.dpToPx(getContext(), indicatorSize);
indicatorRadius = indicatorWidthHeight / 2;
int cx = indicatorWidthHeight / 2;
int cy = indicatorWidthHeight / 2;
int totalIndicators = 5;
int totalLines = totalIndicators - 1;
int lineWidth = (getMeasuredWidth() - (indicatorWidthHeight * totalIndicators)) / totalLines;
linePaint.setStrokeWidth(Utils.dpToPx(getContext(), lineHeight));
for (int i = 0; i < circles.length; i++) {
if (selected >= i) {
indicatorPaint.setColor(selectedBackgroundColor);
textPaint.setColor(selectedTextColor);
} else {
indicatorPaint.setColor(backgroundColor);
textPaint.setColor(textColor);
}
if (selected >= i + 1) {
linePaint.setColor(selectedBackgroundColor);
} else {
linePaint.setColor(backgroundColor);
}
int nCx = cx + (lineWidth + indicatorRadius * 2) * i;
circles[i].setRadius(indicatorRadius);
circles[i].setX(nCx);
circles[i].setY(cy);
canvas.drawCircle(nCx, cy, indicatorRadius, indicatorPaint);
String text = "" + (i+1);
textPaint.getTextBounds(text, 0, text.length(), rect);
canvas.drawText(text, nCx, cy+rect.height()/2, textPaint);
// Draw lines one less than circles
if (i != circles.length - 1) {
int startX = nCx + indicatorRadius;
int stopX = nCx + indicatorRadius + lineWidth;
lines[i].setStartX(startX);
lines[i].setStartY(cy);
lines[i].setStopX(stopX);
lines[i].setStopY(cy);
canvas.drawLine(startX, cy, stopX, cy, linePaint);
}
}
}
View Full Source Code
public class NumberBar extends View {
public static final int DEFAULT_TEXT_SIZE = 16;
public static final int DEF_INDICATOR_SIZE = 20;
Rect rect = new Rect();
Circle[] circles = new Circle[5];
Line[] lines = new Line[4];
private int backgroundColor, textColor, selectedBackgroundColor, selectedTextColor, indicatorSize, lineHeight, selected;
private Paint indicatorPaint;
private Paint textPaint;
private Paint linePaint;
private int indicatorRadius;
private boolean enabled = true;
public NumberBar(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.NumberBar, 0, 0);
try {
backgroundColor = typedArray.getInteger(R.styleable.NumberBar_backgroundColor, Color.parseColor("#eeeeee"));
selectedBackgroundColor = typedArray.getInteger(R.styleable.NumberBar_selectedBackgroundColor, Color.parseColor("#0171fe"));
textColor = typedArray.getInteger(R.styleable.NumberBar_textColor, Color.parseColor("#c8c8c8"));
selectedTextColor = typedArray.getInteger(R.styleable.NumberBar_selectedTextColor, Color.parseColor("#ffffff"));
indicatorSize = typedArray.getInteger(R.styleable.NumberBar_indicatorSize, DEF_INDICATOR_SIZE);
lineHeight = typedArray.getInteger(R.styleable.NumberBar_lineHeight, 3);
selected = typedArray.getInteger(R.styleable.NumberBar_selected, 0);
enabled = typedArray.getBoolean(R.styleable.NumberBar_enabled, true);
} finally {
typedArray.recycle();
}
for (int i = 0; i < circles.length; i++) {
circles[i] = new Circle();
}
for (int i = 0; i < lines.length; i++) {
lines[i] = new Line();
}
indicatorPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
indicatorPaint.setStyle(Paint.Style.FILL);
textPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
textPaint.setTextAlign(Paint.Align.CENTER);
textPaint.setTextSize(Utils.spToPx(getContext(), DEFAULT_TEXT_SIZE));
linePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
linePaint.setStyle(Paint.Style.FILL_AND_STROKE);
}
#Override
protected void onDraw(Canvas canvas) {
int indicatorWidthHeight = Utils.dpToPx(getContext(), indicatorSize);
indicatorRadius = indicatorWidthHeight / 2;
int cx = indicatorWidthHeight / 2;
int cy = indicatorWidthHeight / 2;
int totalIndicators = 5;
int totalLines = totalIndicators - 1;
int lineWidth = (getMeasuredWidth() - (indicatorWidthHeight * totalIndicators)) / totalLines;
linePaint.setStrokeWidth(Utils.dpToPx(getContext(), lineHeight));
for (int i = 0; i < circles.length; i++) {
if (selected >= i) {
indicatorPaint.setColor(selectedBackgroundColor);
textPaint.setColor(selectedTextColor);
} else {
indicatorPaint.setColor(backgroundColor);
textPaint.setColor(textColor);
}
if (selected >= i + 1) {
linePaint.setColor(selectedBackgroundColor);
} else {
linePaint.setColor(backgroundColor);
}
int nCx = cx + (lineWidth + indicatorRadius * 2) * i;
circles[i].setRadius(indicatorRadius);
circles[i].setX(nCx);
circles[i].setY(cy);
canvas.drawCircle(nCx, cy, indicatorRadius, indicatorPaint);
String text = "" + (i+1);
textPaint.getTextBounds(text, 0, text.length(), rect);
canvas.drawText(text, nCx, cy+rect.height()/2, textPaint);
// Draw lines one less than circles
if (i != circles.length - 1) {
int startX = nCx + indicatorRadius;
int stopX = nCx + indicatorRadius + lineWidth;
lines[i].setStartX(startX);
lines[i].setStartY(cy);
lines[i].setStopX(stopX);
lines[i].setStopY(cy);
canvas.drawLine(startX, cy, stopX, cy, linePaint);
}
}
}
#Override
public boolean onTouchEvent(MotionEvent event) {
if (!enabled) {
return true;
}
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
handleDownTouch(event.getX(), event.getY());
break;
}
return true;
}
private void handleDownTouch(float eventX, float eventY) {
for (int i = 0; i < circles.length; i++) {
if (isCircleClicked(eventX, eventY, circles[i])) { // Toast.makeText(NumberBar.this.getContext(), "Circle Clicked: " + i, Toast.LENGTH_SHORT).show();
this.selected = i;
invalidate();
return;
}
}
for (int i = 0; i < lines.length; i++) {
if (inLine(lines[i].getStartPoint(), lines[i].getStopPoint(), new Point((int)eventX, (int)eventY))) {
this.selected = i+1;
invalidate();
return; // Toast.makeText(NumberBar.this.getContext(), "Line: " + i, Toast.LENGTH_SHORT).show();
}
}
}
// is BC inline with AC or visa-versa
public boolean inLine(Point A, Point B, Point C) {
int offset = 5;
return C.x >= A.x && C.x <= B.x && (C.y <= (B.y-lineHeight+ offset) || C.y <= (B.y-lineHeight- offset));
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // Don't measure width its most or which user will give
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int height;
//Measure Height
if (heightMode == MeasureSpec.EXACTLY) {
//Must be this size
height = heightSize;
} else if (heightMode == MeasureSpec.AT_MOST) {
//Can't be bigger than...
height = Math.min(indicatorSize, heightSize);
} else {
//Be whatever you want
height = indicatorSize;
}
//MUST CALL THIS
setMeasuredDimension(widthSize, height);
setMeasuredDimension(getMeasuredWidth(), Utils.dpToPx(getContext(), indicatorSize));
}
private boolean isCircleClicked(float ex, float ey, Circle circle) {
return Math.sqrt((circle.getX() - ex) * (circle.getX() - ex) + (circle.getY() - ey) * (circle.getY() - ey)) < circle.getRadius()+4;
}
public int getBackgroundColor() {
return backgroundColor;
}
#Override
public void setBackgroundColor(int backgroundColor) {
this.backgroundColor = backgroundColor;
invalidate();
}
public int getTextColor() {
return textColor;
}
public void setTextColor(int textColor) {
this.textColor = textColor;
invalidate();
}
public int getSelectedBackgroundColor() {
return selectedBackgroundColor;
}
public void setSelectedBackgroundColor(int selectedBackgroundColor) {
this.selectedBackgroundColor = selectedBackgroundColor;
invalidate();
}
public int getSelectedTextColor() {
return selectedTextColor;
}
public void setSelectedTextColor(int selectedTextColor) {
this.selectedTextColor = selectedTextColor;
invalidate();
}
public int getIndicatorSize() {
return indicatorSize;
}
public void setIndicatorSize(int indicatorSize) {
this.indicatorSize = indicatorSize;
invalidate();
requestLayout();
}
public int getLineHeight() {
return lineHeight;
}
public void setLineHeight(int lineHeight) {
this.lineHeight = lineHeight;
invalidate();
requestLayout();
}
public int getSelected() {
return selected;
}
public void setSelected(int selected) {
this.selected = selected;
invalidate();
}
private class Circle {
int x, y;
int radius;
public Circle() {
}
public Circle(int x, int y, int radius) {
this.x = x;
this.y = y;
this.radius = radius;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public int getRadius() {
return radius;
}
public void setRadius(int radius) {
this.radius = radius;
}
}
class Line {
Point startPoint = new Point();
Point stopPoint = new Point();
public int getStartX() {
return startPoint.x;
}
public void setStartX(int startX) {
this.startPoint.x = startX;
}
public int getStartY() {
return startPoint.y;
}
public void setStartY(int startY) {
this.startPoint.y = startY;
}
public int getStopX() {
return stopPoint.x;
}
public void setStopX(int stopX) {
this.stopPoint.x = stopX;
}
public int getStopY() {
return stopPoint.y;
}
public void setStopY(int stopY) {
this.stopPoint.y = stopY;
}
public Point getStartPoint() {
return startPoint;
}
public Point getStopPoint() {
return stopPoint;
}
}
#Override
public boolean isEnabled() {
return enabled;
}
#Override
public void setEnabled(boolean enabled) {
this.enabled = enabled;
} }
Em...the title is not clearly, here is my question: i custom a view to display calendar, my logic is when user swipe horizontal it can switch month of current year, when user swipe vertical it can switch year of current month, like image below:
Here is my all code below and i delete some useless code:
public class MonthView extends View {
private static final Region[][] MONTH_REGIONS = new Region[6][7];
private DPCManager mCManager = DPCManager.getInstance();
private DPTManager mTManager = DPTManager.getInstance();
private TextPaint mTextPaint;
private Paint mPaint;
private Scroller mScroller;
private DecelerateInterpolator decelerateInterpolator = new DecelerateInterpolator();
private AccelerateInterpolator accelerateInterpolator = new AccelerateInterpolator();
private OnDateChangeListener onDateChangeListener;
private ScaleAnimationListener scaleAnimationListener = new ScaleAnimationListener();
private DPMode mode;
private int indexYear, indexMonth;
private int centerYear, centerMonth;
private int leftYear, leftMonth;
private int rightYear, rightMonth;
private int topYear, topMonth;
private int bottomYear, bottomMonth;
private int width, height;
private int lastHeight, nextHeight;
private int baseSize;
private int sizeDecor, sizeDecor2x, sizeDecor3x;
private int lastPointX, lastPointY;
private int lastMoveX, lastMoveY;
private int criticalWidth, criticalHeight;
private float sizeTextGregorian, sizeTextFestival;
private float offsetYFestival1, offsetYFestival2;
private boolean isSlideV;
private Map<String, BGCircle> circlesAppear = new HashMap<>();
private Map<String, BGCircle> circlesDisappear = new HashMap<>();
private List<String> dateSelected = new ArrayList<>();
public interface OnDateChangeListener {
void onMonthChange(int month);
void onYearChange(int year);
}
public MonthView(Context context) {
this(context, null);
}
public MonthView(Context context, AttributeSet attrs) {
super(context, attrs);
mScroller = new Scroller(context);
mTextPaint = new TextPaint();
mTextPaint.setTextAlign(Paint.Align.CENTER);
mPaint = new Paint();
}
void setOnDateChangeListener(OnDateChangeListener onDateChangeListener) {
this.onDateChangeListener = onDateChangeListener;
}
void setMode(DPMode mode) {
this.mode = mode;
}
void setDate(int year, int month) {
centerYear = year;
centerMonth = month;
indexYear = 0;
indexMonth = 0;
computeDate();
requestLayout();
invalidate();
}
private void computeDate() {
rightYear = leftYear = centerYear;
topYear = centerYear - 1;
bottomYear = centerYear + 1;
topMonth = centerMonth;
bottomMonth = centerMonth;
rightMonth = centerMonth + 1;
leftMonth = centerMonth - 1;
if (centerMonth == 12) {
rightYear++;
rightMonth = 1;
}
if (centerMonth == 1) {
leftYear--;
leftMonth = 12;
}
if (null != onDateChangeListener) {
onDateChangeListener.onYearChange(centerYear);
onDateChangeListener.onMonthChange(centerMonth);
}
}
#Override
public void computeScroll() {
if (mScroller.computeScrollOffset()) {
scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
} else {
}
}
boolean isNewEvent = false;
#Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
isNewEvent = true;
lastPointX = (int) event.getX();
lastPointY = (int) event.getY();
break;
case MotionEvent.ACTION_MOVE:
if (isNewEvent) {
if (Math.abs(lastPointX - event.getX()) > 100) {
isSlideV = false;
isNewEvent = false;
} else if (Math.abs(lastPointY - event.getY()) > 50) {
isSlideV = true;
isNewEvent = false;
}
}
if (isSlideV) {
int totalMoveY = (int) (lastPointY - event.getY()) + lastMoveY;
smoothScrollTo(0, totalMoveY);
} else {
int totalMoveX = (int) (lastPointX - event.getX()) + lastMoveX;
smoothScrollTo(totalMoveX, 0);
}
break;
case MotionEvent.ACTION_UP:
if (isSlideV) {
if (Math.abs(lastPointY - event.getY()) > 25) {
if (lastPointY < event.getY()) {
if (Math.abs(lastPointY - event.getY()) >= criticalHeight) {
indexYear--;
centerYear = centerYear - 1;
computeDate();
}
smoothScrollTo(0, height * indexYear);
lastMoveY = height * indexYear;
} else if (lastPointY > event.getY()) {
if (Math.abs(lastPointY - event.getY()) >= criticalHeight) {
indexYear++;
centerYear = centerYear + 1;
computeDate();
}
smoothScrollTo(0, height * indexYear);
lastMoveY = height * indexYear;
}
} else {
}
} else {
if (Math.abs(lastPointX - event.getX()) > 25) {
if (lastPointX > event.getX()) {
if (Math.abs(lastPointX - event.getX()) >= criticalWidth) {
indexMonth++;
centerMonth = (centerMonth + 1) % 13;
if (centerMonth == 0) {
centerMonth = 1;
centerYear++;
}
computeDate();
}
smoothScrollTo(width * indexMonth, 0);
lastMoveX = width * indexMonth;
} else if (lastPointX < event.getX()) {
if (Math.abs(lastPointX - event.getX()) >= criticalWidth) {
indexMonth--;
centerMonth = (centerMonth - 1) % 12;
if (centerMonth == 0) {
centerMonth = 12;
centerYear--;
}
computeDate();
}
smoothScrollTo(width * indexMonth, 0);
lastMoveX = width * indexMonth;
}
} else {
}
}
break;
}
return true;
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int measureWidth = MeasureSpec.getSize(widthMeasureSpec);
setMeasuredDimension(measureWidth, measureWidth * 6 / 7F);
}
#Override
protected void onSizeChanged(int w, int h, int oldW, int oldH) {
width = w;
height = h;
criticalWidth = (int) (1F / 5F * width);
criticalHeight = (int) (1F / 5F * height);
baseSize = w;
int sizeCell = (int) (baseSize / 7F);
sizeDecor = (int) (sizeCell / 3F);
sizeDecor2x = sizeDecor * 2;
sizeDecor3x = sizeDecor * 3;
sizeTextGregorian = baseSize / 20F;
mTextPaint.setTextSize(sizeTextGregorian);
float heightGregorian = mTextPaint.getFontMetrics().bottom - mTextPaint.getFontMetrics().top;
sizeTextFestival = baseSize / 40F;
mTextPaint.setTextSize(sizeTextFestival);
float heightFestival = mTextPaint.getFontMetrics().bottom - mTextPaint.getFontMetrics().top;
offsetYFestival1 = (((Math.abs(mTextPaint.ascent() + mTextPaint.descent())) / 2F) +
heightFestival / 2F + heightGregorian / 2F) / 2F;
offsetYFestival2 = offsetYFestival1 * 2F;
for (int i = 0; i < MONTH_REGIONS.length; i++) {
for (int j = 0; j < MONTH_REGIONS[i].length; j++) {
Region region = new Region();
region.set((j * sizeCell), (i * sizeCell), sizeCell + (j * sizeCell),
sizeCell + (i * sizeCell));
MONTH_REGIONS[i][j] = region;
}
}
}
#Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.LTGRAY);
draw(canvas, width * (indexMonth - 1), height * indexYear, leftYear, leftMonth);
draw(canvas, width * indexMonth, height * indexYear, centerYear, centerMonth);
draw(canvas, width * (indexMonth + 1), height * indexYear, rightYear, rightMonth);
draw(canvas, width * indexMonth, height * (indexYear - 1), topYear, topMonth);
draw(canvas, width * indexMonth, height * (indexYear + 1), bottomYear, bottomMonth);
}
private void draw(Canvas canvas, int x, int y, int year, int month) {
canvas.save();
canvas.translate(x, y);
DPInfo[][] info = mCManager.obtainDPInfo(year, month);
for (int i = 0; i < info.length; i++) {
for (int j = 0; j < info[i].length; j++) {
draw(canvas, MONTH_REGIONS[i][j].getBounds(), info[i][j]);
}
}
canvas.restore();
}
private void draw(Canvas canvas, Rect rect, DPInfo info) {
drawGregorian(canvas, rect, info.strG, info.isWeekend);
}
private void drawGregorian(Canvas canvas, Rect rect, String str, boolean isWeekend) {
mTextPaint.setTextSize(sizeTextGregorian);
if (isWeekend) {
mTextPaint.setColor(mTManager.colorWeekend());
} else {
mTextPaint.setColor(mTManager.colorG());
}
canvas.drawText(str, rect.centerX(), rect.centerY(), mTextPaint);
}
private void smoothScrollTo(int fx, int fy) {
int dx = fx - mScroller.getFinalX();
int dy = fy - mScroller.getFinalY();
smoothScrollBy(dx, dy);
}
private void smoothScrollBy(int dx, int dy) {
mScroller.startScroll(mScroller.getFinalX(), mScroller.getFinalY(), dx, dy, 500);
invalidate();
}
}
If i swipe vertical to switch year, for example 2015/7-->2016/7-->2017/7, it's run correctly, but now if i swipe horizontal to switch month, for example 2017/7-->2017/6, everything will not display:
That's mean only horizontal and vertical on current month can touch and display correctly, for example the default display month is 2015/7, when i swipe to 2016/7 or 2017/7, i can't get the correct display when i swipe to 2017/6 or 2017/8, only swipe back to 2015/7 to swipe correctly can get the correct display of 2015/6 and 2015/8.
This problem troubled me many days, the coordinates and data of months all correct, i don't know why it happen, hope and thanks for your answer.
This question already has answers here:
Android Tile Bitmap
(8 answers)
Closed 8 years ago.
To draw landscapes, backgrounds with patterns etc, we used TiledLayer in J2ME. Is there an android counterpart for that. Does android provide an option to set such tiled patterns in the layout XML?
You can use this class as a equivalent "TiledLayer class of jme":
package net.obviam.walking;
import java.util.ArrayList;
import com.kilobolt.framework.Graphics;
import com.kilobolt.framework.Image;
import com.kilobolt.framework.implementation.AndroidImage;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.Rect;
public class TiledLayer {
public static final int DIR_LEFT = 0;
public static final int DIR_RIGHT = 1;
public static final int DIR_UP = 2;
public static final int DIR_DOWN = 3;
private int cellWidth;
private int cellHeight;
private int yPosition = 0, xPosition = 0;
private int[][] grid;
private Image image;
private Bitmap tileArray[];
private int[] tileXPositions;
private int[] tileYPositions;
private ArrayList animatedTiles;
private int numberOfTiles;
private int numberOfColumns;
private int numberOfRows;
private int gridColumns;
private int gridRows, width, height;
int tileCounter;
public TiledLayer(Image image, int columns, int rows, int tileWidth,
int tileHeight, int width, int height) {
this.grid = new int[columns][rows];
this.gridColumns = columns;
this.gridRows = rows;
this.width = columns * tileWidth;
this.height = rows * tileHeight;
this.animatedTiles = new ArrayList();
this.cellWidth = tileWidth;
this.cellHeight = tileHeight;
int r = image.getHeight() / tileHeight;
int c = image.getWidth() / tileWidth;
tileArray = new Bitmap[(r * c) + 1];
setStaticTileSet(image, tileWidth, tileHeight);
}
public TiledLayer(Bitmap image, int columns, int rows, int tileWidth,
int tileHeight, int width, int height) {
this.grid = new int[columns][rows];
this.gridColumns = columns;
this.gridRows = rows;
this.width = columns * tileWidth;
this.height = rows * tileHeight;
this.animatedTiles = new ArrayList();
this.cellWidth = tileWidth;
this.cellHeight = tileHeight;
int r = image.getHeight() / tileHeight;
int c = image.getWidth() / tileWidth;
tileArray = new Bitmap[(r * c) + 1];
setStaticTileSet(image, tileWidth, tileHeight);
}
public void setStaticTileSet(Image image, int tileWidth, int tileHeight) {
tileArray[0] = Bitmap.createBitmap(tileWidth, tileHeight,
Config.ARGB_4444);
int rows = image.getHeight() / tileHeight;
int columns = image.getWidth() / tileWidth;
numberOfTiles = rows * columns;
for (int i = 0; i < rows; i++) {
yPosition = i * tileHeight;
for (int j = 0; j < columns; j++) {
xPosition = j * tileWidth;
tileCounter++;
tileArray[tileCounter] = Bitmap.createBitmap(
((AndroidImage) image).bitmap, xPosition, yPosition,
tileWidth, tileHeight);
}
}
if (gridColumns * gridRows < this.numberOfTiles) {
// clear the grid, when there are not as many tiles as in the
// previous set:
for (int i = 0; i < this.grid.length; i++) {
for (int j = 0; j < this.grid[i].length; j++) {
this.grid[i][j] = 0;
}
}
}
}
public void setStaticTileSet(Bitmap image, int tileWidth, int tileHeight) {
tileArray[0] = Bitmap.createBitmap(tileWidth, tileHeight,
Config.ARGB_4444);
int rows = image.getHeight() / tileHeight;
int columns = image.getWidth() / tileWidth;
numberOfTiles = rows * columns;
for (int i = 0; i < rows; i++) {
yPosition = i * tileHeight;
for (int j = 0; j < columns; j++) {
xPosition = j * tileWidth;
tileCounter++;
tileArray[tileCounter] = Bitmap.createBitmap(image, xPosition,
yPosition, tileWidth, tileHeight);
}
}
if (gridColumns * gridRows < this.numberOfTiles) {
// clear the grid, when there are not as many tiles as in the
// previous set:
for (int i = 0; i < this.grid.length; i++) {
for (int j = 0; j < this.grid[i].length; j++) {
this.grid[i][j] = 0;
}
}
}
}
public int createAnimatedTile(int staticTileIndex) {
if (staticTileIndex >= this.numberOfTiles) {
throw new IllegalArgumentException("invalid static tile index: "
+ staticTileIndex + " (there are only ["
+ this.numberOfTiles + "] tiles available.");
}
this.animatedTiles.add(new Integer(staticTileIndex));
return -1 * (this.animatedTiles.size() - 1);
}
public void setAnimatedTile(int animatedTileIndex, int staticTileIndex) {
if (staticTileIndex >= this.numberOfTiles) {
}
int animatedIndex = (-1 * animatedTileIndex) - 1;
this.animatedTiles.set(animatedIndex, new Integer(staticTileIndex));
}
public int getAnimatedTile(int animatedTileIndex) {
int animatedIndex = (-1 * animatedTileIndex) - 1;
Integer animatedTile = (Integer) this.animatedTiles.get(animatedIndex);
return animatedTile.intValue();
}
public void setCell(int col, int row, int tileIndex) {
if (tileIndex >= this.numberOfTiles) {
throw new IllegalArgumentException("invalid static tile index: "
+ tileIndex + " (there are only [" + this.numberOfTiles
+ "] tiles available.");
}
this.grid[col][row] = tileIndex;
}
public int getCell(int col, int row) {
return this.grid[col][row];
}
public boolean checkTileCollision(Sprite sp, int dir, int speed) {
int curRow, curCollumn;
int leftTile = 0, rightTile = 0, upTile = 0, downTile = 0;
curRow = sp.getY() / cellHeight;
curCollumn = sp.getX() / cellWidth;
leftTile = grid[curCollumn - 1][curRow];
rightTile = grid[curCollumn + 1][curRow];
upTile = grid[curCollumn][curRow - 1];
downTile = grid[curCollumn][curRow + 1];
if (dir == DIR_RIGHT
&& (sp.getX() + sp.getWidth() + speed) <= (curCollumn + 1)
* cellWidth)
return false;
else if (dir == DIR_RIGHT
&& ((sp.getX() + sp.getWidth() + speed)) > (curCollumn + 1)
* cellWidth && rightTile != 1)
return true;
else if (dir == DIR_LEFT
&& (sp.getX() - speed) >= (curCollumn) * cellWidth)
return false;
else if (dir == DIR_LEFT
&& (sp.getX() - speed) < (curCollumn) * cellWidth
&& leftTile != 1)
return true;
else if (dir == DIR_UP && (sp.getY() - speed) >= (curRow) * cellHeight)
return false;
else if (dir == DIR_UP && (sp.getY() - speed) < (curRow) * cellHeight
&& upTile != 1)
return true;
else if (dir == DIR_DOWN
&& (sp.getY() + sp.getHeight() + speed) <= (curRow + 1)
* cellHeight)
return false;
else if (dir == DIR_DOWN
&& (sp.getY() + sp.getHeight() + speed) > (curRow + 1)
* cellHeight && downTile != 1)
return true;
else
return false;
}
public void fillCells(int col, int row, int numCols, int numRows,
int tileIndex) {
if (tileIndex >= this.numberOfTiles) {
throw new IllegalArgumentException("invalid static tile index: "
+ tileIndex + " (there are only [" + this.numberOfTiles
+ "] tiles available.");
}
int endCols = col + numCols;
int endRows = row + numRows;
for (int i = col; i < endCols; i++) {
for (int j = row; j < endRows; j++) {
this.grid[i][j] = tileIndex;
}
}
}
public final int getCellWidth() {
return this.cellWidth;
}
public final int getCellHeight() {
return this.cellHeight;
}
public final int getColumns() {
return this.gridColumns;
}
public final int getRows() {
return this.gridRows;
}
public final void paint(Graphics g) {
for (int i = 0; i < this.gridRows; i++) {
for (int j = 0; j < this.gridColumns; j++) {
Bitmap bmp = tileArray[grid[j][i]];
g.drawImage(bmp, j * cellWidth, i * cellHeight);
}
}
}
public final void paint(Canvas c) {
for (int i = 0; i < this.gridRows; i++) {
for (int j = 0; j < this.gridColumns; j++) {
Bitmap bmp = tileArray[grid[j][i]];
c.drawBitmap(bmp, j * cellWidth, i * cellHeight, null);
// g.drawImage(bmp, j*cellWidth,i*cellHeight);
}
}
}
}