TextView在xml檔案中加入onClick屬性後,clickable值依舊是false的原因。

來源:互聯網
上載者:User

標籤:

先看View中是如何定義clickable和onClick的:

                case com.android.internal.R.styleable.View_clickable:                    if (a.getBoolean(attr, false)) {                        viewFlagValues |= CLICKABLE;                        viewFlagMasks |= CLICKABLE;                    }                    break;

上面這段代碼是View源碼中對clickable屬性的定義,預設值為false。

                case R.styleable.View_onClick:                    if (context.isRestricted()) {                        throw new IllegalStateException("The android:onClick attribute cannot "                                + "be used within a restricted context");                    }                    final String handlerName = a.getString(attr);                    if (handlerName != null) {                        setOnClickListener(new OnClickListener() {                            private Method mHandler;                            public void onClick(View v) {                                if (mHandler == null) {                                    try {                                        mHandler = getContext().getClass().getMethod(handlerName,                                                View.class);                                    } catch (NoSuchMethodException e) {                                        int id = getId();                                        String idText = id == NO_ID ? "" : " with id ‘"                                                + getContext().getResources().getResourceEntryName(                                                    id) + "‘";                                        throw new IllegalStateException("Could not find a method " +                                                handlerName + "(View) in the activity "                                                + getContext().getClass() + " for onClick handler"                                                + " on view " + View.this.getClass() + idText, e);                                    }                                }                                try {                                    mHandler.invoke(getContext(), View.this);                                } catch (IllegalAccessException e) {                                    throw new IllegalStateException("Could not execute non "                                            + "public method of the activity", e);                                } catch (InvocationTargetException e) {                                    throw new IllegalStateException("Could not execute "                                            + "method of the activity", e);                                }                            }                        });                    }                    break;

上面是onClick屬性在View源碼中的定義。可以看到它調用了setOnClickListener()方法對點擊事件進行註冊,下面看下setOnClickListener()方法的源碼:

    /**     * 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;    }

如果clickable屬性是false那麼在調用此方法後就會變為true。

繼承自View的Button、ImageView控制項在xml裡使用onClick屬性時,通過列印日誌可以看到clickable由預設的false變為了true,可是同樣繼承自View的TextView依舊是false。為什麼會出現這種情況呢?

那就要瞭解Android載入xml檔案的過程。

以View為例進行說明。我們使用setOnContentView()方法載入布局檔案時。布局檔案中的View元素會調用下面的這個構造器來建立一個View對象

    /**     * Constructor that is called when inflating a view from XML. This is called     * when a view is being constructed from an XML file, supplying attributes     * that were specified in the XML file. This version uses a default style of     * 0, so the only attribute values applied are those in the Context‘s Theme     * and the given AttributeSet.     *     * <p>     * The method onFinishInflate() will be called after all children have been     * added.     *     * @param context The Context the view is running in, through which it can     *        access the current theme, resources, etc.     * @param attrs The attributes of the XML tag that is inflating the view.     * @see #View(Context, AttributeSet, int)     */    public View(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }
View Code

this(context, attrs, 0);又會調用 public View(Context context, AttributeSet attrs, int defStyleAttr){}構造器。可以看到onClick屬性在定義時調用的setOnClickListener()方法是在對象被建立時調用的。

下面再來看TextView控制項,他在構造器中對clickable又進行了一些處理

        boolean focusable = mMovement != null || getKeyListener() != null;        boolean clickable = focusable;        boolean longClickable = focusable;        n = a.getIndexCount();        for (int i = 0; i < n; i++) {            int attr = a.getIndex(i);            switch (attr) {            case com.android.internal.R.styleable.View_focusable:                focusable = a.getBoolean(attr, focusable);                break;            case com.android.internal.R.styleable.View_clickable:                clickable = a.getBoolean(attr, clickable);                break;            case com.android.internal.R.styleable.View_longClickable:                longClickable = a.getBoolean(attr, longClickable);                break;            }        }

從代碼中可以看到clickable的預設值變成了focuseable的值,TextView在調用構造器創造新的對象的時候會預設調用父類的構造器,也就是說經過setOnClickListener()處理過的clickable值是變成了true,可是在TextView的構造器中又被賦予了新的值。這也可以解釋說為什麼TextView控制項在xml檔案中用了onClick屬性後clickable的值依舊是false,而在代碼中調用setOnClickListener()方法後,clickable值就變成了true,那是因為在代碼中調用的setOnClickListener()方法是在TextView對象被建立之後。

TextView在xml檔案中加入onClick屬性後,clickable值依舊是false的原因。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

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.