編輯:Android開發實例
上次寫的是構建Android內置浮動搜索框的配置,當然很簡單了,就是麻煩點而已 在我寫demo的過程中我發現一個問題 上次有提到
其中有個 android:icon="@drawable/menu_route" 本來以為可以設置 就搜索Text前面那個View的 後來發現不起作用,而且文檔中都沒提到這個屬性 看來確實沒用啊 因為這屬性我可折騰好久
效果如圖
就是這個了,看了SDK的文檔發現確實這裡沒有提供修改圖標的配置,那如果這裡有需求要改的情況怎麼辦呢,所以研究了下源碼 終於解決了
仔細看中間輸入框兩邊的那個圖標就可以看到 左邊那個就是Application的Icon 是個ImageView , 右邊那個是固定的 是個Button
這個配置就在 /res/layout/search_bar.xml 文件中 可以自己看一下布局 如下:
- <?xml version="1.0" encoding="UTF-8"?>
- <view android:orientation="vertical" android:id="@id/search_bar" android:focusable="true" android:descendantFocusability="afterDescendants" android:layout_width="fill_parent" android:layout_height="wrap_content" class="android.app.SearchDialog$SearchBar"
- xmlns:android="http://schemas.android.com/apk/res/android">
- <LinearLayout android:orientation="vertical" android:id="@id/search_plate" android:background="@drawable/search_plate_global" android:paddingLeft="12.0dip" android:paddingTop="7.0dip" android:paddingRight="6.0dip" android:paddingBottom="16.0dip" android:layout_width="fill_parent" android:layout_height="wrap_content">
- <TextView android:textAppearance="?textAppearanceSmall" android:textColor="?textColorPrimaryInverse" android:id="@id/search_badge" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="2.0dip" android:drawablePadding="0.0dip" />
- <LinearLayout android:orientation="horizontal" android:id="@id/search_edit_frame" android:layout_width="fill_parent" android:layout_height="wrap_content">
- <ImageView android:layout_gravity="center_vertical" android:id="@id/search_app_icon" android:layout_width="36.0dip" android:layout_height="36.0dip" android:layout_marginRight="7.0dip" />
- <view android:ellipsize="end" android:id="@id/search_src_text" android:background="@drawable/textfield_search" android:paddingLeft="8.0dip" android:paddingRight="6.0dip" android:layout_width="0.0dip" android:layout_height="wrap_content" android:singleLine="true" android:drawablePadding="2.0dip" android:popupBackground="@drawable/search_dropdown_background" android:layout_weight="1.0" android:inputType="textAutoComplete" android:dropDownWidth="fill_parent" android:dropDownAnchor="@id/search_plate" android:dropDownHeight="fill_parent" android:dropDownVerticalOffset="-9.0dip" class="android.app.SearchDialog$SearchAutoComplete" />
- <Button android:id="@id/search_go_btn" android:background="@drawable/btn_search_dialog" android:layout_width="wrap_content" android:layout_height="fill_parent" />
- <ImageButton android:id="@id/search_voice_btn" android:background="@drawable/btn_search_dialog_voice" android:layout_width="wrap_content" android:layout_height="fill_parent" android:layout_marginLeft="0.0dip" android:layout_marginTop="-6.5dip" android:layout_marginRight="-5.0dip" android:layout_marginBottom="-7.0dip" android:src="@drawable/ic_btn_speak_now" />
- </LinearLayout>
- </LinearLayout>
- </view>
可以看到Google還專門給訂制了一款搜索框呢 android.app.SearchDialog$SearchAutoComplete 都不帶用 AutoCompleteTextView 的
上面就是這個搜索框的布局文件 那顯示的其實就是 SearchDialog 在android.app包裡的 剛開始在2.1裡還沒見到這個類呢 不知道咋回事
我們調用搜索框的方法是 通過onSearchRequested ()來調用Acitvity的startSearch()
而在Acitivity中我們可以看到一個變量mSearchManager 真正調用的就是它的方法startSearch()
這樣我們就了解了這個搜索框整個的調用過程了
在我的應用中:
MapActivity--》Acitvity--》SearchManager--》SearchDialog
這樣就清晰了 下面就可以進行操作了 然而這些類中的全局變量是private 的 而且沒有提供set方法 這樣我們就不能直接訪問變量進行修改了,那只有一個方法了 就是反射
首先看代碼: 在調用startSearch()方法顯示搜索框之後
- try {
- //通過反射修改搜索框的圖標
- Class activityClass = Class.forName("android.app.Activity");
- Field activityClassf = activityClass.getDeclaredField("mSearchManager");
- activityClassf.setAccessible(true);
- Object mSearchManager = activityClassf.get(this);
- Class searchClass = Class.forName("android.app.SearchManager");
- Field mSearchDialogf = searchClass.getDeclaredField("mSearchDialog");
- mSearchDialogf.setAccessible(true);
- Object mSearchDialog = mSearchDialogf.get(mSearchManager);
- Class searchDialog = Class.forName("android.app.SearchDialog");
- Field mAppIcon = searchDialog.getDeclaredField("mAppIcon");
- mAppIcon.setAccessible(true);
- ImageView imageView = (ImageView) mAppIcon.get(mSearchDialog);
- Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.test);
- imageView.setImageDrawable(new BitmapDrawable(bitmap));
- } catch (Exception e) {
- e.printStackTrace();
- }
這裡首先在當前對象Acitivity中 拿到私有變量 mSearchManager 的對象 然後通過它拿到私有變量 mSearchDialog 的SearchDialog的對象,最後拿到SearchDialog中的私有變量mAppIcon 這個ImageView 那當然就可以隨便對他進行修改了
上面這個是更改搜索框左邊那個Icon的方法 右邊的那個同理也是可以修改的 只不過它是Button而已
- Field mGoButtonf = searchDialog.getDeclaredField("mGoButton");
- mGoButtonf.setAccessible(true);
- Button mGoButton = (Button) mGoButtonf.get(mSearchDialog);
- bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.transit);
- mGoButton.setCompoundDrawablesWithIntrinsicBounds(new BitmapDrawable(bitmap), null, null, null);
這樣就修改完成了 下面來看看效果:
都修改完成了。。當然圖片大小可能不合適就先將就吧 demo而已
最後總結一下 我們開發中的大多數控件android都是提供的 但是難免會有需求想修改一些地方 文字大小樣式 圖片位置 icon等的一些修改 一般也都是比較小的修改 但是雖然是小修改可以google可不給我們機會 這種情況下要麼照著葫蘆畫瓢重寫一個,但這樣就得花費比較長的時間了,我們還可以用java的工具反射來搞呢,這樣簡單而且有效啊
PS:不得不說反射真是實用啊,以前框架裡經常會用到,現在也是有用武之地啊,就是geiliable
可以顯示在的Android任務,通過加載進度條的進展。進度條有兩種形狀。加載欄和加載微調(spinner)。在本章中,我們將討論微調(spinner)。Spinner 用
1.黑白效果 代碼如下:/** * 將彩色圖轉換為黑白圖 * &n
一、軟鍵盤介紹 實現軟鍵盤主要用到了系統的兩個類:Keyboard和KeyboardView。 Keyboard類源碼的介紹是: Listene
在項目開發中,可能系統自帶的一些widget不能滿足我們的需求,這時就需要自定義View。 通過查看系統中的常用widget如Button,TextView,Ed