- TextView
- EditText
- Button
- Spinner
- DatePicker
| Simple View | Container | Compound Control |
|---|---|---|
|
↳ TextView ↳ EditText ↳ Button ↳ ImageView ↳ ImageButton |
↳ AdapterView ↳ ListView ↳ Gallery ↳ GridView ↳ LinearLayout ↳ RelativeLayout ↳ FrameLayout ↳ TableLayout |
↳ DatePicker ↳ TwoLineListItem |
Modularize repeated code
<TextView android:id="@+id/date" android:layout_width="match_parent" android:layout_height="wrap_content" />
TextView dateView = (TextView) findViewById(R.id.date);
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
String today = dateFormat.format(Calendar.getInstance().getTime());
dateView.setText(today);
package com.sqisland.android.dateview;
public class DateView extends TextView {
public DateView(Context context) {
super(context);
}
public DateView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public DateView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
}
public class DateView extends TextView {
public DateView(Context context) {
super(context);
setDate();
}
public DateView(Context context, AttributeSet attrs) {
super(context, attrs);
setDate();
}
public DateView(
Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setDate();
}
}
private void setDate() {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
String today = dateFormat.format(Calendar.getInstance().getTime());
setText(today); // self = DateView = subclass of TextView
}
public class DateActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
DateView dateView = new DateView(this);
setContentView(dateView);
}
}
public class DateActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}
<com.sqisland.android.dateview.DateView android:layout_width="match_parent" android:layout_height="wrap_content" />
requestLayout up to ViewRootmeasure all childrenlayout all childrenCustomize size and appearance of the View
onMeasure - how big?onDraw - what to show?void onMeasure(int widthMeasureSpec, int heightMeasureSpec);
setMeasuredDimension to store resultsUNSPECIFIED - anything goes!
AT_MOST - as large as the specified size
EXACTLY - as given by parent
public void onMeasure(int widthSpec, int heightSpec) {
super.onMeasure(widthSpec, heightSpec);
int size = Math.min(getMeasuredWidth(), getMeasuredHeight());
setMeasuredDimension(size, size);
}
void onDraw(Canvas canvas);
Container for positioning child views
onMeasure - how big are the children?onLayout - where are the children?dispatchDraw - adjustments before or after drawing the children
public class BookshelfGridView extends GridView {
// Constructors etc
protected void dispatchDraw(Canvas canvas) {
for (int y = top; y < height; y += mWoodPanelHeight) {
for (int x = mLeftWidth; x < width; x += mWoodPanelWidth) {
canvas.drawBitmap(mWoodPanelImage, x, y, null);
}
}
for (int y = top; y < height; y += mShelfHeight) {
// Draw left edge
// Draw shelf
// Draw right edge
}
super.dispatchDraw(canvas);
}
}
SurfaceView
public void onDraw(Canvas canvas) {
canvas.drawColor(mBackgroundColor);
drawGuidelines(canvas);
drawCharacter(canvas);
drawAnimation(canvas);
drawPenStrokes(canvas);
drawStrokeNumbers(canvas);
}
// CharacaterActivity.java
mCharacterArea = (CharacterArea) findViewById(R.id.sketch_pad);
mStrokeNumbersCheckBox = (CheckBox) findViewById(R.id.stroke_numbers_checkbox);
mStrokeNumbersCheckBox.setOnCheckedChangeListener(new OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton view, boolean isChecked) {
mCharacterArea.toggleStrokeNumbers();
}
});
// CharacterArea.java
public void toggleStrokeNumbers() {
mShowStrokeNumbers = !mShowStrokeNumbers;
}
public void drawStrokeNumbers(Canvas canvas) {
if (!mShowStrokeNumbers) {
return;
}
// Proceed to draw stroke numbers
}
public void registerListener(Listener listener) {
mListeners.add(listener);
}
public void unregisterListener(Listener listener) {
mListeners.remove(listener);
}
private void notifyPenStrokeComplete(PenStroke penStroke) {
for (Listener listener : mListeners) {
listener.onPenStrokeComplete(penStroke);
}
}
public interface Listener {
public void onPenStrokeComplete(PenStroke penStroke);
}
public void onPenStrokeComplete(PenStroke penStroke) {
boolean pass = (penStroke.grade == PenStroke.Grade.PASS);
if (mMonkeyView != null) {
mMonkeyView.setImageResource(pass ?
R.drawable.happy_monkey : R.drawable.sad_monkey);
}
// Just a bit more, wrong stroke etc
String feedback = getFeedback(penStroke.grade);
mFeedbackView.setText(feedback);
}
ACTION_DOWN
stopAnimation()new PenStroke()ACTION_DOWN / ACTION_MOVE / ACTION_UPPenStroke
ACTION_UP
PASS: Show next strokeFAIL: startAnimation()
onMeasure: Customize sizeonDraw: Customize appearanceonLayout: Position the childrendispatchDraw: Adjustment before/after drawing the childrenBookshelfGridView
onDispatchDrawCharacterArea
onMeasureonDrawonTouchEvent