Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發實例 >> Android ViewGroup(Layout)使用注意事項(II)

Android ViewGroup(Layout)使用注意事項(II)

編輯:Android開發實例

在前文中我們闡述了使用組合View的這種奇怪現象。出現這種問題的根源在於IconTextView類的實現,大部分的開發者認為使用IconTextView這種自定義View的方式 就相當於自定義了一個包含有一個ImageView和兩個TextView的組合控件。 但是這裡有個問題, 在View的層次結構中多出了一個LinearLayout。

仔細分析下, 我們的IconTextView類繼承自LinearLayou,而布局文件icon_text_view.xml的根元素也是LinearLayou,這樣我們的IconTextView的View關系就是兩個Layout下面包含3個單個View。 使用Android的hierarchyviewer.bat工具可以查看到這種層次結構。

在icon_text_view.xml的布局文件中 我們指定了布局文件中的LinearLayout的android:focusable和android:clickable屬性, 這樣外面的自定義LInearLayou(上圖中的IconTextView)就沒法獲取焦點和點擊事件了,這樣設置在IconTextView中的點擊事件當然也無法響應了。

為了使這種View的層次結構更加清晰可見,可以在代碼中給IconTextView也添加一個背景圖片

        IconTextView itv = new IconTextView(this);
        itv.setBackgroundResource(android.R.drawable.btn_default);
這樣再次運行程序就可以發現Layout的層次關系了.

可以很明顯的看到 有2個Layout存在。 當我們點擊裡面那個Layout的時候 可以具有Press狀態響應,但是由於裡面的Layout沒有注冊事件,所以不會有時間響應;如果我們設置外面的Layout可以響應點擊事件,這樣裡面的Layou就不能響應Press狀態了。從而出現這種Press狀態顯示和點擊事件的響應不能同時實現的問題。

現在既然已經明白問題的根源了, 解決之道也是很容易的,把 icon_text_view.xml中的Layout刪除 使用Android提供的marge元素就可以了,同時在IconTextView類中或者在添加該組合View到其他ViewGroup的時候指定其是可以獲得焦點的就可以了。
最終解決代碼如下:

布局文件 merge_icon_text_view.xml 使用marge來代替LinearLayout

 <?xml version="1.0" encoding="utf-8"?>
<merge
  xmlns:android="http://schemas.android.com/apk/res/android"
 >
  <ImageView
      android:src="@drawable/feedicon"
      android:layout_width="wrap_content"
      android:layout_height="fill_parent"
  />
  <LinearLayout
    android:orientation="vertical"
      android:layout_width="fill_parent"
      android:layout_height="wrap_content">
  <TextView
      android:text="merge Line one"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"/>
  <TextView
      android:text="merge Line two"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"/>
  </LinearLayout>
</merge>

自定義View類IconTextView, 不要忘記設置focusable屬性

 public class IconTextView extends LinearLayout {

    ImageView mImageView;
    TextView mTextOne;
    TextView mTextTwo;

    public IconTextView(Context context) {
        super(context);

        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        inflater.inflate(R.layout.merge_icon_text_view, this, true);
        setFocusable(true);
        // 設置mImageView,mTextOne,mTextTwo view的代碼
    }

    public void setData(Drawable icon,String line1, String line2) {
        mImageView.setImageDrawable(icon);
        mTextOne.setText(line1);
        mTextTwo.setText(line2);
    }

}

總結: 在使用自定義組合View的時候 注意ViewGroup的層次結構,如果引入了不必要的ViewGroup可以通過marge元素來消除。

更新: 也可以在布局文件中使用 自定義View的類名稱, 例如把上面布局文件中的 merge 替換為: org.goodev.IconTextView.

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved