Sunday, July 13, 2014

Android Custom View - A Look at LabelView class


The LabelView class demonstrates a Custom LabeView which draws the given text. This example doesn't load anything from a layout XML file, instead it paints the text. This is done by overriding the onDraw method like below 

@override 
protected void onDraw(Canvas canvas)
super.onDraw(canvas);
canvas.drawText(mText, getPaddingLeft(), getPaddingTop() - mAscent, mTextPaint);
}

Other  important functions is onMeasure, This function is important to let the parent know that how much amount of space this component require 

The implementation is like below 

@override 
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
setMeasuredDimension( measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec)); 

the widthMeasureSpec and heightMeasureSpec are int values which is a package of multiple measure spec attributes for e.g. specMode, specSize, which can be extracted using the MeasureSpec class 

A Typical implementation is like below 

private int measureWidth (int measureSpec)
{
int result = 0; 
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
if(specMode == MeasureSpec.EXACTLY)
{
//We were told how big it would be 
result  = specSize;
}
else 
{
result = (int) mTextPaint.measureText(mText) + getPaddingLeft() + getPaddingRight(); 
if(specMode == MeasureSpec.AT_MOST)
{
result  = Math.min(result, specSize);
}
}
return result; 
}

I decided to take this and layout in the Custom Layout engine i created. And below are few observations from this. 
As usual, came across the issue where style able is not present in the workspace i have. A workaround like this did solve the problem 

onMeasure, the individual views have been passed with MeasureSpec value as UNSPECIFIED for specMode.
Based on the passed in value, the LabelView class computed the measurable width and height. But since the layout was called with the 
absolute value, the view was still looking according to how the CardLayout wanted. 

However, tried to use the modified measured values by the LabelView which was returned like values 57 and 17 which was not sufficient to display the view
But it did work with a 20px more from the measured value. 

References: 

No comments:

Post a Comment