databinding view is not a binding layout root 以及不顯示的坑

weixin_34247155發表於2017-08-01

好吧其實不是來講這個的,重點是說可能換一種寫法解決,還是把過程寫下來吧.
通過幾個控制元件組合了一個自定義view,繼承自RelativeLayout,就叫IdCardView吧想用databinding來簡化操作,去年怎麼寫怎麼爽,今天忽然就發現了好多坑:
先看怎麼初始化的:

  public IDCardView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initView();
    }
    private void initView() {
        LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context
                .LAYOUT_INFLATER_SERVICE);
//注意這的container是自己,是否繫結到container上設定為false
        binding = DataBindingUtil.inflate(inflater, R.layout.view_idcard, this, false);
    }

然後很happy的開始跑了起來,發現WTF怎麼不顯示,記得去年就是這樣寫的呀,哎當時真的是不求甚解呀...而且記得跟著斷點走了一邊,最後DataBindingUtils呼叫了一個factory.inflate(....) 這個factory都是context湖片區的layoutinflator,應該是沒問題的,但是這是什麼情況呢,算了試試直接用RelativeLayout的inflate方法寫一下試試,於是initView()就這樣寫:


    private void initView() {
        LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context
                .LAYOUT_INFLATER_SERVICE);
        View root = inflate(getContext(), R.layout.view_idcard, null);

        binding = DataBindingUtil.bind(root);
       // binding = DataBindingUtil.getBinding(root);
       // binding = DataBindingUtil.findBinding(root);
    }

然後就得到了標題提到的view is not a binding layout root
後邊註釋掉的是後邊的嘗試,其中findBinding(root)的含義是

Retrieves the binding responsible for the given View. If view is not a binding layout root, its parents will be searched for the binding. If there is no binding, null will be returned.

意思是說,先從root中找繫結的東東,如果root不是個layout包裹的view,那就讓他的父控制元件找,找不到就返回null;

然後getBinding(root)的意思是

Retrieves the binding responsible for the given View layout root. If there is no binding, null
 will be returned. This uses the DataBindingComponent set in[setDefaultComponent(DataBindingComponent)](https://developer.android.com/reference/android/databinding/DataBindingUtil.html#setDefaultComponent(android.databinding.DataBindingComponent))
.

直接看這個view 是不是layout包裹的view,不是直接返回null

但是這個layout確實是layout標籤包裹的,為什麼麼各種繫結獲得的都不是一個binding呢,這是一個問題...我也不知道為什麼...build後能夠獲取binding說明layout檔案沒有錯,也就是說inflate的過程不會錯,那就是引數寫錯了,於是往回看了一下最初寫的

 binding = DataBindingUtil.inflate(inflater, R.layout.view_idcard, this, false);

第四個引數是不將繫結到container上,因為寫adapter什麼的不把inflate到的view填充到container上習慣了就直接寫了,但這裡的container是自己,如果不綁上去那返回的不就是空了嗎,於是還按照最初的寫法,將最後一個引數false改為true,就能夠顯示了,也就不需要bind,getBinding,findbinding了,也算曲線解決了view is not a binding layout root的坑,
最終初始化程式碼為:

 private void initView() {
        LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context
                .LAYOUT_INFLATER_SERVICE);
        DataBindingUtil.inflate(inflater, R.layout.view_idcard, this, false);
    }

相關文章