編輯: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.
系統啟動過程圖: Framework層所有的Service都是運行在SystemServer進程中;SystemServer進程是由Zygote進程創
屏幕亮度自動調節:主要是從Sensor分析之中分離出來分析LIGHT 光線感應器,因此就分析一下自動調節屏幕亮度(手機隨著光線的強度自我調節,也就是在亮的光線下屏
前面文章已經詳細介紹了Android界面的入門技術,相信大家在看完和跟著練習之後,會對於常用的Layout和View都會有一定的了解了,接下來就不再強調介紹界面了
登錄應用程序的屏幕,詢問憑據登錄到一些特定的應用。可能需要登錄到Facebook,微博等本章介紹了,如何創建一個登錄界面,以及如何管理安全問題和錯誤嘗試。首先,必須定義兩