Android自定义View之RadioGroup实现跨多行显示
程序员文章站
2023-10-31 09:04:28
本文实例为大家分享了android radiogroup跨多行显示的具体代码,供大家参考,具体内容如下
此自定义view源于网络,具体出处不详。
import androi...
本文实例为大家分享了android radiogroup跨多行显示的具体代码,供大家参考,具体内容如下
此自定义view源于网络,具体出处不详。
import android.content.context; import android.content.res.typedarray; import android.util.attributeset; import android.view.motionevent; import android.view.view; import android.view.viewgroup; import android.view.accessibility.accessibilityevent; import android.view.accessibility.accessibilitynodeinfo; import android.widget.compoundbutton; import android.widget.linearlayout; import android.widget.radiobutton; public class radiogroup extends linearlayout { // holds the checked id; the selection is empty by default private int mcheckedid = -1; // tracks children radio buttons checked state private compoundbutton.oncheckedchangelistener mchildoncheckedchangelistener; // when true, moncheckedchangelistener discards events private boolean mprotectfromcheckedchange = false; private oncheckedchangelistener moncheckedchangelistener; private passthroughhierarchychangelistener mpassthroughlistener; /** * {@inheritdoc} */ public radiogroup(context context) { super(context); setorientation(vertical); init(); } /** * {@inheritdoc} */ public radiogroup(context context, attributeset attrs) { super(context, attrs); mcheckedid = view.no_id; final int index = vertical; setorientation(index); init(); } private void init() { mchildoncheckedchangelistener = new checkedstatetracker(); mpassthroughlistener = new passthroughhierarchychangelistener(); super.setonhierarchychangelistener(mpassthroughlistener); } /** * {@inheritdoc} */ @override public void setonhierarchychangelistener(onhierarchychangelistener listener) { // the user listener is delegated to our pass-through listener mpassthroughlistener.monhierarchychangelistener = listener; } /** * {@inheritdoc} */ @override protected void onfinishinflate() { super.onfinishinflate(); // checks the appropriate radio button as requested in the xml file if (mcheckedid != -1) { mprotectfromcheckedchange = true; setcheckedstateforview(mcheckedid, true); mprotectfromcheckedchange = false; setcheckedid(mcheckedid); } } @override public void addview(final view child, int index, viewgroup.layoutparams params) { if (child instanceof radiobutton) { child.setontouchlistener(new ontouchlistener() { @override public boolean ontouch(view v, motionevent event) { ((radiobutton) child).setchecked(true); checkradiobutton((radiobutton) child); if (moncheckedchangelistener != null) { moncheckedchangelistener.oncheckedchanged(radiogroup.this, child.getid()); } return true; } }); } else if (child instanceof linearlayout) { int childcount = ((linearlayout) child).getchildcount(); for (int i = 0; i < childcount; i++) { view view = ((linearlayout) child).getchildat(i); if (view instanceof radiobutton) { final radiobutton button = (radiobutton) view; button.setontouchlistener(new ontouchlistener() { @override public boolean ontouch(view v, motionevent event) { button.setchecked(true); checkradiobutton(button); if (moncheckedchangelistener != null) { moncheckedchangelistener.oncheckedchanged(radiogroup.this, button.getid()); } return true; } }); } } } super.addview(child, index, params); } private void checkradiobutton(radiobutton radiobutton) { view child; int radiocount = getchildcount(); for (int i = 0; i < radiocount; i++) { child = getchildat(i); if (child instanceof radiobutton) { if (child == radiobutton) { // do nothing } else { ((radiobutton) child).setchecked(false); } } else if (child instanceof linearlayout) { int childcount = ((linearlayout) child).getchildcount(); for (int j = 0; j < childcount; j++) { view view = ((linearlayout) child).getchildat(j); if (view instanceof radiobutton) { final radiobutton button = (radiobutton) view; if (button == radiobutton) { // do nothing } else { button.setchecked(false); } } } } } } /** * <p>sets the selection to the radio button whose identifier is passed in * parameter. using -1 as the selection identifier clears the selection; * such an operation is equivalent to invoking {@link #clearcheck()}.</p> * * @param id the unique id of the radio button to select in this group * @see #getcheckedradiobuttonid() * @see #clearcheck() */ public void check(int id) { // don't even bother if (id != -1 && (id == mcheckedid)) { return; } if (mcheckedid != -1) { setcheckedstateforview(mcheckedid, false); } if (id != -1) { setcheckedstateforview(id, true); } setcheckedid(id); } private void setcheckedid(int id) { mcheckedid = id; } private void setcheckedstateforview(int viewid, boolean checked) { view checkedview = findviewbyid(viewid); if (checkedview != null && checkedview instanceof radiobutton) { ((radiobutton) checkedview).setchecked(checked); } } /** * <p>returns the identifier of the selected radio button in this group. * upon empty selection, the returned value is -1.</p> * * @return the unique id of the selected radio button in this group * @attr ref android.r.styleable#radiogroup_checkedbutton * @see #check(int) * @see #clearcheck() */ public int getcheckedradiobuttonid() { return mcheckedid; } /** * <p>clears the selection. when the selection is cleared, no radio button * in this group is selected and {@link #getcheckedradiobuttonid()} returns * null.</p> * * @see #check(int) * @see #getcheckedradiobuttonid() */ public void clearcheck() { check(-1); } /** * <p>register a callback to be invoked when the checked radio button * changes in this group.</p> * * @param listener the callback to call on checked state change */ public void setoncheckedchangelistener(oncheckedchangelistener listener) { moncheckedchangelistener = listener; } /** * {@inheritdoc} */ @override public layoutparams generatelayoutparams(attributeset attrs) { return new radiogroup.layoutparams(getcontext(), attrs); } /** * {@inheritdoc} */ @override protected boolean checklayoutparams(viewgroup.layoutparams p) { return p instanceof radiogroup.layoutparams; } @override protected linearlayout.layoutparams generatedefaultlayoutparams() { return new layoutparams(layoutparams.wrap_content, layoutparams.wrap_content); } @override public void oninitializeaccessibilityevent(accessibilityevent event) { super.oninitializeaccessibilityevent(event); event.setclassname(radiogroup.class.getname()); } @override public void oninitializeaccessibilitynodeinfo(accessibilitynodeinfo info) { super.oninitializeaccessibilitynodeinfo(info); info.setclassname(radiogroup.class.getname()); } public static class layoutparams extends linearlayout.layoutparams { /** * {@inheritdoc} */ public layoutparams(context c, attributeset attrs) { super(c, attrs); } /** * {@inheritdoc} */ public layoutparams(int w, int h) { super(w, h); } /** * {@inheritdoc} */ public layoutparams(int w, int h, float initweight) { super(w, h, initweight); } /** * {@inheritdoc} */ public layoutparams(viewgroup.layoutparams p) { super(p); } /** * {@inheritdoc} */ public layoutparams(marginlayoutparams source) { super(source); } /** * <p>fixes the child's width to * {@link android.view.viewgroup.layoutparams#wrap_content} and the child's * height to {@link android.view.viewgroup.layoutparams#wrap_content} * when not specified in the xml file.</p> * * @param a the styled attributes set * @param widthattr the width attribute to fetch * @param heightattr the height attribute to fetch */ @override protected void setbaseattributes(typedarray a, int widthattr, int heightattr) { if (a.hasvalue(widthattr)) { width = a.getlayoutdimension(widthattr, "layout_width"); } else { width = wrap_content; } if (a.hasvalue(heightattr)) { height = a.getlayoutdimension(heightattr, "layout_height"); } else { height = wrap_content; } } } /** * <p>interface definition for a callback to be invoked when the checked * radio button changed in this group.</p> */ public interface oncheckedchangelistener { /** * <p>called when the checked radio button has changed. when the * selection is cleared, checkedid is -1.</p> * * @param group the group in which the checked radio button has changed * @param checkedid the unique identifier of the newly checked radio button */ void oncheckedchanged(radiogroup group, int checkedid); } private class checkedstatetracker implements compoundbutton.oncheckedchangelistener { public void oncheckedchanged(compoundbutton buttonview, boolean ischecked) { // prevents from infinite recursion if (mprotectfromcheckedchange) { return; } mprotectfromcheckedchange = true; if (mcheckedid != -1) { setcheckedstateforview(mcheckedid, false); } mprotectfromcheckedchange = false; int id = buttonview.getid(); setcheckedid(id); } } /** * <p>a pass-through listener acts upon the events and dispatches them * to another listener. this allows the table layout to set its own internal * hierarchy change listener without preventing the user to setup his.</p> */ private class passthroughhierarchychangelistener implements viewgroup.onhierarchychangelistener { private viewgroup.onhierarchychangelistener monhierarchychangelistener; /** * {@inheritdoc} */ public void onchildviewadded(view parent, view child) { if (parent == radiogroup.this && child instanceof radiobutton) { int id = child.getid(); // generates an id if it's missing if (id == view.no_id) { id = child.hashcode(); child.setid(id); } ((radiobutton) child).setoncheckedchangelistener(mchildoncheckedchangelistener); } if (monhierarchychangelistener != null) { monhierarchychangelistener.onchildviewadded(parent, child); } } /** * {@inheritdoc} */ public void onchildviewremoved(view parent, view child) { if (parent == radiogroup.this && child instanceof radiobutton) { ((radiobutton) child).setoncheckedchangelistener(null); } if (monhierarchychangelistener != null) { monhierarchychangelistener.onchildviewremoved(parent, child); } } } }
使用:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
上一篇: 还原访问网页的全过程
推荐阅读
-
Android自定义View之RadioGroup实现跨多行显示
-
Android自定义View实现地铁显示牌效果
-
Android 自定义View实现任意布局的RadioGroup效果
-
Android开发之自定义view实现通讯录列表A~Z字母提示效果【附demo源码下载】
-
Android自定义view之围棋动画效果的实现
-
Android自定义view之太极图的实现教程
-
Android中使用自定义View实现下载进度的显示
-
Android 自定义View系列之贝塞尔曲线+QQ未读消息拖拽效果实现+水波浪充电效果
-
Android深入探究自定义View之嵌套滑动的实现
-
Android自定义View之RadioGroup实现跨多行显示