1. 程式人生 > >自定義preference onBindView易犯的錯誤

自定義preference onBindView易犯的錯誤

public class PowerInformationPreference extends Preference {

    private TextView firstName;

    public PowerInformationPreference(Context context, AttributeSet attr, int defStyle) {
        super(context, attr, defStyle);
        setLayoutResource(R.layout.layout_power_information);
    }

    @Override
    protected void onBindView(View view) {(1)
        // TODO Auto-generated method stub
        super.onBindView(view);
        firstName = (TextView)view.findViewById(R.id.firstname);(2)
    }

}

上面是我們很常見到的自定義preference的基本形式,我們在onBindView()函式中操作自定義檢視,比如上面的程式碼中我們需要動態的改變firstName這一TextView的text值。

如下,我們提供一個setText()介面,通過這個介面我們可以動態改變TextView的text值。

public void setText(String text){(3)
    firstName.setText(text);//NullPointerException(4)
}

如果我們真的是這樣寫這個介面的話,會發現一定會出現NullPointerException,除錯發現這裡的firstName為空。而回到onBindView()中除錯分析又會發現,firstName = (TextView)view.find...實際上是會執行的,也就是有這個firstName物件存在。那麼唯一的解釋就是setText()的呼叫在onBindView()執行之前,因此我們的疑惑來了,如何確保onBindView()在setText()呼叫之前執行呢?

事實上,到這裡我們如果繼續這樣分析的話,就會鑽入誤區,跳出來,從邏輯層面上想想,我們會發現,(1),(2),(4)是對UI的操作,(3)是對資料的操作。這裡,(1)(2)和(4)分開了,也就是說,(1)(2)執行的時候不能保證(4)執行;(4)執行的時候不能保證(1)(2)執行,這對UI操作是非常危險的事,很容易就產生了控制正異常。

不僅僅是這裡,我們檢視Adapter.java的原始碼,檢視有getView(), onCreateView(), onBindView()等類的相關原始碼,都會發現,凡是涉及到UI操作的一定是放在一起的。

現給出上例的修正方案:

public class PowerInformationPreference extends Preference {

    private TextView firstName;
    private String text;

    public PowerInformationPreference(Context context, AttributeSet attr, int defStyle) {
        super(context, attr, defStyle);
        setLayoutResource(R.layout.layout_power_information);
    }

    @Override
    protected void onBindView(View view) {(1)
        // TODO Auto-generated method stub
        super.onBindView(view);
        firstName = (TextView)view.findViewById(R.id.firstname);(2)
        firstName.setText(text);
    }

public void setText(String text){(3) this.text = text;
notifyChanged();
}
}
這裡還需要強調的一點是一定不要忘記notifyChanged()這個函式通知UI更新資料,否則我們會發現通過這個介面設定的資料並沒有改變原來的值。這個函式如同View中的invalidate(),雖然資料更新了,但是顯示在檢視中的數字影象依然沒變,因此需要通知UI更新顯示。

相關推薦

定義preference onBindView錯誤

public class PowerInformationPreference extends Preference { private TextView firstName;     public PowerInformationPreference(Cont

ionic項目中使用定義圖標打包出現錯誤-broken import

opera b- 替換 tex clas size c項目 smo androi 添加自定義字體圖標 在src目錄下新建icon文件夾,把字體文件放進去。然後在theme/variables.scss中後面添加以下內容,註意把相應位置替換成你自己的: 1 $i

C++筆記007:錯誤模型——類中為什麽需要成員函數

計算 成員 area 分享圖片 end src 賦值 內存空間 3.1 先看源碼,在VS2010環境下無法編譯通過,在VS2013環境下可以編譯通過,並且可以運行,只是運行結果並不是我們期待的結果。 最初通過MyCircle類定義對象c1時,為對象分配內存空間,r沒有初

定義異常處理類及錯誤提示類的使用技巧

一.關於自定義處理異常類及聯合自定義錯誤提示類的使用     1.專案內自定義py檔案,使用者存放自定義的錯誤提示類 class BaseResponse(object):     def __init__(self):

安卓定義View——網顏色漸變效果指示器

一直想寫部落格來著,可惜直到現在才真正抽出時間。最近一直在研究網易新聞這個UI框架,發現了一些很值得借鑑的效果,當然,網上也不乏這方面的介紹。本文主要實現的指示器效果為字型顏色和大小漸變,廢話不多說獻上效果圖: 實現效果主要包括: 指示器背景可以根據使用者自己定製形

VC定義訊息ON_MESSAGE的編譯錯誤error C2440

在手動新增ON_MESSAGE時,遇到下面的編譯錯誤: error C2440: 'type cast' : cannot convert from 'void (__thiscall CXXXView::*)(unsigned int,long)' to 'long

Thinkphp框架中IF標籤的錯誤彙總

今天用到了Thinkphp框架中IF標籤,一直報錯,在排錯過程中很是糾結,特此總結一下。 官方文件:模板->內建標籤->IF標籤舉例如下: 用法示例: <ifcondition="($name eq 1) OR ($name gt 100) ">

測試開發專題:spring-boot定義返回引數校驗錯誤資訊

之前兩篇文章 [Spring-boot自定義引數校驗註解](https://www.immortalp.com/articles/2020/05/15/1589509382896.html)和[如何在spring-boot中進行引數校驗](https://www.immortalp.com/articles/

nginx定義500,502,504錯誤頁面無法跳轉【轉】

header cli targe head href 錯誤 error tom htm 1、自定一個頁面,這個頁面是一個鏈接地址可以直接訪問的。 以下是nginx的配置: location / { proxy_pass http://tomcat_

Laravel之加密解密/日誌/異常處理及定義錯誤

文件中 例如 tom 處理器 crypt return cat 情況 而不是 一.加密解密 1.加密Crypt::encrypt($request->secret) 2.解密try {   $decrypted = Crypt::decrypt($encryptedV

學習筆記19_定義錯誤

默認 errors acc .html 調試 error redirect nbsp edi 在WebConfig中,可以配置當服務器發生哪些錯誤時,能跳轉到那個頁面: <customErrors mode ="On" defaultRedirect = " defa

qt5 + vs2015定義控件錯誤:undefend interface

自定義 widget 報錯 文件路徑 集成 wid 所在 結果 nbsp 控件中編譯時因為是把所有的單個控件集成到一個lib中,所以會引用#include<QDesignerCustomWidgetInterface>以及#include<QDesigne

Laravel5.4中定義404等錯誤頁面

dtd app top exc auto get 1.0 存在 href 1.在resources/views/下簡歷文件夾error,在error文件中建立"404.blade.php文件"。    1 <!DOCTYPE html PUBLIC "-//W3C

lumen 定義錯誤日誌文件

參數 glib ace 寫入文件 handle cnblogs 可用 perm ror 自定義錯誤日誌文件,改造新的方法 <?php namespace App; use Monolog\Logger; use Monolog\Handler\StreamHandl

定義工具錯誤: 無法生成服務引用的代碼VS2012

有關 lock 原因 集合類型 pointer 錯誤 類型 clas tex 今天更新服務引用後出現了一百多個錯誤,不更新就沒事, 後來在網上找到原因: 箭頭處的checkbox不要點選,此外,跟集合類型也有關系,我這邊是System.Collecti

MVC定義錯誤頁面

scu ebp name lte timeout sts form -m 技術   MVC異常處理主要有三種方案:1.基於HandleErrorAttribute重寫OnException方法;2.基於Global.apsx添加Application_Error方法;3.直

定義錯誤處理

處理 all 信息 誤報 綁定 ont error () err 自己定義錯誤報告的處理方式。這裏主要是要介紹一個函數set_error_handler ()函數,裏面接受兩個參數(第一個參數是一個回調函數,第二個參數規定哪一個錯報報告級別顯示用戶定義的錯誤,默認值為E_

Tomcat下使用定義錯誤頁面

tomcat html 最近在整理部分服務器的時候發現有一臺業務量並不是很大的Windows服務器可以下架了,但是目前在服務器上還有一個使用IIS的站點,知道這個站點在平時的訪問量不大,就打算做遷移,打開IIS看了下這個站點上都是html純靜態頁面,連數據庫連接的交互都沒有。好吧,這樣就簡單了,

MVC4 定義錯誤頁面(三)

gif static quest glob logger tool iis def .cn 一、概述 MVC4框架自帶了定義錯誤頁,該頁面位於Shared/Error,該頁面能夠顯示系統未能捕獲的異常,如何才能使用該頁面; 二、使用步驟: 1、配置WebConfig文件,在

ASP.NET MVC下定義錯誤頁和展示錯誤頁的幾種方式

提供服務 one url attribute 運行 16px execute 釋放 namespace 在網站運行中,錯誤是不可避免的,錯誤頁的產生也是不可缺少的。 這幾天看了博友的很多文章,自己想總結下我從中學到的和實際中配置的。 首先,需要知道產生錯誤頁的來源,一種