relativelayout:将视图与同级视图组的子视图对齐

发布于 2024-12-17 01:08:07 字数 1528 浏览 0 评论 0原文

我正在尝试使用RelativeLayout 和RadioGroup 在android 中制作一个选项卡栏,该RadioGroup 具有一个指示器,该指示器将滑动以指示RadioGroup 内的活动RadioButton。

这些是自定义的单选按钮,它们实际上是矩形,文本上方有一个图标,所有内容均居中,并使用自定义状态选择器作为背景。

这是我当前的层次结构:

<RelativeLayout>       // Main view of the tab bar
  <RadioGroup>         // The buttons
    <RadioButton />
    <RadioButton />
    <RadioButton />
  </RadioGroup>
  <ImageView />        // The indicator
</RelativeLayout>

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

我想过将指示器作为 RadioGroup 的成员,但由于 RadioGroup 是 LinearLayout 的扩展,因此似乎没有办法将其放置在给定 RadioButton 的边缘。

谁能想到我如何解决这个问题?或者也许有比我的动画对齐按钮技术更好的解决方案?

更新 在@superjos的帮助下,我很好地解决了这个问题。

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

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

源来凯始玺欢你 2024-12-24 01:08:07

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

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

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

步骤:

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

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

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

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

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

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

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. 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.

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. The animation is set with fillAfter so to stay firm after it completes.

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.

  • To initially align the ImageView to the first RadioButton, some XML could suffice: in ImageView attach layout_toRightOf and layout_alignTop to the RadioGroup. In order to take into account the top-padding from RadioGroup, you could add that to the initial ImageView top-padding XML attribute. 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). 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 (e.g. from 0 to 2) (Warning: that is pseudo-code, not necessarily an existing Java field named Index).

  • Apply the animation to the ImageView and start it.

荒岛晴空 2024-12-24 01:08:07

您可以自定义 RadioButton 样式,以包含指示器图像的 9patch 版本作为所选(可能会检查单选按钮..)状态的背景。或者作为可绘制的

但是,这取决于您想要动画的外观。

例如。

<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>

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. 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>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文