AndroidUI佈局問題總結

xiaoqb發表於2016-01-25
在做新行程專案期間,遇到了很多關於UI佈局的問題,這裡總結一部分,都是一些小細節,希望能加深理解,以後少走彎路。

一 頁面喚起後view建立完成的時間

   

 Activity的生命週期為下圖所示:

   

 Activity在onCreate中使用setContentView()方法中載入xml佈局,那麼佈局中的view是在何時完成建立的呢?在父佈局中新增一個TextView,使用getLeft()、getRight()方法獲取TextView在父佈局中的左右邊界的位置,列印出來可以看到

   

    在onResume方法中獲取的位置依然為0,按下home鍵後,將應用置為後臺執行,可以看到

   
    在onPause方法中列印出了位置,所以Activity中view建立完成的時間是在呼叫OnResume()方法返回之後,在此之前是無法獲取view的位置資訊的,fragment也是類似的,fragment的生命週期如圖:


     

    同樣在佈局中新增一個TextView,頁面啟動後列印TextView的位置,可以看到

  

    在OnResume方法中也並沒有列印出TextView得位置,按下home鍵,可以看到

   
    
    列印出了TextView得位置,所以Fragment中view從建立完成到可見也是在OnResume()方法返回之後。那麼如何才能知道activity已經完全載入,view已經可見了呢,可以根據OnWindowFocusChange()回撥方法來判斷。
OnWindowFocusChange()在OnResume()或者OnPause()方法呼叫完成之後被呼叫,可以保證activity已經完全載入,如圖所示

   

二 複用View時避免之前View的屬性的影響   

    在使用RecyclerView,ListView或者GridView時,為了節省記憶體,android系統將新建立的view直接複用上一個同型別的、當前已不可見的view,以RecyclerView為例,設定RecyclerView的item佈局為一個ImageView加一個TextView,在adapter的

OnBindViewHolder()中設定第一個item的字型顏色為紅色,程式碼如下:

@Override public void onBindViewHolder(MyViewHolder holder, int position) { String url = mUrlList.get(position); Picasso.with(mContext).load(url).into(holder.mIvPic); holder.mTvText.setText("這是第 " + position + "個"); if(position == 0){ holder.mTvText.setTextColor(Color.parseColor("#ff0000")); } }

執行效果如圖所示:
     

咋看起來滿足了要求,只有第一個item的字型標紅了,但是上下滾動幾次,使得別的view能夠複用第一個view,可以看到
    
    

別的item也出現了字型被標紅的效果,這是由於在view複用的時候,只是對特殊情況進行了處理,並沒有對正常情況進行處理,簡單來說就是隻設定第一個位紅色,沒有設定非第一個為黑色,沒有做到有if就有else,重寫onBindViewHolder方法為:

    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {
        String url = mUrlList.get(position);
        Picasso.with(mContext).load(url).into(holder.mIvPic);
        holder.mTvText.setText("這是第 " + position + "個");
        if(position == 0){
            holder.mTvText.setTextColor(Color.parseColor("#ff0000"));
        }else{
            holder.mTvText.setTextColor(Color.parseColor("#000000"));
        }
    }

這樣就不會出現非0個view字型標紅的情況了,如圖:

   

與此類似,當使用RecyclerView、ListView或者GridView時,要注意上一個view對之後view複用的影響,對於特殊屬性的處理,要做到有if就要有else,避免屬性不同的影響。
三 .9圖片的可繪製區域

    Android使用9patch處理圖片以保證圖片不會隨著螢幕尺寸的變化而失真,如圖:
    
    

背景圖片會隨著文字內容的變化動態調整大小而不會失真,在使用.9圖片時候需要注意可操作區域的大小,每條邊都要設定操作區域,如果設定.9圖片的拉伸區域為:

    

那麼在尖角上面的區域就是不可操作的區域,如圖:

    

文字只存在於下方可操作區域內,上面的空間就無法使用了,正確的設定方法為:

    

保證可編輯區域的大小範圍滿足要求。

總結

    還有一些小細節,比如RelativeLayout使用wrap_content屬性,如果其內部View使用alignParentBottom或者alignParentRight等需要依賴父佈局位置時,RelativeLayout就會撐滿全屏等,都是一些小細節,陸續還會總結,以便加深記憶,提高效率。


該文章來自於阿里巴巴技術協會(ATA

作者:蕭鎖


相關文章