志在指尖
用双手敲打未来

Android 控件开发之 ToggleButton 原理原理

Android平台上比拟有特征的就是ToggleButton控件,固然它的功用和CheckBox有些相似,但是他们的用途还是有一定的区别比方ToggleButton本来有图片装饰,经过ToggleButton能够很分明的显现某些状态。它们均从Button为基类的CompoundButton中完成,其真假事情从Checkable来完成。
publicabstractclassCompoundButtonextendsButtonimplementsCheckable{
privatebooleanmChecked;//状态能否选中
privateintmButtonResource;
privatebooleanmBroadcasting;
privateDrawablemButtonDrawable;//按钮的图标
privateOnCheckedChangeListenermOnCheckedChangeListener;//选中状态改动监听Android
privateOnCheckedChangeListenermOnCheckedChangeWidgetListener;
privatestaticfinalint[]CHECKED_STATE_SET={
R.attr.state_checked
};
publicCompoundButton(Contextcontext){
this(context,null);
}
publicCompoundButton(Contextcontext,AttributeSetattrs){
this(context,attrs,0);
}
publicCompoundButton(Contextcontext,AttributeSetattrs,intdefStyle){
super(context,attrs,defStyle);
TypedArraya=context.obtainStyledAttributes(attrs,com.android.internal.R.styleable.CompoundButton,
defStyle,0);
Drawabled=a.getDrawable(com.android.internal.R.styleable.CompoundButton_button);
if(d!=null){
setButtonDrawable(d);
}
booleanchecked=a.getBoolean(com.android.internal.R.styleable.CompoundButton_checked,false);
setChecked(checked);
a.recycle();//显式的GC
}
publicvoidtoggle(){
setChecked(!mChecked);
}
@Override
publicbooleanperformClick(){
toggle();
returnsuper.performClick();
}
publicbooleanisChecked(){
returnmChecked;
}
publicvoidsetChecked(booleanchecked){
if(mChecked!=checked){
mChecked=checked;
refreshDrawableState();//更新当前状态的按钮图标
if(mBroadcasting){
return;
}
mBroadcasting=true;
if(mOnCheckedChangeListener!=null){
mOnCheckedChangeListener.onCheckedChanged(this,mChecked);
}
if(mOnCheckedChangeWidgetListener!=null){
mOnCheckedChangeWidgetListener.onCheckedChanged(this,mChecked);
}
mBroadcasting=false;
}
}
publicvoidsetOnCheckedChangeListener(OnCheckedChangeListenerlistener){
mOnCheckedChangeListener=listener;
}
voidsetOnCheckedChangeWidgetListener(OnCheckedChangeListenerlistener){
mOnCheckedChangeWidgetListener=listener;
}
publicstaticinterfaceOnCheckedChangeListener{
voidonCheckedChanged(CompoundButtonbuttonView,booleanisChecked);
}
publicvoidsetButtonDrawable(intresid){
if(resid!=0&&resid==mButtonResource){
return;
}
mButtonResource=resid;
Drawabled=null;
if(mButtonResource!=0){
d=getResources().getDrawable(mButtonResource);
}
setButtonDrawable(d);
}
publicvoidsetButtonDrawable(Drawabled){
if(d!=null){
if(mButtonDrawable!=null){
mButtonDrawable.setCallback(null);
unscheduleDrawable(mButtonDrawable);
}
d.setCallback(this);
d.setState(getDrawableState());
d.setVisible(getVisibility()==VISIBLE,false);
mButtonDrawable=d;
mButtonDrawable.setState(null);
setMinHeight(mButtonDrawable.getIntrinsicHeight());
}
refreshDrawableState();
}
@Override
publicbooleandispatchPopulateAccessibilityEvent(AccessibilityEventevent){
booleanpopulated=super.dispatchPopulateAccessibilityEvent(event);
if(!populated){
intresourceId=0;
if(mChecked){
resourceId=R.string.accessibility_compound_button_selected;
}else{
resourceId=R.string.accessibility_compound_button_unselected;
}
Stringstate=getResources().getString(resourceId);
event.getText().add(state);
event.setChecked(mChecked);
}
returnpopulated;
}
@Override
protectedvoidonDraw(Canvascanvas){
super.onDraw(canvas);
finalDrawablebuttonDrawable=mButtonDrawable;
if(buttonDrawable!=null){
finalintverticalGravity=getGravity()&Gravity.VERTICAL_GRAVITY_MASK;
finalintheight=buttonDrawable.getIntrinsicHeight();
inty=0;
switch(verticalGravity){
caseGravity.BOTTOM:
y=getHeight()-height;
break;
caseGravity.CENTER_VERTICAL:
y=(getHeight()-height)/2;
break;
}
buttonDrawable.setBounds(0,y,buttonDrawable.getIntrinsicWidth(),y+height);
buttonDrawable.draw(canvas);
}
}
@Override
protectedint[]onCreateDrawableState(intextraSpace){
finalint[]drawableState=super.onCreateDrawableState(extraSpace+1);
if(isChecked()){
mergeDrawableStates(drawableState,CHECKED_STATE_SET);
}
returndrawableState;
}
@Override
protectedvoiddrawableStateChanged(){//android123提示状态改动时需求改换按钮的图标
super.drawableStateChanged();
if(mButtonDrawable!=null){
int[]myDrawableState=getDrawableState();
mButtonDrawable.setState(myDrawableState);
invalidate();
}
}
@Override
protectedbooleanverifyDrawable(Drawablewho){
returnsuper.verifyDrawable(who)||who==mButtonDrawable;
}
staticclassSavedStateextendsBaseSavedState{
booleanchecked;
SavedState(ParcelablesuperState){
super(superState);
}
privateSavedState(Parcelin){
super(in);
checked=(Boolean)in.readValue(null);
}
@Override
publicvoidwriteToParcel(Parcelout,intflags){
super.writeToParcel(out,flags);
out.writeValue(checked);
}
@Override
publicStringtoString(){
return”CompoundButton.SavedState{”
+Integer.toHexString(System.identityHashCode(this))
+”checked=”+checked+”}”;
}
publicstaticfinalParcelable.CreatorCREATOR=newParcelable.Creator(){
publicSavedStatecreateFromParcel(Parcelin){
returnnewSavedState(in);
}
publicSavedState[]newArray(intsize){
returnnewSavedState[size];
}
};
}
@Override
publicParcelableonSaveInstanceState(){
//Forceourancestorclasstosaveitsstate
setFreezesText(true);
ParcelablesuperState=super.onSaveInstanceState();
SavedStatess=newSavedState(superState);
ss.checked=isChecked();
returnss;
}
@Override
publicvoidonRestoreInstanceState(Parcelablestate){
SavedStatess=(SavedState)state;
super.onRestoreInstanceState(ss.getSuperState());
setChecked(ss.checked);
requestLayout();
}
}
从上面来看我们晓得CompuundButton的完成相对繁琐了些,主要是思索状态能否曾经选中等状况的音讯通知,Android
开发网提示大家而ToggleButton相对CompuundButton增加的给用户而言主要是开关的文字显现。
publicclassToggleButtonextendsCompoundButton{
privateCharSequencemTextOn;
privateCharSequencemTextOff;
privateDrawablemIndicatorDrawable;
privatestaticfinalintNO_ALPHA=0xFF;
privatefloatmDisabledAlpha;
publicToggleButton(Contextcontext,AttributeSetattrs,intdefStyle){
super(context,attrs,defStyle);
TypedArraya=context.obtainStyledAttributes(
attrs,com.android.internal.R.styleable.ToggleButton,defStyle,0);
mTextOn=a.getText(com.android.internal.R.styleable.ToggleButton_textOn);
mTextOff=a.getText(com.android.internal.R.styleable.ToggleButton_textOff);
mDisabledAlpha=a.getFloat(com.android.internal.R.styleable.ToggleButton_disabledAlpha,0.5f);
syncTextState();
a.recycle();
}
publicToggleButton(Contextcontext,AttributeSetattrs){
this(context,attrs,com.android.internal.R.attr.buttonStyleToggle);
}
publicToggleButton(Contextcontext){
this(context,null);
}
@Override
publicvoidsetChecked(booleanchecked){
super.setChecked(checked);
syncTextState();
}
privatevoidsyncTextState(){
booleanchecked=isChecked();
if(checked&&mTextOn!=null){
setText(mTextOn);
}elseif(!checked&&mTextOff!=null){
setText(mTextOff);
}
}
publicCharSequencegetTextOn(){
returnmTextOn;
}
publicvoidsetTextOn(CharSequencetextOn){
mTextOn=textOn;
}
publicCharSequencegetTextOff(){
returnmTextOff;
}
protectedvoidonFinishInflate(){
super.onFinishInflate();
updateReferenceToIndicatorDrawable(getBackground());
}
@Override
publicvoidsetBackgroundDrawable(Drawabled){
super.setBackgroundDrawable(d);
updateReferenceToIndicatorDrawable(d);
}
privatevoidupdateReferenceToIndicatorDrawable(DrawablebackgroundDrawable){
if(backgroundDrawableinstanceofLayerDrawable){
LayerDrawablelayerDrawable=(LayerDrawable)backgroundDrawable;
mIndicatorDrawable=layerDrawable.findDrawableByLayerId(com.android.internal.R.id.toggle);
}
}
@Override
protectedvoiddrawableStateChanged(){
super.drawableStateChanged();
if(mIndicatorDrawable!=null){
mIndicatorDrawable.setAlpha(isEnabled()?NO_ALPHA:(int)(NO_ALPHA*mDisabledAlpha));
}
}
}

未经允许不得转载:IT技术网站 » Android 控件开发之 ToggleButton 原理原理
分享到: 更多 (0)

评论 抢沙发

评论前必须登录!

 

志在指尖 用双手敲打未来

登录/注册IT技术大全

热门IT技术

C#基础入门   SQL server数据库   系统SEO学习教程   WordPress小技巧   WordPress插件   脚本与源码下载