Android Widget添加自訂控制項

來源:互聯網
上載者:User

首先看一個引用:

ARemoteViews object (and, consequently, an App Widget) can support thefollowing layout classes:

*FrameLayout

*LinearLayout

*RelativeLayout

 

Andthe following widget classes:

 

*AnalogClock

*Button

*Chronometer

*ImageButton

*ImageView

*ProgressBar

*TextView

Descendantsof these classes are not supported.

 

可見我們widget裡面可以使用的控制項只有:AnalogClock,Button,Chronometer,ImageButton,mageView,ProgressBar,TextView這7種,Listview,Editview,Scrollview等這些很常用的控制項都無法在我們的Widget中使用。而其實這所有的控制項的源碼都是放在framework/base/core/java/android/widget這個目錄下的,這7種控制項之所以可用是因為加了@RemoteView這個標籤,我們可以看一下源碼:

AnalogClock.java:39:@RemoteView

AnalogClock.java-40-publicclass AnalogClock extends View {


ImageButton.java:66:@RemoteView

ImageButton.java-67-publicclass ImageButton extends ImageView {

…..

 

所以我們想要在widget中使用諸如Listview這樣的控制項的話,需要自己寫一個和Listview一模一樣的類,加上@RemoteView標籤,並拷貝到framework/base/core/java/android/widget這個目錄下。

然後我們就可以在Widget中使用我們寫的這個控制項了,由於他和其他可用控制項一樣都有@RemoteView標籤,那麼他也就能被RemoteView對象所識別了。

 

既然原理我們已經知道了,那麼可以按下面的步驟實現(以我自訂一個AnalogClock為例):

 

 

 

1.首先我完完整整的拷貝了源碼中的AnalogClock.java命名為MyClock.java到framework/base/core/java/android/widget這個目錄下,然後按自己的需求修改了代碼。

 

 

2.這個MyClock.java用到的資源檔必須存放在frameworks/base/core/res/res目錄下。而且必須是這樣的方式引用:com.android.internal.R.drawable.*

不過如果這樣做的話更換資源不太方便,我們知道每個系統控制項都有個style檔案,所以我的做法是:

 

 

先看系統的AnalogClock.java的style源檔案:

frameworks/base/core/res/res/values/attrs.xml:

<declare-styleable name="AnalogClock">

<!-省去部分代碼->

<attrname="hand_minute"format="reference"/>

</declare-styleable>

 

private Drawable mMinuteHand;

public MyClock(Context context, AttributeSet attrs, intdefStyle) {

super(context,attrs, defStyle);

Resources r = context.getResources();


TypedArray a = context.obtainStyledAttributes(attrs,com.android.internal.R.styleable.AnalogClock,defStyle,0);

mMinuteHand = a.getDrawable(com.android.internal.R.styleable.AnalogClock_hand_minute);//這裡就是調用attrs.xml裡的參數


if(mMinuteHand== null){

mMinuteHand= r.getDrawable(com.android.internal.R.drawable.clock_hand_minute);//而這裡是調用系統frameworks/base/core/res/res目錄下的資源

}


}

我自己在widget的布局設定檔裡面定義:

<MyClock

xmlns:android="http://schemas.android.com/apk/res/android"

android:id="@+id/rl_widget_clockView"

<!-省去部分代碼->

android:hand_minute="@drawable/minute_white"//這裡就是引用本地drawable下的資源

android:layout_width="80dp"

android:layout_height="80dp"

/>

這一塊比較繞。。我也是反覆編譯源碼測試才成功。

 

 

3.這個時候基本上工作已經完成一大半了,我們需要編譯整個SDK。但是注意,我在編譯過程中出現了各種編譯錯誤,而且提示都是unknown,十分讓人費解,最終我總結出一套成功率極高編譯方法。

先在根目錄make-j4編譯整個純淨的源碼(注意不要添加任何我們自己定義的類和資源),大約1-2小時成功編譯結束後,再把我們自訂的類和資源等拷貝到framework下,再一次在根目錄make-j4編譯。

如果要測試我們添加的代碼,需要在全部編譯成功後,執行emulator命令啟動一個新編出的模擬器,然後在上面安裝我們的APK。

基本上已經大告成功了,也許還遺漏了一些瑣碎的問題,可以和我討論。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.