具有嵌套线性布局的Android无线电组不会取消选择无线电按钮

时间:2017-03-08 07:41:34

标签: android radio-button radio-group

我在放射线组中有一组放射线按钮,它们拒绝按照我喜欢的方式行事。 radiobuttons需要是两行两行,一行一行,最后一个按钮具有edittext而不是标签。布局看起来正确,但无线电按钮允许选择多个并且不会取消选择任何一个。 以下是我的XML:

    <RadioGroup
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/rgDesignation">

    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/llVT1">

        <RadioButton
            android:text="@string/pressure_equipment"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/rbPE"
            android:layout_weight="1" />

        <RadioButton
            android:text="@string/assemblies"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/rbAss"
            android:layout_weight="1" />
    </LinearLayout>

    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/llVT2">

        <RadioButton
            android:text="@string/unheated"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/rbUnh"
            android:layout_weight="1" />

        <RadioButton
            android:text="@string/heated"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/rbH"
            android:layout_weight="1" />

    </LinearLayout>

    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:id="@+id/llVT3">

        <RadioButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/rbOwnSel"
            android:layout_weight="0" />

        <EditText
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:inputType="text"
            android:ems="10"
            android:id="@+id/etOwnChoice"
            android:layout_weight="1"
            android:textColor="@android:color/black"
            android:background="@android:color/white"
            android:elevation="5dp" />
    </LinearLayout>

    </RadioGroup>

1 个答案:

答案 0 :(得分:0)

按照以下方式制作自定义RadioGroup类:

public class RadioGroup extends LinearLayout {

private int mCheckedId = -1;

private CompoundButton.OnCheckedChangeListener mChildOnCheckedChangeListener;

private boolean mProtectFromCheckedChange = false;
private OnCheckedChangeListener mOnCheckedChangeListener;
private PassThroughHierarchyChangeListener mPassThroughListener;


public RadioGroup(Context context) {
    super(context);
    setOrientation(VERTICAL);
    init();
}


public RadioGroup(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) {

    mPassThroughListener.mOnHierarchyChangeListener = listener;
}

@Override
protected void onFinishInflate() {
    super.onFinishInflate();


    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());
        }
    }

    super.addView(child, index, params);
}


public void check(@IdRes 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(@IdRes 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);
    }
}


@IdRes
public int getCheckedRadioButtonId() {
    return mCheckedId;
}


public void clearCheck() {
    check(-1);
}


public void setOnCheckedChangeListener(OnCheckedChangeListener listener) {
    mOnCheckedChangeListener = listener;
}


@Override
public LayoutParams generateLayoutParams(AttributeSet attrs) {
    return new LayoutParams(getContext(), attrs);
}

@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 CharSequence getAccessibilityClassName() {
    return RadioGroup.class.getName();
}


public static class LayoutParams extends LinearLayout.LayoutParams {

    public LayoutParams(Context c, AttributeSet attrs) {
        super(c, attrs);
    }


    public LayoutParams(int w, int h) {
        super(w, h);
    }


    public LayoutParams(int w, int h, float initWeight) {
        super(w, h, initWeight);
    }


    public LayoutParams(ViewGroup.LayoutParams p) {
        super(p);
    }


    public LayoutParams(MarginLayoutParams source) {
        super(source);
    }


    @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;
        }
    }
}


    public void onCheckedChanged(RadioGroup group, @IdRes 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);
    }
}


private class PassThroughHierarchyChangeListener implements
        ViewGroup.OnHierarchyChangeListener {
    private ViewGroup.OnHierarchyChangeListener mOnHierarchyChangeListener;

    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1)
    public void traverseTree(View view) {
        if (view instanceof RadioButton) {
            int id = view.getId();
            // generates an id if it's missing
            if (id == View.NO_ID) {
                id = View.generateViewId();
                view.setId(id);
            }
            ((RadioButton) view).setOnCheckedChangeListener(
                    mChildOnCheckedChangeListener);
        }
        if (!(view instanceof ViewGroup)) {
            return;
        }
        ViewGroup viewGroup = (ViewGroup) view;
        if (viewGroup.getChildCount() == 0) {
            return;
        }
        for (int i = 0; i < viewGroup.getChildCount(); i++) {
            traverseTree(viewGroup.getChildAt(i));
        }
    }

    /**
     * {@inheritDoc}
     */
    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1)
    public void onChildViewAdded(View parent, View child) {
        traverseTree(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 = View.generateViewId();
                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);
        }
    }
}

}

并添加如下布局:

 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="@dimen/activity_vertical_margin"
>

<com.example.admin.myapplication.RadioGroup
    android:id="@+id/radio_group_plus"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="60dp">

        <RadioButton
            android:id="@+id/rb_latte"
            android:text="radio1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_centerVertical="true" />

        <RadioButton
            android:text="radio2"
            android:id="@+id/rb_latte1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true" />
    </RelativeLayout>

    <View
        android:layout_width="match_parent"
        android:layout_height="2dp"
        android:background="#E0E0E0" />

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="60dp">

        <ImageView
            android:id="@+id/iv_mocha"
            android:layout_width="40dp"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:src="@mipmap/ic_launcher" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:layout_toRightOf="@+id/iv_mocha"
            android:paddingLeft="20dp"
            android:text="Mocha" />

        <RadioButton
            android:id="@+id/rb_mocha"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true" />
    </RelativeLayout>

    <View
        android:layout_width="match_parent"
        android:layout_height="2dp"
        android:background="#E0E0E0" />

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="60dp">

        <ImageView
            android:id="@+id/iv_americano"
            android:layout_width="40dp"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:src="@mipmap/ic_launcher" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:layout_toRightOf="@+id/iv_americano"
            android:paddingLeft="20dp"
            android:text="Americano" />

        <RadioButton
            android:id="@+id/rb_americano"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true" />
    </RelativeLayout>

    <View
        android:layout_width="match_parent"
        android:layout_height="2dp"
        android:background="#E0E0E0" />

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="60dp">

        <ImageView
            android:id="@+id/iv_espresso"
            android:layout_width="40dp"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:src="@mipmap/ic_launcher" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:layout_toRightOf="@+id/iv_espresso"
            android:paddingLeft="20dp"
            android:text="Espresso" />

        <RadioButton
            android:id="@+id/rb_espresso"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true" />
    </RelativeLayout>

    <View
        android:layout_width="match_parent"
        android:layout_height="2dp"
        android:background="#E0E0E0" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:orientation="horizontal">

        <RelativeLayout
            android:layout_width="0dp"
            android:layout_height="60dp"
            android:layout_weight="1">

            <ImageView
                android:id="@+id/iv_orange"
                android:layout_width="40dp"
                android:layout_height="wrap_content"
                android:layout_alignParentLeft="true"
                android:src="@mipmap/ic_launcher" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerVertical="true"
                android:layout_toRightOf="@+id/iv_orange"
                android:paddingLeft="20dp"
                android:text="Orange" />

            <RadioButton
                android:id="@+id/rb_orange"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentRight="true"
                android:layout_centerVertical="true" />
        </RelativeLayout>

        <View
            android:layout_width="2dp"
            android:layout_height="wrap_content"
            android:layout_marginBottom="10dp"
            android:layout_marginTop="10dp"
            android:background="#E0E0E0" />

        <RelativeLayout
            android:layout_width="0dp"
            android:layout_height="60dp"
            android:layout_weight="1"
            android:paddingLeft="10dp">

            <ImageView
                android:id="@+id/iv_butter"
                android:layout_width="40dp"
                android:layout_height="wrap_content"
                android:layout_alignParentLeft="true"
                android:src="@mipmap/ic_launcher" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerVertical="true"
                android:layout_toRightOf="@+id/iv_butter"
                android:paddingLeft="20dp"
                android:text="Butter" />

            <RadioButton
                android:id="@+id/rb_butter"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentRight="true"
                android:layout_centerVertical="true" />
        </RelativeLayout>
    </LinearLayout>

</com.example.admin.myapplication.RadioGroup>

<Button
    android:layout_width="wrap_content"
    android:layout_height="48dp"
    android:layout_gravity="center"
    android:layout_marginTop="20dp"
    android:background="#138BE8"
    android:gravity="center"
    android:onClick="onOrderClicked"
    android:paddingLeft="20dp"
    android:paddingRight="20dp"
    android:text="Order Drink"
    android:textColor="@android:color/white" />