You can use a layerlist in xml drawable such that you set both the xml background and image as you exactly need then you set the background just once.
Here is an example
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<corners android:radius="@dimen/quarter_margin" />
<stroke
android:width="1dp"
android:color="@color/ash_gray" />
<solid android:color="@color/white" />
</shape>
</item>
<item android:drawable="@drawable/blue_back">
</item>
</layer-list>
Another Solution:
To be able to use just one layout and control the image, You can make you own custom control, here is an example
public class RecordButton extends LinearLayout {
@BindView(R.id.record_switch)
SwitchCompat recordSwitch;
@BindView(R.id.record_toggle_button)
ToggleButton recordButton;
private boolean checkable = true;
public RecordButton(Context context) {
super(context);
init(context, null);
}
public RecordButton(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
public RecordButton(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs);
}
private void init(@NonNull Context context, @Nullable AttributeSet attrs) {
LayoutInflater inflater = LayoutInflater.from(context);
inflater.inflate(R.layout.record_button, this);
ButterKnife.bind(this);
setGravity(Gravity.CENTER_HORIZONTAL);
applyAttr(attrs);
setChecked(false);
}
private void applyAttr(@Nullable AttributeSet attrs) {
if (attrs != null) {
TypedArray a = getContext().getTheme().obtainStyledAttributes(attrs,
R.styleable.RecordButton, 0, 0);
// Set Image
int drawableResource = a.getResourceId(R.styleable.RecordButton_drawable, -1);
if (drawableResource > -1) {
int color = a.getColor(R.styleable.RecordButton_tint, -1);
if (color > -1) {
Drawable drawable = ContextCompat.getDrawable(getContext(), drawableResource);
Drawable wrapDrawable = DrawableCompat.wrap(drawable);
DrawableCompat.setTint(wrapDrawable, Color.RED);
recordSwitch.setBackground(wrapDrawable);
} else {
recordSwitch.setBackgroundResource(drawableResource);
}
}
// Set Orientation
boolean isVertical = a.getBoolean(R.styleable.RecordButton_isVertical, false);
if (isVertical) {
setOrientation(VERTICAL);
}
a.recycle();
}
}
}
Here I inflated a layout and added to this class which inherits from LinearLayout
Here is the layout inflated
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<android.support.v7.widget.SwitchCompat
android:id="@+id/record_switch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="false"
android:thumb="@android:color/transparent" />
<ToggleButton
android:id="@+id/record_toggle_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
android:clickable="false"
android:minHeight="0dp"
android:minWidth="0dp"
android:padding="@dimen/standard_margin"
android:textAllCaps="false"
android:textColor="@color/colorPrimary" />
</merge>
Now you main question comes, how can I change the image. In Java class you will find a method called applyAttr this method takes takes the custom attributes you added to your custom control
Here is an attr sample
this code to attrs.xml file
<declare-styleable name="RecordButton">
<attr name="drawable" format="reference" />
</declare-styleable>