2011-11-18 75 views
5

我想在android中使用RelativeLayout和RadioGroup制作一个标签栏,该标签栏有一个指示灯,它将滑动以指示RadioGroup中的活动RadioButton。RelativeLayout:将视图对齐同级视图组的孩子

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

这里是我当前的层次:

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

的想法我是被点击一个单选按钮的时候,我会对准指标顶端&底部选择单选按钮(和动画吧)。但是,似乎layout_align<Edge>只适用于兄弟元素,而不适用于其他视图组的成员,即我可以对齐到RadioGroup本身,但不适用于其中的RadioButton。

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

任何人都可以想到我可以如何解决这个问题?或者,也许有比我的animate-align-to-button技术更好的解决方案?

UPDATE 在@superjos的帮助下,我设法解决了这个问题。

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

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

太棒了!实施看起来也不错! – superjos

回答

1

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

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

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

步骤:

  • 创建你的资源,这样的ImageView和单选按钮具有相同的高度,或者使他们的结果具有相同高度的垂直垫衬工作。

  • 要首先对准的ImageView到第一单选按钮,一些XML 可能足够了:在ImageView的附加layout_toRightOflayout_alignTop到RadioGroup中。为了考虑RadioGroup的顶部填充,您可以将其添加到初始ImageView顶部填充XML属性。或者更好的是顶级利润。

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

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

    这里指数是单选按钮组成的组中的顺序位置(例如,从0到2)(注意:这是伪代码中,不一定是现有Java字段名为索引)。

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

+0

大部分情况下,这看起来可能是使用的解决方案。该算法大部分工作(尽管需要设置'setFillAfter(true)'使其保持不变),但使用起始坐标0使动画始终从_original_起点开始,而不是从当前起点开始。我尝试过使用'getTop()','getBaseline()','getLocation()[1]'。但这些不起作用,并使起点成为第一或最底端的位置。任何想法如何调整呢? –

+0

看起来问题源于只有绘图位置改变。为了解决这个问题,我在动画完成时将一个实际的layout_marginTop更改应用到基于所选按钮的偏移量的指标上。这工作正常,但唯一的问题是它完成动画时闪烁。有没有简单的动画布局参数变化的方法? –

+0

这里有_new_ [属性动画](http://developer.android.com/guide/topics/graphics/prop-animation.html)框架,它允许你动画许多(所有?)视图属性,WPF /属性与动画的Silverlight绑定。自API 11以来它一直存在,但我从来没有使用它。 – superjos

0

你可以自定义单选按钮样式包括指示图像的9patched版作为选择的(可能是检查收音机..)状态的背景。或者作为drawable

但是,这取决于您想要动画的样子。

例如。

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

指示器基本上是一个三角形,指向一个边缘的按钮中心,点击该按钮时将从一个按钮边缘中心沿直线滑动到另一个边缘中心。我不确定把它作为按钮本身的drawable会给我带来那种效果。 –

相关问题