RelativeLayout:将视图与兄弟视图组的子视图对齐

Jos*_*ach 6 android tabbar relativelayout viewgroup

我正在尝试使用RelativeLayout和一个RadioGroup创建一个标签栏,该组有一个指示器,该指示器将滑动以指示RadioGroup中的活动RadioButton.

这些是定制的单选按钮,它们是有效的矩形,文本上有一个图标,所有内容都居中,它使用自定义状态选择器作为背景.

这是我目前的等级制度:

<RelativeLayout>       // Main view of the tab bar
  <RadioGroup>         // The buttons
    <RadioButton />
    <RadioButton />
    <RadioButton />
  </RadioGroup>
  <ImageView />        // The indicator
</RelativeLayout>
Run Code Online (Sandbox Code Playgroud)

我的想法是单击一个单选按钮时,我会将指示器对齐到所选单选按钮的顶部和底部(并为其设置动画).但是,它似乎layout_align<Edge>只适用于兄弟元素,而不适用于另一个视图组的成员,即我可以与RadioGroup本身对齐,但不能与其中的RadioButton对齐.

我想把指标作为RadioGroup的成员,但由于RadioGroup是LinearLayout的扩展,似乎没有办法将它放在给定RadioButton的边缘.

谁能想到我怎么解决这个问题?或者也许比我的animate-align-to-button技术有更好的解决方案?

更新 使用@superjos帮助,我设法很好地解决了这个问题.

我必须给每个按钮一个已知的高度而不是使用wrap_content(不理想,但对于这个项目,它可能应该工作正常).使指示器高度与按钮的高度相匹配.确保将RadioGroup设置为包装内容并在父视图中垂直居中.将指标设置为alignTop和toRightOfRadioGroup.然后,对于按钮单击侦听器:

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();
}
Run Code Online (Sandbox Code Playgroud)

sup*_*jos 1

这是我的想法。以下是一些更详细的步骤。

这个想法是让 ImageView 有一个 RadioGroup 同级,就像您的示例中一样。ImageView 最初位于 RadioGroup 的右侧,其水平中线与第一个(或任何选定的)RadioButton 之一对齐。

然后,单击 RadioButton 时,会在运行时构建/配置 TranslateAnimation,以便让 ImageView 垂直移动,直到其中线与单击的按钮之一对齐。动画是用fillAfter设置的,以便在完成后保持稳定。

脚步:

  • 创建资源,使 ImageView 和 RadioButtons 具有相同的高度,或者使用垂直填充,使它们具有相同的高度。

  • 为了最初将 ImageView 与第一个 RadioButton 对齐,一些 XML就足够了:在 ImageView 中附加layout_toRightOf并附layout_alignTop加到 RadioGroup。为了考虑 RadioGroup 的顶部填充,您可以将其添加到初始 ImageView 顶部填充 XML 属性中。或者作为上边距更好。

  • 单击 RadioButton 时,创建一个将应用于 ImageVew 的 TranslateAnimation,仅更改从 0 开始的 Y 坐标到其目标 toY 值(而 from/toX 属性将为 0)。这是由如下公式给出的:

    toY = (ClickedRadioButton.Index - LastClickedRadioButton.Index) * RadioButton.Heigth
    
    Run Code Online (Sandbox Code Playgroud)

    这里Index是 RadioButton 在组内的顺序位置(例如从 0 到 2)(警告:这是伪代码,不一定是名为Index的现有 Java 字段)。

  • 将动画应用到 ImageView 并启动它。