// ******************************************************************* //
// ** Chapter 4 Code Listings ** //
// ** Professional Android 2 Application Development ** //
// ** Reto Meier ** //
// ** (c)2010 Wrox ** //
// ******************************************************************* //
// ** Creating Layouts ******************************************** //
// *******************************************************************
// ** Listing 4-1: Inflating an Activity layout
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
TextView myTextView = (TextView)findViewById(R.id.myTextView);
}
// *******************************************************************
// ** Listing 4-2: Creating a UI layout in code
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
TextView myTextView = new TextView(this);
setContentView(myTextView);
myTextView.setText("Hello, Android");
}
// *******************************************************************
// ** Listing 4-3: Simple Linear Layout in XML
// *******************************************************************
// ** Listing 4-4: Simple LinearLayout in code
LinearLayout ll = new LinearLayout(this);
ll.setOrientation(LinearLayout.VERTICAL);
TextView myTextView = new TextView(this);
EditText myEditText = new EditText(this);
myTextView.setText("Enter Text Below");
myEditText.setText("Text Goes Here!");
int lHeight = LinearLayout.LayoutParams.FILL_PARENT;
int lWidth = LinearLayout.LayoutParams.WRAP_CONTENT;
ll.addView(myTextView, new LinearLayout.LayoutParams(lHeight, lWidth));
ll.addView(myEditText, new LinearLayout.LayoutParams(lHeight, lWidth));
setContentView(ll);
// ** Extending Views ********************************************* //
// *******************************************************************
// ** Listing 4-5: Extending TextView (Extended)
public class MyTextView extends TextView {
public MyTextView (Context context, AttributeSet ats, int defStyle) {
super(context, ats, defStyle);
}
public MyTextView (Context context) {
super(context);
}
public MyTextView (Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public void onDraw(Canvas canvas) {
[ ... Draw things on the canvas under the text ... ]
// Render the text as usual using the TextView base class.
super.onDraw(canvas);
[ ... Draw things on the canvas over the text ... ]
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent keyEvent) {
[ ... Perform some special processing ... ]
[ ... based on a particular key press ... ]
// Use the existing functionality implemented by
// the base class to respond to a key press event.
return super.onKeyDown(keyCode, keyEvent);
}
}
// *******************************************************************
// ** Listing 4-6: Creating a compound control
public class MyCompoundView extends LinearLayout {
public MyCompoundView(Context context) {
super(context);
}
public MyCompoundView(Context context, AttributeSet attrs) {
super(context, attrs);
}
}
// *******************************************************************
// ** Listing 4-7: A compound View layout resource
// *******************************************************************
// ** Listing 4-8: Constructing a compound View
public class ClearableEditText extends LinearLayout {
EditText editText;
Button clearButton;
public ClearableEditText(Context context) {
super(context);
// Inflate the view from the layout resource.
String infService = Context.LAYOUT_INFLATER_SERVICE;
LayoutInflater li;
li = (LayoutInflater)getContext().getSystemService(infService);
li.inflate(R.layout.clearable_edit_text, this, true);
// Get references to the child controls.
editText = (EditText)findViewById(R.id.editText);
clearButton = (Button)findViewById(R.id.clearButton);
// Hook up the functionality
hookupButton();
}
}
// *******************************************************************
// ** Listing 4-9: Creating a compound View layout in code
public ClearableEditText(Context context) {
super(context);
// Set orientation of layout to vertical
setOrientation(LinearLayout.VERTICAL);
// Create the child controls.
editText = new EditText(getContext());
clearButton = new Button(getContext());
clearButton.setText("Clear");
// Lay them out in the compound control.
int lHeight = LayoutParams.WRAP_CONTENT;
int lWidth = LayoutParams.FILL_PARENT;
addView(editText, new LinearLayout.LayoutParams(lWidth, lHeight));
addView(clearButton, new LinearLayout.LayoutParams(lWidth, lHeight));
// Hook up the functionality
hookupButton();
}
private void hookupButton() {
clearButton.setOnClickListener(new Button.OnClickListener() {
public void onClick(View v) {
editText.setText("");
}
});
}
// ** Creating New Views ****************************************** //
// *******************************************************************
// ** Listing 4-10: Creating a new View class
public class MyView extends View {
// Constructor required for in-code creation
public MyView(Context context) {
super(context);
}
// Constructor required for inflation from resource file
public MyView (Context context, AttributeSet ats, int defaultStyle) {
super(context, ats, defaultStyle );
}
//Constructor required for inflation from resource file
public MyView (Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onMeasure(int wMeasureSpec, int hMeasureSpec) {
int measuredHeight = measureHeight(hMeasureSpec);
int measuredWidth = measureWidth(wMeasureSpec);
// MUST make this call to setMeasuredDimension
// or you will cause a runtime exception when
// the control is laid out.
setMeasuredDimension(measuredHeight, measuredWidth);
}
private int measureHeight(int measureSpec) {
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
[ ... Calculate the view height ... ]
return specSize;
}
private int measureWidth(int measureSpec) {
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
[ ... Calculate the view width ... ]
return specSize;
}
@Override
protected void onDraw(Canvas canvas) {
[ ... Draw your visual interface ... ]
}
}
// *******************************************************************
// ** Listing 4-11: Drawing a custom View
@Override
protected void onDraw(Canvas canvas) {
// Get the size of the control based on the last call to onMeasure.
int height = getMeasuredHeight();
int width = getMeasuredWidth();
// Find the center
int px = width/2;
int py = height/2;
// Create the new paint brushes.
// NOTE: For efficiency this should be done in
// the views’s constructor
Paint mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mTextPaint.setColor(Color.WHITE);
// Define the string.
String displayText = "Hello World!";
// Measure the width of the text string.
float textWidth = mTextPaint.measureText(displayText);
// Draw the text string in the center of the control.
canvas.drawText(displayText, px-textWidth/2, py, mTextPaint);
}
// *******************************************************************
// ** Listing 4-12: Determining View dimensions
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int measuredHeight = measureHeight(heightMeasureSpec);
int measuredWidth = measureWidth(widthMeasureSpec);
setMeasuredDimension(measuredHeight, measuredWidth);
}
private int measureHeight(int measureSpec) {
// Return measured widget height.
}
private int measureWidth(int measureSpec) {
// Return measured widget width.
}
// *******************************************************************
// ** Listing 4-13: A typical View measurement implementation
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int measuredHeight = measureHeight(heightMeasureSpec);
int measuredWidth = measureWidth(widthMeasureSpec);
setMeasuredDimension(measuredHeight, measuredWidth);
}
private int measureHeight(int measureSpec) {
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
// Default size if no limits are specified.
int result = 500;
if (specMode == MeasureSpec.AT_MOST) {
// Calculate the ideal size of your
// control within this maximum size.
// If your control fills the available
// space return the outer bound.
result = specSize;
} else if (specMode == MeasureSpec.EXACTLY) {
// If your control can fit within these bounds return that value.
result = specSize;
}
return result;
}
private int measureWidth(int measureSpec) {
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
// Default size if no limits are specified.
int result = 500;
if (specMode == MeasureSpec.AT_MOST) {
// Calculate the ideal size of your control
// within this maximum size.
// If your control fills the available space
// return the outer bound.
result = specSize;
} else if (specMode == MeasureSpec.EXACTLY) {
// If your control can fit within these bounds return that value.
result = specSize;
}
return result;
}
// *******************************************************************
// ** Listing 4-14: Input event handling for Views
@Override
public boolean onKeyDown(int keyCode, KeyEvent keyEvent) {
// Return true if the event was handled.
return true;
}
@Override
public boolean onKeyUp(int keyCode, KeyEvent keyEvent) {
// Return true if the event was handled.
return true;
}
@Override
public boolean onTrackballEvent(MotionEvent event ) {
// Get the type of action this event represents
int actionPerformed = event.getAction();
// Return true if the event was handled.
return true;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
// Get the type of action this event represents
int actionPerformed = event.getAction();
// Return true if the event was handled.
return true;
}
// *******************************************************************
// ** Listing 4-15: Using a custom View
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
CompassView cv = new CompassView(this);
setContentView(cv);
cv.setBearing(45);
}
// ** Drawable Resources ****************************************** //
// *******************************************************************
// ** Listing 4-16: A solid red Drawable resource
// *******************************************************************
// ** Listing 4-17: A red Drawable rectangle with green border and rounded edges
// *******************************************************************
// ** Listing 4-18: Linear, Radial, and Sweep Gradient definitions
// *******************************************************************
// ** Listing 4-19: Resource files for a Rotate Drawable and Scale Drawable
// *******************************************************************
// ** Listing 4-20: Applying rotation and scale Drawable transformations in code
ImageView rotatingImage = (ImageView)findViewById(R.id.RotatingImageView);
ImageView scalingImage = (ImageView)findViewById(R.id.ScalingImageView);
// Rotate the image 50% of the way to it's final orientation.
rotatingImage.setImageLevel(5000);
// Scale the image to 50% of it’s final size.
scalingImage.setImageLevel(5000);
// *******************************************************************
// ** Listing 4-21: A Layer Drawable resource XML definition
// *******************************************************************
// ** Listing 4-22: State List Drawable
// *******************************************************************
// ** Listing 4-23: Level List Drawable resource
// *******************************************************************
// ** Listing 4-24: Sample screen-based resource directory qualifiers
res/layout-small-long/ // Layouts for small, long screens.
res/layout-large/ // Layouts for large screens.
res/drawable-hdpi/ // Drawabless for high density screens.
// *******************************************************************
// ** Listing 4-25: Manifest element supporting normal and large screen sizes
// ** Menus ******************************************************* //
// *******************************************************************
// ** Listing 4-26: Adding a Menu Item
static final private int MENU_ITEM = Menu.FIRST;
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
// Group ID
int groupId = 0;
// Unique menu item identifier. Used for event handling.
int menuItemId = MENU_ITEM;
// The order position of the item
int menuItemOrder = Menu.NONE;
// Text to be displayed for this menu item.
int menuItemText = R.string.menu_item;
// Create the menu item and keep a reference to it.
MenuItem menuItem = menu.add(groupId, menuItemId,
menuItemOrder, menuItemText);
return true;
}
// *******************************************************************
// ** Listing 4-27: Dynamic menu modification
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
MenuItem menuItem = menu.findItem(MENU_ITEM);
[ ... modify menu items ... ]
return true;
}
// *******************************************************************
// ** Listing 4-28: Handling Menu Item selections
public boolean onOptionsItemSelected(MenuItem item) {
super.onOptionsItemSelected(item);
// Find which menu item has been selected
switch (item.getItemId()) {
// Check for each known menu item
case (MENU_ITEM):
[ ... Perform menu handler actions ... ]
return true;
}
// Return false if you have not handled the menu item.
return false;
}
// *******************************************************************
// ** Listing 4-29: Assigning a Context Menu to a View
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
EditText view = new EditText(this);
setContentView(view);
registerForContextMenu(view);
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
menu.setHeaderTitle("Context Menu");
menu.add(0, menu.FIRST, Menu.NONE,
"Item 1").setIcon(R.drawable.menu_item);
menu.add(0, menu.FIRST+1, Menu.NONE, "Item 2").setCheckable(true);
menu.add(0, menu.FIRST+2, Menu.NONE, "Item 3").setShortcut('3', '3');
SubMenu sub = menu.addSubMenu("Submenu");
sub.add("Submenu Item");
}
@Override
public boolean onContextItemSelected(MenuItem item) {
super.onContextItemSelected(item);
[ ... Handle menu item selection ... ]
return false;
}
// *******************************************************************
// ** Listing 4-30: Defining a menu in XML
// *******************************************************************
// ** Listing 4-31: Inflating an XML menu resource
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.my_menu, menu);
menu.setHeaderTitle("Context Menu");
}
// ******************************************************************* //