RadioButton drawableTop背景自適應(yīng),Context轉(zhuǎn)Activity(解釋Context)

效果圖如下:


以下適當(dāng)?shù)男薷木涂梢允褂?/p>

package net.ossrs.yasea.demo.Activity.Uitls;

import android.app.Activity;

import android.content.Context;

import android.content.ContextWrapper;

import android.graphics.Rect;

import android.graphics.drawable.Drawable;

import android.widget.RadioButton;

public class RadioButtonUtil

{

private? RadioButton[]rb;

private Drawable[]drawables;

/**

* 圖片要縮小的比例molecule:Denominator

? ? * @param rbid

? ? * @param context

? ? * @param molecule

? ? * @param Denominator

? ? */

? ? public RadioButtonUtil(int[] rbid, Context context,int molecule,int Denominator)

{

//定義RadioButton數(shù)組用來裝RadioButton,改變drawableTop大小

? ? ? ? rb =new RadioButton[rbid.length];

//將RadioButton裝進數(shù)組中

? ? ? ? for (int i=0;i

{

int rb_id=rbid[i];

//? ? ? ? ? View view=LayoutInflater.from(context).inflate(viewId,null);

? ? ? ? ? ? try {

rb[i] = (RadioButton)getActivity(context).findViewById(rb_id);

}catch (Exception e) {

e.printStackTrace();

}

}

//for循環(huán)對每一個RadioButton圖片進行縮放

? ? ? ? for (int i =0; i

{

//挨著給每個RadioButton加入drawable限制邊距以控制顯示大小

? ? ? ? ? ? drawables =rb[i].getCompoundDrawables();

//獲取drawables

? ? ? ? ? ? Rect r =new Rect(0,0,drawables[1].getMinimumWidth() * molecule / Denominator,

drawables[1].getMinimumHeight() * molecule / Denominator);

//定義一個Rect邊界

? ? ? ? ? ? drawables[1].setBounds(r);

//給每一個RadioButton設(shè)置圖片大小

? ? ? ? ? ? rb[i].setCompoundDrawables(null,drawables[1],null,null);

}

}

private Activity getActivity(Context context)throws Exception {

while (!(contextinstanceof Activity) && contextinstanceof ContextWrapper) {

context = ((ContextWrapper) context).getBaseContext();

}

if (contextinstanceof Activity)

{

return (Activity) context;

}

throw new? Exception("Unable to get Activity.");

}

}

傳入四個參數(shù):/**

* 圖片要縮小的比例molecule:Denominator

* @param rbid

* @param context

* @param molecule

* @param Denominator

*/

這些注釋里叫的也相對明白。所以就不多解釋了,context轉(zhuǎn)activity涉及到的東西蠻多的。

Android應(yīng)用模型是基于組件的應(yīng)用設(shè)計模式,組件的運行要有一個完整的Android工程環(huán)境,在

這個環(huán)境下,Activity、Service等系統(tǒng)組件才能夠正常工作,而這些組件并不能采用普通的Java對象

創(chuàng)建方式,new一下就能創(chuàng)建實例了,而是要有它們各自的上下文環(huán)境,也就是我們的Context。


context部分截圖


源碼中的注釋是這么來解釋Context的:Context提供了關(guān)于應(yīng)用環(huán)境全局信息的接口。它是一個抽象類,

它的執(zhí)行被Android系統(tǒng)所提供。它允許獲取以應(yīng)用為特征的資源和類型,是一個統(tǒng)領(lǐng)一些資源(應(yīng)用程序環(huán)境變量等)

的上下文。就是說,它描述一個應(yīng)用程序環(huán)境的信息(即上下文);是一個抽象類,

Android提供了該抽象類的具體實現(xiàn)類;通過它我們可以獲取應(yīng)用程序的資源和類

(包括應(yīng)用級別操作,如啟動Activity,發(fā)廣播,接受Intent等)。



context


Context類本身是一個純abstract類,它有兩個具體的實現(xiàn)子類:ContextImpl和ContextWrapper

一個負責(zé)實現(xiàn)一個負責(zé)包裝

Activity,Application,Service雖都繼承自ContextWrapper

(Activity繼承自ContextWrapper的子類ContextThemeWrapper),

但它們初始化的過程中都會創(chuàng)建ContextImpl對象,由ContextImpl實現(xiàn)Context中的方法。

在應(yīng)用程序中Context的具體實現(xiàn)子類就是:Activity,Service,Application。那么Context數(shù)量=Activity數(shù)量+Service數(shù)量+1。

當(dāng)然如果你足夠細心,可能會有疑問:我們常說四大組件,這里怎么只有Activity,Service持有Context,那Broadcast Receiver,

Content Provider呢?Broadcast Receiver,Content Provider并不是Context的子類,他們所持有的Context都是其他地方傳過去的,

所以并不計入Context總數(shù)。上面的關(guān)系圖也從另外一個側(cè)面告訴我們Context類在整個Android系統(tǒng)中的地位是多么的崇高,

因為很顯然Activity,Service,Application都是其子類,其地位和作用不言而喻。爸比一樣的存在!

因此在絕大多數(shù)場景下,Activity、Service和Application這三種類型的Context都是可以通用的。

不過有幾種場景比較特殊,比如啟動Activity,還有彈出Dialog。


通常我們想要獲取Context對象,主要有以下四種方法

1:View.getContext,返回當(dāng)前View對象的Context對象,通常是當(dāng)前正在展示的Activity對象。

2:Activity.getApplicationContext,獲取當(dāng)前Activity所在的(應(yīng)用)進程的Context對象,通常我們使用Context對象時,要優(yōu)先考慮這個全局的進程Context。

3:ContextWrapper.getBaseContext():用來獲取一個ContextWrapper進行裝飾之前的Context,可以使用這個方法,這個方法在實際開發(fā)中使用并不多,也不建議使用。

4:Activity.this 返回當(dāng)前的Activity實例,如果是UI控件需要使用Activity作為Context對象,但是默認的Toast實際上使用ApplicationContext也可以。

上面說到獲取當(dāng)前Application對象用getApplicationContext,不知道你有沒有聯(lián)想到getApplication(),這兩個方法有什么區(qū)別?相信這個問題會難倒不少開發(fā)者。

Application本身就是一個Context,所以這里獲取getApplicationContext()得到的結(jié)果就是Application本身的實例。那么問題來了,

既然這兩個方法得到的結(jié)果都是相同的,那么Android為什么要提供兩個功能重復(fù)的方法呢?實際上這兩個方法在作用域上有比較大的區(qū)別。

getApplication()方法的語義性非常強,一看就知道是用來獲取Application實例的,但是這個方法只有在Activity和Service中才能調(diào)用的到。

那么也許在絕大多數(shù)情況下我們都是在Activity或者Service中使用Application的,但是如果在一些其它的場景,

比如BroadcastReceiver中也想獲得Application的實例,這時就可以借助getApplicationContext()方法了。


但Context并不能隨便亂用,用的不好有可能會引起內(nèi)存泄露的問題

1:當(dāng)Application的Context能搞定的情況下,并且生命周期長的對象,優(yōu)先使用Application的Context。

2:不要讓生命周期長于Activity的對象持有到Activity的引用。

3:盡量不要在Activity中使用非靜態(tài)內(nèi)部類,因為非靜態(tài)內(nèi)部類會隱式持有外部類實例的引用,如果使用靜態(tài)內(nèi)部類,將外部實例引用作為弱引用持有

總之Context在Android系統(tǒng)中的地位很重要,它幾乎無所不能,但它也不是你想用就能隨便用的,謹防使用不當(dāng)引起的內(nèi)存問題。

(總結(jié):使用前需要清楚應(yīng)用的對象的生命周期,否則就才采用 軟引用 SoftReference,弱引用 WeakReference,虛引用 PhantomReference,這種·可以被GC掉引用)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容