围绕圆圈动态排列按钮

发布于 2025-01-07 15:24:48 字数 847 浏览 2 评论 0原文

我对 android 还很陌生,所以我并不完全熟悉所有的视图组件。 我正在努力围绕圆动态对齐按钮。

我想要实现的目标是将 n 个按钮(n 可以在创建时更改)添加到看起来像所附图像的视图:

我想避免使用absoluteLayout(但如果是的话,我愿意接受建议解决这个问题的唯一方法)。 我已经计算出按钮的 x/y 位置(暂时忽略按钮大小):

int iNumberOfButtons = 10;
double dIncrease = Math.PI * 2 / iNumberOfButtons,
    dAngle = 0,
        x = 0,
        y = 0;

  for( int i = 0; i < iNumberOfButtons; i++ )
  {
    x = 100 * Math.cos( dAngle ) + 200;
    y = 100 * Math.sin( dAngle ) + 200;
    dAngle += dIncrease;
    // get button and set position?
  }

我考虑过从自定义视图内部使用此代码,但从我所看到的来看,视图需要从 ViewGroup 进行子类化有 addView 方法,然后再次只有absoluteLayout似乎允许设置x,y位置...我不知道如何实现这个功能。

稍后我可能会向该视图添加一些动画,因此如果可能的话,使用 SurfaceView 可能会很好,但这不是必需的。

I'm still new to android so I'm not totally familiar with all the view components.
I'm struggling with aligning Buttons dynamically around a circle.

What I am trying to achieve is to add n buttons (n can change at creation time) to a view that looks like the attached image:

I'd like to avoid using absoluteLayout (but I'm open to suggestions if that's the only way to solve it).
I already came up with a calculation for the x/y positions for the buttons (ignoring button size for now):

int iNumberOfButtons = 10;
double dIncrease = Math.PI * 2 / iNumberOfButtons,
    dAngle = 0,
        x = 0,
        y = 0;

  for( int i = 0; i < iNumberOfButtons; i++ )
  {
    x = 100 * Math.cos( dAngle ) + 200;
    y = 100 * Math.sin( dAngle ) + 200;
    dAngle += dIncrease;
    // get button and set position?
  }

I thought about using this code from inside a custom view but from what I've seen the view needs to be subclassed from ViewGroup to have the addView method and then again only absoluteLayout seems to allow setting x, y positions... I'm at a loss how to implement this feature.

I might add some animations to that view later on, so using SurfaceView might be nice if it's possible but it's not a requirement.

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

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

发布评论

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

评论(3

酒绊 2025-01-14 15:24:48

我想我找到了我试图实现的解决方案。

我创建了自己的视图子类RelativeLayout。在 onCreate() 中,我设置了

setWillNotDraw(false);

onDraw() 被调用。
然后我继续 onDraw():

int iHeight = getHeight();
int iWidth = getWidth();
int iNumberOfButtons = 10;
double dIncrease = Math.PI * 2 / iNumberOfButtons,
       dAngle = 0,
       x = 0,
       y = 0;

  for( int i = 0; i < iNumberOfButtons; i++ )
  {
    x = 200 * Math.cos( dAngle ) + iWidth/2;
    y = 200 * Math.sin( dAngle ) + iHeight/2;
    dAngle += dIncrease;
    Button xButton = new Button(m_xContext);
    xButton.setAdjustViewBounds(true);
    xButton.setBackgroundResource(R.drawable.some_image);
    LayoutParams xParams = (RelativeLayout.LayoutParams)xButton.getLayoutParams();
    if( xParams == null )
    {
      xParams = new RelativeLayout.LayoutParams( xButton.getBackground().getIntrinsicWidth(), xButton.getBackground().getIntrinsicHeight() );
    }
    xParams.leftMargin = (int)x - ( xButton.getBackground().getIntrinsicWidth() / 2 ) ;
    xParams.topMargin =  (int)y - ( xButton.getBackground().getIntrinsicHeight() / 2 );
    addView( xButton, xParams );
  }

这给了我想要的结果,但是 LayoutParams 的初始化感觉(并且很可能是)错误的。有更好的方法吗?

I think I found the solution I tried to achieve.

I create my own view subclassing RelativeLayout. In onCreate() I set

setWillNotDraw(false);

so that onDraw() gets called.
I then continue in onDraw():

int iHeight = getHeight();
int iWidth = getWidth();
int iNumberOfButtons = 10;
double dIncrease = Math.PI * 2 / iNumberOfButtons,
       dAngle = 0,
       x = 0,
       y = 0;

  for( int i = 0; i < iNumberOfButtons; i++ )
  {
    x = 200 * Math.cos( dAngle ) + iWidth/2;
    y = 200 * Math.sin( dAngle ) + iHeight/2;
    dAngle += dIncrease;
    Button xButton = new Button(m_xContext);
    xButton.setAdjustViewBounds(true);
    xButton.setBackgroundResource(R.drawable.some_image);
    LayoutParams xParams = (RelativeLayout.LayoutParams)xButton.getLayoutParams();
    if( xParams == null )
    {
      xParams = new RelativeLayout.LayoutParams( xButton.getBackground().getIntrinsicWidth(), xButton.getBackground().getIntrinsicHeight() );
    }
    xParams.leftMargin = (int)x - ( xButton.getBackground().getIntrinsicWidth() / 2 ) ;
    xParams.topMargin =  (int)y - ( xButton.getBackground().getIntrinsicHeight() / 2 );
    addView( xButton, xParams );
  }

This gives me the desired result, however the initializing of the LayoutParams feels (and most likely is) wrong. Is there a better way to do this?

牛↙奶布丁 2025-01-14 15:24:48

以下 Apache 2.0 许可项目可能有用: https://github.com/dmitry-zaitsev/CircleLayout< /a>

The following Apache 2.0 Licensed project may be of service: https://github.com/dmitry-zaitsev/CircleLayout

鲜血染红嫁衣 2025-01-14 15:24:48

您可以使用RelativeLayout 代替绝对布局,并为子视图设置上边距和左边距。像这样的事情:

RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) view.getLayoutParams();
params.leftMargin = x;
params.topMargin = y;

Instead of absolute layout you can use RelativeLayout and to child view, set the top and the left margins. Something like this:

RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) view.getLayoutParams();
params.leftMargin = x;
params.topMargin = y;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文