I'm trying to make a tab bar in android using a RelativeLayout and a RadioGroup that has an indicator which will slide to indicate the active RadioButton within the RadioGroup.
These are customized radio buttons that are effectively rectangles with an icon over text, all contents centered, which uses a custom state-selector for the background.
Here's my current hierarchy:
<RelativeLayout> // Main view of the tab bar
<RadioGroup> // The buttons
<RadioButton />
<RadioButton />
<RadioButton />
</RadioGroup>
<ImageView /> // The indicator
</RelativeLayout>
The idea I had was when a radio button was clicked, I would align the indicator to the top & bottom of the selected radio button (and animate it). However, It seems that layout_align<Edge>
only works with sibling elements, not with members of another view group, i.e. I can align to the RadioGroup itself, but not to a RadioButton inside it.
I thought of putting the indicator as a member of the RadioGroup, but since RadioGroup is an extension of LinearLayout, there doesn't seem to be a way to place it at the edge of a given RadioButton.
Can anyone think of how I might solve this issue? Or perhaps there's a better solution than my animate-align-to-button technique?
UPDATE With @superjos help, I managed to work this out fairly well.
I had to give each button a known height instead of using wrap_content
(not ideal, but for this project it should probably work fine). Make the indicator height match that of the buttons. Make sure the RadioGroup is set to wrap content and be centered vertically in the parent view. Set indicator to alignTop
and toRightOf
the RadioGroup. Then, for the button click listener:
int prevY, newY;
int prevButtonIndex, newButtonIndex;
public void moveIndicator(button, indicator, index) {
prevY = newY;
newY = prevY + (index - prevButtonIndex) * button.getHeight();
TranslateAnimation animation = new TranslateAnimation(0, 0, prevY, newY);
animation.setDuration(500);
animation.setFillAfter(true); // stay at final animation position
indicator.setAnimation();
animation.start();
}