- 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 childrenpublic 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_UP
PenStroke
ACTION_UP
PASS
: Show next strokeFAIL
: startAnimation()
onMeasure
: Customize sizeonDraw
: Customize appearanceonLayout
: Position the childrendispatchDraw
: Adjustment before/after drawing the childrenBookshelfGridView
onDispatchDraw
CharacterArea
onMeasure
onDraw
onTouchEvent