Tagged: android

Android: Custom View's onLayout and onMeasure methods

If you want to layout a custom view’s children yourself, as opposed to making the custom view extend LinearLayout or similar, you need to implement the onLayout and onMeasure methods of the ViewGroup class.


Let’s first look at onLayout(). This tells your custom view’s children where they should lay themselves out:

protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
  childCount = getChildCount();
  for(int i=0; i<childCound;i++) {
    View v = getChildAt(i);

This method is called by the ViewGroup, passing in the parent’s dimensions.

The ‘left’ and ‘top’ is the left and right from the custom view’s parent, this is normally zero unless you have set margins on your custom view.

Then we get the number of children and are about to process each in the loop.

The method we must call on each of the views’ in the loop is

v.layout(left, top, right, bottom). 

If ‘left’ or ‘top’ are 0 this means right at the left and top edge of the parent.

If you have defined some padding on your custom view, you must include these in your layout call, otherwise the padding will be in front of the view.


Before you can call methods such like getMeasuredWidth() on your ViewGroup’s children, however, you must tell them how to measure themselves in onMeasure:

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

The two parameters passed in are int values which represent the mode and side of the width and height.

Let’s say you passed in match_parent to the layout_width parameter in your View’s XML, and the width of your view’s parent is 400, then the following would be true:

int mode = MeasureSpec.getMode(widthMeasureSpec) // mode == View.MesaureSpec.EXACTLY
int size = MeasureSpec.getSize(widthMeasureSpec) // size == 400

In this method you must call either its super method or setMeasuredDimension() with the width specifications and height specification either passed into the method or created with MeasureSpec.makeMeasureSpec(size, mode).

You must also call the measure(widthSpec, heightSpec) on the child views too.

  for(int i=0; i<childCound;i++) {
    View v = getChildAt(i);
    v.measure(widthSpec, heightSpec);

If you wanted to give each view the same measurements as its parents (BUT WHY???) you could give it its parent’s measure specs, or create your own via the makeMeasureSpec above, perhaps by using a division of the parent’s getMeasuredWidth(), taking into account any padding using the getPadding*() methods.

android android-custom-view

Android: Detect a fling

If you want to detect a fling on a view, create a GestureDetector that for an argument takes a SimpleOnGestureListener.

final static GestureDetector.SimpleOnGestureListener simpleDetector = new GestureDetector.SimpleOnGestureListener() {
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
        super.onFling(e1, e2, velocityX, velocityY);
        Log.d("HI", "on fling");
        return true; // If you've consumed it
final static GestureDetector detector = new GestureDetector(simpleDetector);

It’s within these methods you calculate what kind of fling it is.

Within your onTouch event listener return with return detector.onTouchEvent(motionEvent);.

And make sure the view you’re listening on is clickable. And that should be it.

android android-fling

Android: Simple view dragging tutorial

Let’s say you’ve added a touch listener to a view. And in that listener you have a motionEvent.

Use this code to start dragging that view in onTouch.

if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
    ClipData data = ClipData.newPlainText("", "");
    View.DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(
    view.startDrag(data, shadowBuilder, view, 0);
    return true;
} else {
    return false;

The clipdata is the data passed to the drop area. And the shadowBuilder is what the view looks like when dragged.

There’s no drop area, but you can look that up.

android android-drag-drop

Android and Facebook's Litho: Getting started

Litho allows you to declare your view in code with speed optimisations for lists.

It uses flexbox layout logic, via the Facebook Yoga library, allowing you to use your existing web knowledge. This applies to iOS too since Yoga also exists for iOS.

It supports one-directional data binding, thereby allowing you dive into the flux architecture a little.

Let’s do the basic getting started first. Let’s bung all the depenedencies into your app’s build.gradle.

compile 'com.facebook.litho:litho-core:0.2.0'
compile 'com.facebook.litho:litho-widget:0.2.0'
provided 'com.facebook.litho:litho-annotations:0.2.0'
annotationProcessor 'com.facebook.litho:litho-processor:0.2.0'
compile 'com.facebook.soloader:soloader:0.2.0'
debugCompile 'com.facebook.litho:litho-stetho:0.2.0'
compile 'com.facebook.litho:litho-fresco:0.2.0'

Create an Application class in your app and ensure your manifest points to it. In the onCreate method add this:

SoLoader.init(this, false);

In your Activity’s onCreate change the view layout code to:

 ComponentContext c = new ComponentContext(this);
 setContentView(LithoView.create(c, MyComponent.create(c).build()));

We’re creating a Litho context, and then creating a Litho view with that context, and a component too. Where does that MyComponent come from?

public class MyComponentSpec {
    static ComponentLayout onCreateLayout(ComponentContext c) {
        return Column.create(c)
                .paddingDip(YogaEdge.ALL, 16)


The annoation @LayoutSpec takes the class name minus Spec, thereby creating the MyComponent class via facebook’s annoation processor.

We create a Column using flexbox terminology, with two Text children, which are not TextViews incidentally.

Later tutorials will focus on using Android Views within Litho and events I should think.

android litho

Android: Style Toolbar/ActionBar and centre text

In recent support library updates, we have the Toolbar to use instead of the standard ActionBar to style via various properties in your style xml files.

You add this manually to your layout XML file.

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

If you want to centre the title text, for example, you now just add a normal TextView and centre align it.

          tools:text="Some title"

Obviously this is a lot to put at the top of every activity, you can instead place it in a separate layout file and use an include directive:

    <include android:id="@+id/toolbar_layout"
        layout="@layout/toolbar_layout" />

In order to give this the title of your activity, you add this code in your onStart() method, or anywhere after the layout has been inflated:

TextView toolbarText = (TextView) findViewById(R.id.toolbar_text);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
if(toolbarText!=null && toolbar!=null) {

This will grab our toolbar, grab the text view which will hold our title, set the text on our text view and set the toolbar as our ActionBar.

Now when options menu etc, it will appear in that toolbar.

android android-toolbar

Page 1 of 16