With the new look Android ADT (Android Developer Tool) there is some new project wizards which go a lot further than the old hello world template that I was used to and I am trying to understand them but finding it really difficult.
I am looking at the FullScreen Project Wizard.
enter code here
When you create a project using this wizard it will create an util library containing a file SystemUIHider.java.
Here is the question.
I see:
protected OnVisibilityChangeListener mOnVisibilityChangeListener = sDummyListener;
Which calls an interface found at the bottom of the class file:
public interface OnVisibilityChangeListener {
public void onVisibilityChange(boolean visible);
}
My question is:
1) I thought interfaces had to be extended so what practical purposes can this code have ?
2) How is this possible if OnVisibilityChangeListener is an Interface its not strictly speaking a class ?
private static OnVisibilityChangeListener sDummyListener = new OnVisibilityChangeListener() {
@Override
public void onVisibilityChange(boolean visible) {
}
};
Thanks !
package com.example.test2.util;
import android.app.Activity;
import android.os.Build;
import android.view.View;
public abstract class SystemUiHider {
/**
* When this flag is set, the
* {@link android.view.WindowManager.LayoutParams#FLAG_LAYOUT_IN_SCREEN}
* flag will be set on older devices, making the status bar "float" on top
* of the activity layout. This is most useful when there are no controls at
* the top of the activity layout.
* <p>
* This flag isn't used on newer devices because the <a
* href="http://developer.android.com/design/patterns/actionbar.html">action
* bar</a>, the most important structural element of an Android app, should
* be visible and not obscured by the system UI.
*/
public static final int FLAG_LAYOUT_IN_SCREEN_OLDER_DEVICES = 0x1;
/**
* When this flag is set, {@link #show()} and {@link #hide()} will toggle
* the visibility of the status bar. If there is a navigation bar, show and
* hide will toggle low profile mode.
*/
public static final int FLAG_FULLSCREEN = 0x2;
/**
* When this flag is set, {@link #show()} and {@link #hide()} will toggle
* the visibility of the navigation bar, if it's present on the device and
* the device allows hiding it. In cases where the navigation bar is present
* but cannot be hidden, show and hide will toggle low profile mode.
*/
public static final int FLAG_HIDE_NAVIGATION = FLAG_FULLSCREEN | 0x4;
/**
* The activity associated with this UI hider object.
*/
protected Activity mActivity;
/**
* The view on which {@link View#setSystemUiVisibility(int)} will be called.
*/
protected View mAnchorView;
/**
* The current UI hider flags.
*
* @see #FLAG_FULLSCREEN
* @see #FLAG_HIDE_NAVIGATION
* @see #FLAG_LAYOUT_IN_SCREEN_OLDER_DEVICES
*/
protected int mFlags;
/**
* The current visibility callback.
*/
protected OnVisibilityChangeListener mOnVisibilityChangeListener = sDummyListener;
/**
* Creates and returns an instance of {@link SystemUiHider} that is
* appropriate for this device. The object will be either a
* {@link SystemUiHiderBase} or {@link SystemUiHiderHoneycomb} depending on
* the device.
*
* @param activity The activity whose window's system UI should be
* controlled by this class.
* @param anchorView The view on which
* {@link View#setSystemUiVisibility(int)} will be called.
* @param flags Either 0 or any combination of {@link #FLAG_FULLSCREEN},
* {@link #FLAG_HIDE_NAVIGATION}, and
* {@link #FLAG_LAYOUT_IN_SCREEN_OLDER_DEVICES}.
*/
public static SystemUiHider getInstance(Activity activity, View anchorView, int flags) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
return new SystemUiHiderHoneycomb(activity, anchorView, flags);
} else {
return new SystemUiHiderBase(activity, anchorView, flags);
}
}
protected SystemUiHider(Activity activity, View anchorView, int flags) {
mActivity = activity;
mAnchorView = anchorView;
mFlags = flags;
}
/**
* Sets up the system UI hider. Should be called from
* {@link Activity#onCreate}.
*/
public abstract void setup();
/**
* Returns whether or not the system UI is visible.
*/
public abstract boolean isVisible();
/**
* Hide the system UI.
*/
public abstract void hide();
/**
* Show the system UI.
*/
public abstract void show();
/**
* Toggle the visibility of the system UI.
*/
public void toggle() {
if (isVisible()) {
hide();
} else {
show();
}
}
/**
* Registers a callback, to be triggered when the system UI visibility
* changes.
*/
public void setOnVisibilityChangeListener(OnVisibilityChangeListener listener) {
if (listener == null) {
listener = sDummyListener;
}
mOnVisibilityChangeListener = listener;
}
/**
* A dummy no-op callback for use when there is no other listener set.
*/
private static OnVisibilityChangeListener sDummyListener = new OnVisibilityChangeListener() {
@Override
public void onVisibilityChange(boolean visible) {
}
};
/**
* A callback interface used to listen for system UI visibility changes.
*/
public interface OnVisibilityChangeListener {
/**
* Called when the system UI visibility has changed.
*
* @param visible True if the system UI is visible.
*/
public void onVisibilityChange(boolean visible);
}
}
private static OnVisibilityChangeListener sDummyListener = new OnVisibilityChangeListener() {
@Override
public void onVisibilityChange(boolean visible) {
// Implementation here.
}
};
The above snippet creates and instantiates an anonymous class that implements OnVisibilityChangeListener
by providing the implementation of the function defined in the interface.
Anonymous classes are intended to be used where you need a specific implementation that will not be reused. I.e., there is no reason to give the above class a name if it will only be instantiated in one place, simply use an anonymous class. Typically, anonymous classes are instantiated inline to where they are used, for example:
protected OnVisibilityChangeListener mOnVisibilityChangeListener = new OnVisibilityChangeListener() {
@Override
public void onVisibilityChange(boolean visible) { }
};
Or as an argument to a function, like the following code snippet:
something.setOnVisibilityChangeListener(new OnVisibilityChangeListener() {
@Override
public void onVisibilityChange(boolean visible) { }
});