简体   繁体   English

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

[英]RelativeLayout: align view to child of sibling viewgroup

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. 我正在尝试使用RelativeLayout和一个RadioGroup创建一个标签栏,该组有一个指示器,该指示器将滑动以指示RadioGroup中的活动RadioButton。

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, ie I can align to the RadioGroup itself, but not to a RadioButton inside it. 但是,似乎layout_align<Edge>仅适用于兄弟元素,而不适用于另一个视图组的成员,即我可以与RadioGroup本身对齐,但不能与其中的RadioButton对齐。

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. 我想把指标作为RadioGroup的成员,但由于RadioGroup是LinearLayout的扩展,似乎没有办法将它放在给定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? 或者也许比我的animate-align-to-button技术有更好的解决方案?

UPDATE With @superjos help, I managed to work this out fairly well. 更新使用@superjos帮助,我设法很好地解决了这个问题。

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). 我必须给每个按钮一个已知的高度,而不是使用wrap_content (不理想,但对于这个项目,它可能应该工作正常)。 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. 确保将RadioGroup设置为包装内容并在父视图中垂直居中。 Set indicator to alignTop and toRightOf the RadioGroup. 将指示器设置为alignToptoRightOf指示器设置为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();
}

Here's my idea about it. 这是我的想法。 Following are some more detailed steps. 以下是一些更详细的步骤。

The idea is to have the ImageView has a RadioGroup sibling, as it is in your sample. 我们的想法是让ImageView拥有一个RadioGroup兄弟,就像你的样本一样。 The ImageView is initially positioned on the right of the RadioGroup, and its horizontal middle line is aligned with the one of the first (or whatever chosen) RadioButton. ImageView最初位于RadioGroup的右侧,其水平中间线与第一个(或任何选定的)RadioButton中的一个对齐。

Then, upon a RadioButton click, a TranslateAnimation is built/configured at runtime in order to let the ImageView shift vertically until its middle line gets aligned with the one of the clicked button. 然后,在RadioButton单击时,在运行时构建/配置TranslateAnimation,以便让ImageView垂直移动,直到其中间线与单击的按钮对齐。 The animation is set with fillAfter so to stay firm after it completes. 动画设置为fillAfter,以便在完成后保持稳定。

Steps: 脚步:

  • Create your resources so that ImageView and RadioButtons have the same height, or else work with vertical paddings so that they result having the same height. 创建资源,使ImageView和RadioButtons具有相同的高度,或者使用垂直填充,以便它们具有相同的高度。

  • To initially align the ImageView to the first RadioButton, some XML could suffice: in ImageView attach layout_toRightOf and layout_alignTop to the RadioGroup. 要最初将ImageView与第一个RadioButton对齐,一些XML 足够了:在ImageView layout_alignTop layout_toRightOflayout_alignTop附加到RadioGroup。 In order to take into account the top-padding from RadioGroup, you could add that to the initial ImageView top-padding XML attribute. 为了考虑RadioGroup的top-padding,您可以将其添加到初始的ImageView顶部填充XML属性中。 Or better as top-margin. 或者更好的是利润最高。

  • When a RadioButton is clicked, create a TranslateAnimation that will be applied to the ImageVew, changing only the Y coordinate starting from 0 to its destination toY value (while from/toX attribute will be 0). 单击RadioButton时,创建将应用于ImageVew的TranslateAnimation,仅更改从0开始到其目标的Y坐标到Y值(而from / toX属性将为0)。 That is given by a formula such as: 这由以下公式给出:

     toY = (ClickedRadioButton.Index - LastClickedRadioButton.Index) * RadioButton.Heigth 

    Here Index is the ordinal position of the RadioButton within the group (eg from 0 to 2) (Warning: that is pseudo-code, not necessarily an existing Java field named Index ). 这里Index是组内RadioButton的序数位置(例如从0到2)(警告:这是伪代码,不一定是名为Index的现有Java字段)。

  • Apply the animation to the ImageView and start it. 将动画应用于ImageView并启动它。

You could customise the RadioButton style to include a 9patched version of the indicator image as a background for the selected (might be checked for radios..) state. 您可以自定义RadioButton样式,以包含9patched版本的指示器图像作为所选(可能检查无线电..)状态的背景。 Or as drawable 或者作为绘画

However, it depends what you want the animation to look like. 但是,这取决于你想要动画的样子。

For example. 例如。

<style name="TabRadioButton" parent="@android:style/Widget.CompoundButton.RadioButton">
    <item name="android:background">@drawable/tab_bg</item>
    <item name="android:drawableLeft">@drawable/tab_indicator</item>
</style>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM