Android design mode-Observer mode and android Design Mode

Source: Internet
Author: User

Android design mode-Observer mode and android Design Mode

Problem:

In Android, based on the Android event tree, we know that the event is triggered when interacting with the app through screen buttons, touch, slide, and other operations, interactive events are propagated from top to bottom along the event tree;

When the parent control at the upper layer of the event tree receives the event, it determines the event to which it belongs. If necessary, the event is intercepted. Otherwise, it is propagated to the Child control.


So we are writing various Listener and reading various event functions to accept and process various types of interactive events. Is this processing mode an observer mode?


The problem is put here first.

Back to the truth:

Observer mode:


1. Definition:

Define a one-to-Define dependency between objects so that when one object changes state, all its dependents aer notified and updated automatically.
Defines a one-to-many dependency between objects so that when an object changes state, all objects dependent on it will be notified and automatically updated.


2. applicable:
When an object needs to change other objects at the same time, and does not know how many objects need to change, consider using the observer mode;


3. Purpose:

The work done by the observer mode is actually decoupling, so that both sides of the coupling depend on and abstract, rather than making the changes of both sides do not affect the changes of the other side;


4. Principles:

The observer mode conforms to the dependency reversal principle;


5. Others:

The observer mode is an object behavior mode. It is also called the Publish/Subscribe mode, Model-View mode, and Source-Listener (Source/Listener) mode) mode or Dependents mode.


6. Simple demo:

The demo business is: a button object. When a button is clicked, two views are changed;

First, the observer:

Package com. example. demo. observer;/*** abstract Observer (Observer) role * @ author qubian * @ data June 11, 2015 * @ email naibbian@163.com **/public interface Observer {public void upadteView (String info );} package com. example. demo. observer; import android. util. log;/*** specific Observer role * @ author qubian * @ data June 11, 2015 * @ email naibbian@163.com **/public class Observer_View1 implements Observer {@ Overridepublic void upadteView (String info) {Log. I ("upadteView", "Observer_View1, View 1 changed. The changed content is:" + info) ;}} package com. example. demo. observer; import android. util. log;/*** specific Observer role * @ author qubian * @ data June 11, 2015 * @ email naibbian@163.com **/public class Observer_View2 implements Observer {@ Overridepublic void upadteView (String info) {Log. I ("upadteView", "Observer_View2, view 2 changed. The changed content is:" + info );}}

Topic role:

Package com. example. demo. observer; import java. util. arrayList; import java. util. list;/*** abstract topic (Subject) role * @ author qubian * @ data June 11, 2015 * @ email naibbian@163.com **/public abstract class Subject {private List <Observer> list; /*** add an observer, interface-oriented, and abstract-Oriented Programming * @ param Observer */public void addObserver (observer) {if (list = null) {list = new ArrayList <Observer> ();} list. add (observer);}/*** Notification View change * @ param info */public void yydatasetchange (String info) {for (Observer observer: list) {observer. upadteView (info) ;}} package com. example. demo. observer; import android. util. log;/*** specific observer role * For example, I click the button, I hope, view changes * @ author qubian * @ data June 11, 2015 * @ email naibbian@163.com */public class Subject_Button extends Subject {/*** click the button, I hope, view changed */public void Click () {Log. I ("Subject_Button", "click the button"); String tag = "101"; yydatasetchange (tag );}}

Usage:

Package com. example. demo. observer;/*** use * @ author qubian * @ data June 11, 2015 * @ email naibbian@163.com **/public class UseObserver {public void use () {// The business is like this: I clicked the button. I want the view bound to this button to change // first, there are two views for the Observer: Observer obj1 = new Observer_View1 (); observer obj2 = new Observer_View2 (); // click Subject_Button sub = new Subject_Button (); sub. addObserver (obj1); sub. addObserver (obj2); // click the button to change sub. click ();}}

7. java Library:

In the java. util library in java, an Observable class and an Observer interface are provided to support the Observer mode in java.

It is easy to use. The Observer interface is implemented for the specific object to be observed. The Observable class can be inherited by the Observer.

Relatively simple;

/* *  Licensed to the Apache Software Foundation (ASF) under one or more *  contributor license agreements.  See the NOTICE file distributed with *  this work for additional information regarding copyright ownership. *  The ASF licenses this file to You under the Apache License, Version 2.0 *  (the "License"); you may not use this file except in compliance with *  the License.  You may obtain a copy of the License at * *     http://www.apache.org/licenses/LICENSE-2.0 * *  Unless required by applicable law or agreed to in writing, software *  distributed under the License is distributed on an "AS IS" BASIS, *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *  See the License for the specific language governing permissions and *  limitations under the License. */package java.util;/** * {@code Observer} is the interface to be implemented by objects that * receive notification of updates on an {@code Observable} object. * * @see Observable */public interface Observer {    /**     * This method is called if the specified {@code Observable} object's     * {@code notifyObservers} method is called (because the {@code Observable}     * object has been updated.     *     * @param observable     *            the {@link Observable} object.     * @param data     *            the data passed to {@link Observable#notifyObservers(Object)}.     */    void update(Observable observable, Object data);}package android.database;import java.util.ArrayList;/** * Provides methods for registering or unregistering arbitrary observers in an {@link ArrayList}. * * This abstract class is intended to be subclassed and specialized to maintain * a registry of observers of specific types and dispatch notifications to them. * * @param T The observer type. */public abstract class Observable<T> {    /**     * The list of observers.  An observer can be in the list at most     * once and will never be null.     */    protected final ArrayList<T> mObservers = new ArrayList<T>();    /**     * Adds an observer to the list. The observer cannot be null and it must not already     * be registered.     * @param observer the observer to register     * @throws IllegalArgumentException the observer is null     * @throws IllegalStateException the observer is already registered     */    public void registerObserver(T observer) {        if (observer == null) {            throw new IllegalArgumentException("The observer is null.");        }        synchronized(mObservers) {            if (mObservers.contains(observer)) {                throw new IllegalStateException("Observer " + observer + " is already registered.");            }            mObservers.add(observer);        }    }    /**     * Removes a previously registered observer. The observer must not be null and it     * must already have been registered.     * @param observer the observer to unregister     * @throws IllegalArgumentException the observer is null     * @throws IllegalStateException the observer is not yet registered     */    public void unregisterObserver(T observer) {        if (observer == null) {            throw new IllegalArgumentException("The observer is null.");        }        synchronized(mObservers) {            int index = mObservers.indexOf(observer);            if (index == -1) {                throw new IllegalStateException("Observer " + observer + " was not registered.");            }            mObservers.remove(index);        }    }    /**     * Remove all registered observers.     */    public void unregisterAll() {        synchronized(mObservers) {            mObservers.clear();        }    }}

8. android Application:

Back to the above problems;

Obviously, the upload of the above Android event tree, the listening of interactive events, the Listener callback we wrote, and the whole listening part is an observer mode.


In the most familiar click events, we set the view listener during initialization:


    /**     * Register a callback to be invoked when this view is clicked. If this view is not     * clickable, it becomes clickable.     *     * @param l The callback that will run     *     * @see #setClickable(boolean)     */    public void setOnClickListener(OnClickListener l) {        if (!isClickable()) {            setClickable(true);        }        getListenerInfo().mOnClickListener = l;    }

OnClickListener Interface Description:

    /**     * Interface definition for a callback to be invoked when a view is clicked.     */    public interface OnClickListener {        /**         * Called when a view has been clicked.         *         * @param v The view that was clicked.         */        void onClick(View v);    }

OnclickListener is in the internal class ListenerInfo of the View:

static class ListenerInfo {        protected OnFocusChangeListener mOnFocusChangeListener;        private ArrayList<OnLayoutChangeListener> mOnLayoutChangeListeners;        private CopyOnWriteArrayList<OnAttachStateChangeListener> mOnAttachStateChangeListeners;        /**         * Listener used to dispatch click events.         * This field should be made private, so it is hidden from the SDK.         * {@hide}         */        public OnClickListener mOnClickListener;        protected OnLongClickListener mOnLongClickListener;        protected OnCreateContextMenuListener mOnCreateContextMenuListener;        private OnKeyListener mOnKeyListener;        private OnTouchListener mOnTouchListener;        private OnHoverListener mOnHoverListener;        private OnGenericMotionListener mOnGenericMotionListener;        private OnDragListener mOnDragListener;        private OnSystemUiVisibilityChangeListener mOnSystemUiVisibilityChangeListener;    }

Call:

    public boolean performClick() {        sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);        ListenerInfo li = mListenerInfo;        if (li != null && li.mOnClickListener != null) {            playSoundEffect(SoundEffectConstants.CLICK);            li.mOnClickListener.onClick(this);            return true;        }        return false;    }    public boolean callOnClick() {        ListenerInfo li = mListenerInfo;        if (li != null && li.mOnClickListener != null) {            li.mOnClickListener.onClick(this);            return true;        }        return false;    }

The calling of javasmclick is embodied in the OnTouchEvent listener of the View:

 public boolean onTouchEvent(MotionEvent event) {        if (((viewFlags & CLICKABLE) == CLICKABLE ||                (viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE)) {            switch (event.getAction()) {                case MotionEvent.ACTION_UP:                    boolean prepressed = (mPrivateFlags & PFLAG_PREPRESSED) != 0;                    if ((mPrivateFlags & PFLAG_PRESSED) != 0 || prepressed) {                        // take focus if we don't have it already and we should in                        // touch mode.                        boolean focusTaken = false;                        if (isFocusable() && isFocusableInTouchMode() && !isFocused()) {                            focusTaken = requestFocus();                        }                        if (prepressed) {                            // The button is being released before we actually                            // showed it as pressed.  Make it show the pressed                            // state now (before scheduling the click) to ensure                            // the user sees it.                            setPressed(true);                       }                        if (!mHasPerformedLongPress) {                            // This is a tap, so remove the longpress check                            removeLongPressCallback();                            // Only perform take click actions if we were in the pressed state                            if (!focusTaken) {                                // Use a Runnable and post this rather than calling                                // performClick directly. This lets other visual state                                // of the view update before click actions start.                                if (mPerformClick == null) {                                    mPerformClick = new PerformClick();                                }                                if (!post(mPerformClick)) {                                    performClick();                                }                            }                        }                        if (mUnsetPressedState == null) {                            mUnsetPressedState = new UnsetPressedState();                        }                        if (prepressed) {                            postDelayed(mUnsetPressedState,                                    ViewConfiguration.getPressedStateDuration());                        } else if (!post(mUnsetPressedState)) {                            // If the post failed, unpress right now                            mUnsetPressedState.run();                        }                        removeTapCallback();                    }                    break;                case MotionEvent.ACTION_DOWN:                                       break;                case MotionEvent.ACTION_CANCEL:                                   case MotionEvent.ACTION_MOVE:                                       break;            }            return true;        }        return false;    }


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.