源码网商城,靠谱的源码在线交易网站 我的订单 购物车 帮助

源码网商城

android自定义RadioGroup可以添加多种布局的实现方法

  • 时间:2020-10-22 07:12 编辑: 来源: 阅读:
  • 扫一扫,手机访问
摘要:android自定义RadioGroup可以添加多种布局的实现方法
android自带的RadioGroup是继承自LinearLayout,如果布局的时候不是直接写radiobutton,即radiobutton外面还包了一层容器,这时分组是不成功的,因为查找不到radiobutton,如果要实现这种效果呢,于是看了RadioGroup的源码,发现问题在于addView方法和自定义的PassThroughHierarchyChangeListener; 下面就这两个地方动手脚,先拷贝源码,然后去掉RadioGroup(Context context, AttributeSet attrs) 中的方法,我新增了一个方法,查找viewGroup控件中的radioButton
[u]复制代码[/u] 代码如下:
/** 查找radioButton控件 */     public RadioButton findRadioButton(ViewGroup group) {         RadioButton resBtn = null;         int len = group.getChildCount();         for (int i = 0; i < len; i++) {             if (group.getChildAt(i) instanceof RadioButton) {                 resBtn = (RadioButton) group.getChildAt(i);             } else if (group.getChildAt(i) instanceof ViewGroup) {                 findRadioButton((ViewGroup) group.getChildAt(i));             }         }         return resBtn;     }
addView的实现如下:
[u]复制代码[/u] 代码如下:
@Override     public void addView(View child, int index, ViewGroup.LayoutParams params) {         if (child instanceof RadioButton) {             final RadioButton button = (RadioButton) child;             if (button.isChecked()) {                 mProtectFromCheckedChange = true;                 if (mCheckedId != -1) {                     setCheckedStateForView(mCheckedId, false);                 }                 mProtectFromCheckedChange = false;                 setCheckedId(button.getId());             }         } else if (child instanceof ViewGroup) {  //这里是我添加的代码             final RadioButton button = findRadioButton((ViewGroup) child);             if (button.isChecked()) {                 mProtectFromCheckedChange = true;                 if (mCheckedId != -1) {                     setCheckedStateForView(mCheckedId, false);                 }                 mProtectFromCheckedChange = false;                 setCheckedId(button.getId());             }         }         super.addView(child, index, params);     }
然后在自定义的PassThroughHierarchyChangeListener中修改:
[u]复制代码[/u] 代码如下:
private class PassThroughHierarchyChangeListener implements             ViewGroup.OnHierarchyChangeListener {         private ViewGroup.OnHierarchyChangeListener mOnHierarchyChangeListener;         public void onChildViewAdded(View parent, View child) {             if (parent == MyRadioGroup.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);             } else if (parent == MyRadioGroup.this   //这里是我添加的代码                     && child instanceof ViewGroup) {                 RadioButton btn = findRadioButton((ViewGroup) child);                 int id = btn.getId();                 // generates an id if it's missing                 if (id == View.NO_ID) {                     id = btn.hashCode();                     btn.setId(id);                 }                 btn.setOnCheckedChangeListener(mChildOnCheckedChangeListener);             }             if (mOnHierarchyChangeListener != null) {                 mOnHierarchyChangeListener.onChildViewAdded(parent, child);             }         }         public void onChildViewRemoved(View parent, View child) {             if (parent == MyRadioGroup.this && child instanceof RadioButton) {                 ((RadioButton) child).setOnCheckedChangeListener(null);             } else if (parent == MyRadioGroup.this                     && child instanceof ViewGroup) {                 findRadioButton((ViewGroup) child).setOnCheckedChangeListener(                         null);             }             if (mOnHierarchyChangeListener != null) {                 mOnHierarchyChangeListener.onChildViewRemoved(parent, child);             }         }     }
做好了上面的步骤,下面布局就可以按照自己的意思来了,并且分组效果也不会影响 下面我的布局文件demo:
[u]复制代码[/u] 代码如下:
<com.huaheng.wy.view.MyRadioGroup         android:id="@+id/rg"         android:layout_width="fill_parent"         android:layout_height="65dp"         android:layout_alignParentBottom="true"         android:background="@drawable/yst_i_bottom"         android:orientation="horizontal" >         <!-- 首页 -->         <FrameLayout             android:id="@+id/left"             android:layout_width="wrap_content"             android:layout_height="wrap_content"             android:layout_gravity="center_vertical"             android:layout_marginBottom="2dp"             android:layout_marginTop="3dp"             android:layout_weight="1" >             <RadioButton                 android:id="@+id/rbtn_home"                 android:layout_width="wrap_content"                 android:layout_height="wrap_content"                 android:layout_gravity="center"                 android:background="@null"                 android:button="@null"                 android:drawableTop="@drawable/yst_i_bottomhome_selector"                 android:gravity="center_horizontal"                 android:text="首页"                 android:textColor="@color/white"                 android:textSize="@dimen/font_5" />             <Button                 android:id="@+id/btn_home_point"                 android:layout_width="21dp"                 android:layout_height="20dp"                 android:layout_gravity="top|right"                 android:layout_marginRight="10dp"                 android:layout_marginTop="0dp"                 android:background="@drawable/notice_bg"                 android:text="1"                 android:textColor="@color/white"                 android:textSize="@dimen/font_6"                 android:visibility="gone" />         </FrameLayout>         <!-- 历史 -->         <RadioButton             android:id="@+id/rbtn_his"             android:layout_width="wrap_content"             android:layout_height="wrap_content"             android:layout_gravity="center_vertical"             android:layout_marginBottom="2dp"             android:layout_marginTop="3dp"             android:layout_weight="1"             android:background="@null"             android:button="@null"             android:drawableTop="@drawable/yst_i_bottomhis_selector"             android:gravity="center_horizontal"             android:text="历史"             android:textColor="@color/white"             android:textSize="@dimen/font_5" />         <!-- 扫描 -->         <Button             android:id="@+id/rbtn_scan"             android:layout_width="wrap_content"             android:layout_height="wrap_content"             android:layout_gravity="center_vertical"             android:background="@drawable/scan_selector"             android:button="@null"             android:gravity="center_horizontal|bottom"             android:paddingBottom="7dp"             android:text="扫描"             android:textColor="@color/white"             android:textSize="@dimen/font_5" />         <RadioButton             android:id="@+id/rbtn_seek"             android:layout_width="wrap_content"             android:layout_height="wrap_content"             android:layout_gravity="center_vertical"             android:layout_marginBottom="2dp"             android:layout_marginTop="3dp"             android:layout_weight="1"             android:background="@null"             android:button="@null"             android:drawableTop="@drawable/yst_i_bottomseek_selector"             android:gravity="center_horizontal"             android:text="搜索"             android:textColor="@color/white"             android:textSize="@dimen/font_5" />         <RadioButton             android:id="@+id/rbtn_more"             android:layout_width="wrap_content"             android:layout_height="wrap_content"             android:layout_gravity="center_vertical"             android:layout_marginBottom="2dp"             android:layout_marginTop="3dp"             android:layout_weight="1"             android:background="@null"             android:button="@null"             android:drawableTop="@drawable/yst_i_bottommore_selector"             android:gravity="center_horizontal"             android:text="更多"             android:textColor="@color/white"             android:textSize="@dimen/font_5" />     </com.huaheng.wy.view.MyRadioGroup>
所有实现代码都在这里,下面我就把自定义的radioGroup的代码,完整的贴出来
[u]复制代码[/u] 代码如下:
/*  * Copyright (C) 2006 The Android Open Source Project  *  * Licensed under the Apache License, Version 2.0 (the "License");  * you may not use this file except in compliance with the License.  * You may obtain a copy of the License at  *  *      http://www.apache.org/licenses/LICENSE-2.0  *  * Unless required by applicable law or agreed to in writing, software  * distributed under the License is distributed on an "AS IS" BASIS,  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  * See the License for the specific language governing permissions and  * limitations under the License.  */ package com.huaheng.wy.view; import android.content.Context; import android.content.res.TypedArray; import android.util.AttributeSet; import android.view.View; import android.view.ViewGroup; import android.widget.CompoundButton; import android.widget.LinearLayout; import android.widget.RadioButton; public class MyRadioGroup 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;     public MyRadioGroup(Context context) {         super(context);         setOrientation(VERTICAL);         init();     }     public MyRadioGroup(Context context, AttributeSet attrs) {         super(context, attrs);         init();     }     private void init() {         mChildOnCheckedChangeListener = new CheckedStateTracker();         mPassThroughListener = new PassThroughHierarchyChangeListener();         super.setOnHierarchyChangeListener(mPassThroughListener);     }     @Override     public void setOnHierarchyChangeListener(OnHierarchyChangeListener listener) {         // the user listener is delegated to our pass-through listener         mPassThroughListener.mOnHierarchyChangeListener = listener;     }     @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(View child, int index, ViewGroup.LayoutParams params) {         if (child instanceof RadioButton) {             final RadioButton button = (RadioButton) child;             if (button.isChecked()) {                 mProtectFromCheckedChange = true;                 if (mCheckedId != -1) {                     setCheckedStateForView(mCheckedId, false);                 }                 mProtectFromCheckedChange = false;                 setCheckedId(button.getId());             }         } else if (child instanceof ViewGroup) {             final RadioButton button = findRadioButton((ViewGroup) child);             if (button.isChecked()) {                 mProtectFromCheckedChange = true;                 if (mCheckedId != -1) {                     setCheckedStateForView(mCheckedId, false);                 }                 mProtectFromCheckedChange = false;                 setCheckedId(button.getId());             }         }         super.addView(child, index, params);     }     /** 查找radioButton控件 */     public RadioButton findRadioButton(ViewGroup group) {         RadioButton resBtn = null;         int len = group.getChildCount();         for (int i = 0; i < len; i++) {             if (group.getChildAt(i) instanceof RadioButton) {                 resBtn = (RadioButton) group.getChildAt(i);             } else if (group.getChildAt(i) instanceof ViewGroup) {                 findRadioButton((ViewGroup) group.getChildAt(i));             }         }         return resBtn;     }     /**      * <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;         if (mOnCheckedChangeListener != null) {             mOnCheckedChangeListener.onCheckedChanged(this, mCheckedId);         }     }     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      *      * @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 MyRadioGroup.LayoutParams(getContext(), attrs);     }     /**      * {@inheritDoc}      */     @Override     protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {         return p instanceof MyRadioGroup.LayoutParams;     }     @Override     protected LinearLayout.LayoutParams generateDefaultLayoutParams() {         return new LayoutParams(LayoutParams.WRAP_CONTENT,                 LayoutParams.WRAP_CONTENT);     }     /**      * <p>      * This set of layout parameters defaults the width and the height of the      * children to {@link #WRAP_CONTENT} when they are not specified in the XML      * file. Otherwise, this class ussed the value read from the XML file.      * </p>      *      * <p>      * See {@link android.R.styleable#LinearLayout_Layout LinearLayout      * Attributes} for a list of all child view attributes that this class      * supports.      * </p>      *      */     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          */         public void onCheckedChanged(MyRadioGroup 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;         public void onChildViewAdded(View parent, View child) {             if (parent == MyRadioGroup.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);             } else if (parent == MyRadioGroup.this                     && child instanceof ViewGroup) {                 RadioButton btn = findRadioButton((ViewGroup) child);                 int id = btn.getId();                 // generates an id if it's missing                 if (id == View.NO_ID) {                     id = btn.hashCode();                     btn.setId(id);                 }                 btn.setOnCheckedChangeListener(mChildOnCheckedChangeListener);             }             if (mOnHierarchyChangeListener != null) {                 mOnHierarchyChangeListener.onChildViewAdded(parent, child);             }         }         public void onChildViewRemoved(View parent, View child) {             if (parent == MyRadioGroup.this && child instanceof RadioButton) {                 ((RadioButton) child).setOnCheckedChangeListener(null);             } else if (parent == MyRadioGroup.this                     && child instanceof ViewGroup) {                 findRadioButton((ViewGroup) child).setOnCheckedChangeListener(                         null);             }             if (mOnHierarchyChangeListener != null) {                 mOnHierarchyChangeListener.onChildViewRemoved(parent, child);             }         }     } }
  • 全部评论(0)
联系客服
客服电话:
400-000-3129
微信版

扫一扫进微信版
返回顶部