Android value change listener

Creating Custom Listeners

The «listener» or «observer» pattern is the most common tegy for creating asynchronous callbacks within Android development. Listeners are used for any type of asynchronous event in order to implement the code to run when an event occurs. We see this pattern with any type of I/O as well as for view events on screen. For example, here’s a common usage of the listener pattern to attach a click event to a button:

This listener is built-in but we can also create our own listeners and attach callbacks to the events they fire from other areas in our code. This is useful in a variety of cases including:

  • Firing events from list items upwards to an activity from within an adapter
  • Firing events from a fragment upwards to an activity.
  • Firing async events from an abstraction (i.e networking library) to a parent handler.

In short, a listener is useful anytime a child object wants to emit events upwards to notify a parent object and allow that object to respond.

Listeners are a powerful mechanism for properly separating concerns in your code. One of the essential principles around writing maintainable code is to reduce coupling and complexity using proper encapsulation. Listeners are about ensuring that code is properly organized into the correct places. In particular, this table below offers guidelines about where different types of code should be called:

Type Called By Description
Intents Activity Intents should be created and executed within activities.
Networking Activity , Fragment Networking code should invoked in an activity or fragment.
FragmentManager Activity Fragment changes should be invoked by an activity.
Persistence Activity , Fragment Writing to disk should be invoked by activity or fragment.

While there are exceptions, generally speaking this table helps to provide guidelines as to when you need a listener to propagate an event to the appropriate owner. For example, if you are inside an adapter and you want to launch a new activity, this is best done by firing an event using a custom listener triggering the parent activity.

There are four steps to using a custom listener to manage callbacks in your code:

Define an interface as an event contract with methods that define events and arguments which are relevant event data.

Setup a listener member variable and setter in the child object which can be assigned an implementation of the interface.

Owner passes in a listener which implements the interface and handles the events from the child object.

Trigger events on the defined listener when the object wants to communicate events to it’s owner

The sample code below will demonstrate this process step-by-step.

First, we define an interface in the child object. This object can be a plain java object, an Adapter , a Fragment , or any object created by a «parent» object such as an activity which will handle the events that are triggered.

This involves creating an interface class and defining the events that will be fired up to the parent. We need to design the events as well as the data passed when the event is triggered.

With the interface defined, we need to setup a listener variable to store a particular implementation of the callbacks which will be defined by the owner.

In the child object, we need to define an instance variable for an implementation of the listener:

as well as a «setter» which allows the listener callbacks to be defined in the parent object:

This allows the parent object to pass in an implementation of the listener after this child object is created similar to how the button accepts the click listener.

Now that we have created the setters, the parent object can construct and set callbacks for the child object:

Here we’ve created the child object and passed in the callback implementation for the listener. These events can now be fired by the child object to pass the event to the parent as appropriate.

Now the child object should trigger events to the listener whenever appropriate and pass along the data to the parent object through the event. These events can be triggered when a user action is taken or when an asynchronous task such as networking or persistence is completed. For example, we will trigger the onDataLoaded(SomeData data) event once this network request comes back on the child:

Notice that we fire the listener event listener.onDataLoaded(data) when the asynchronous network request has completed. Whichever callback has been passed by the parent (shown in the previous step) will be fired.

The «listener pattern» is a very powerful Java pattern that can be used to emit events to a single parent in order to communicate important information asynchronously. This can be used to move complex logic out of adapters, create useful abstractions for your code or communicate from a fragment to your activities.

There are several different ways to pass a listener callback into the child object:

  1. Pass the callback through a method call
  2. Pass the callback through the constructor
  3. Pass the callback through a lifecycle event

The code earlier demonstrated passing the callback through a method call like this:

which is defined in the child object as follows:

If the callback is critical to the object’s function, we can pass the callback directly into the constructor of the child object as an argument:

and then when we can create the child object from the parent we can do the following:

The third case is most common with fragments or other android components that need to communicate upward to a parent. In this case, we can leverage existing Android lifecycle events to get access to the listener. In the case below, a fragment being attached to an activity:

For the full details on this approach, check out the fragments guide.

Источник

How to Write a Change Listener

A change listener is similar to a property change listener. A change listener is registered on an object — typically a component, but it could be another object, like a model — and the listener is notified when the object has changed. The big difference from a property change listener is that a change listener is not notified of what has changed, but simply that the source object has changed. Therefore, a change listener is most useful when it is only necessary to know when an object has changed in any way.

Several Swing components (including JTabbedPane, JViewPort) rely on change events for basic functionality — sliders, color choosers and spinners. To learn when the value in a slider changes, you need to register a change listener. Similarly, you need to register a change listener on a color chooser to be informed when the user chooses a new color. You register a change listener on a spinner, to be notified when the spinner’s value changes.

Here is an example of change event handling code for a slider:

You can find the source file for SliderDemo in the example index for Using Swing Components.

The Change Listener API

Because ChangeListener has only one method, it has no corresponding adapter class.

Method Purpose
stateChanged(ChangeEvent) Called when the listened-to component changes state.
Method Purpose
Object getSource()
(in java.util.EventObject )
Returns the object that fired the event.

Examples that Use Change Listeners

The following table lists the examples that use change listeners.

Источник

How to Write a Property Change Listener

Property-change events occur whenever the value of a bound property changes for a bean — a component that conforms to the JavaBeans™ specification. You can find out more about beans from the JavaBeans trail of the Java Tutorial. All Swing components are also beans.

A JavaBeans property is accessed through its get and set methods. For example, JComponent has the property font which is accessible through the getFont and setFont methods.

Besides the get and set methods, a bound property fires a property-change event when its value changes. For more information, see the Bound Properties page in the JavaBeans trail.

Some scenarios that commonly require property-change listeners include:

  • You have implemented a formatted text field and need a way to detect when the user has entered a new value. You can register a property-change listener on the formatted text field to listen to changes on the value property. See FormattedTextFieldDemo in How to Use Formatted Text Fields for an example of this.
  • You have implemented a dialog and need to know when a user has clicked one of the dialog’s buttons or changed a selection in the dialog. See DialogDemo in How to Make Dialogs for an example of registering a property-change listener on an option pane to listen to changes to the value property. You can also check out FileChooserDemo2 in How to Use File Choosers for an example of how to register a property-change listener to listen to changes to the directoryChanged and selectedFileChanged properties.
  • You need to be notified when the component that has the focus changes. You can register a property-change listener on the keyboard focus manager to listen to changes to the focusOwner property. See TrackFocusDemo and DragPictureDemo in How to Use the Focus Subsystem for examples of this.

Although these are some of the more common uses for property-change listeners, you can register a property-change listener on the bound property of any component that conforms to the JavaBeans specification.

You can register a property change listener in two ways. The first uses the method addPropertyChangeListener(PropertyChangeListener) . When you register a listener this way, you are notified of every change to every bound property for that object. In the propertyChange method, you can get the name of the property that has changed using the PropertyChangeEvent getPropertyName method, as in the following code snippet:

The second way to register a property change listener uses the method addPropertyChangeListener(String, PropertyChangeListener) . The String argument is the name of a property. Using this method means that you only receive notification when a change occurs to that particular property. So, for example, if you registered a property change listener like this:

FontListener only receives notification when the value of the component’s font property changes. It does not receive notification when the value changes for transferHandler, opaque, border, or any other property.

The following example shows how to register a property change listener on the value property of a formatted text field using the two-argument version of addPropertyChangeListener :

The Property Change Listener API

Method Purpose
addPropertyChangeListener(PropertyChangeListener) Add a property-change listener to the listener list.
addPropertyChangeListener(String, PropertyChangeListener) Add a property-change listener for a specific property. The listener is called only when there is a change to the specified property.

Because PropertyChangeListener has only one method, it has no corresponding adapter class.

Method Purpose
propertyChange(PropertyChangeEvent) Called when the listened-to bean changes a bound property.
Method Purpose
Object getNewValue()
Object getOldValue()
Return the new, or old, value of the property, respectively.
String getPropertyName() Return the name of the property that was changed.
void setPropagationId() Get or set the propagation ID value. Reserved for future use.

Examples that Use Property Change Listeners

The following table lists the examples that use property-change listeners.

Источник

Number Picker. IOn Value Change Listener Interface

Definition

Some information relates to prerelease product that may be substantially modified before it’s released. Microsoft makes no warranties, express or implied, with respect to the information provided here.

Interface to listen for changes of the current value.

Remarks

Portions of this page are modifications based on work created andВ shared by the Android Open Source ProjectВ and used according to terms described in theВ Creative Commons 2.5 Attribution License.

Properties

Gets the JNI value of the underlying Android object.

(Inherited from IJavaObject) JniIdentityHashCode (Inherited from IJavaPeerable) JniManagedPeerState (Inherited from IJavaPeerable) JniPeerMembers (Inherited from IJavaPeerable) PeerReference (Inherited from IJavaPeerable)

Methods

Called upon a change of the current value.

Disposed() (Inherited from IJavaPeerable)
DisposeUnlessReferenced() (Inherited from IJavaPeerable)
Finalized() (Inherited from IJavaPeerable)
OnValueChange(NumberPicker, Int32, Int32)
SetJniIdentityHashCode(Int32) (Inherited from IJavaPeerable)
SetJniManagedPeerState(JniManagedPeerStates) (Inherited from IJavaPeerable)
SetPeerReference(JniObjectReference) (Inherited from IJavaPeerable)
UnregisterFromRuntime() (Inherited from IJavaPeerable)

Extension Methods

Performs an Android runtime-checked type conversion.

Источник

Читайте также:  Песочница с физикой для андроид
Оцените статью