Dynamically arrange ImageButtons around a Circle i

2019-09-09 00:48发布

问题:

My question is intended to be more focused on the layout file or files, I know how to calculate and position every item that I need around the circle, but what I don´t have clear, is how to code the xml files, I mean, how many ImageButtons do I define? Is it a relative Layout? Do I use a list instead and populated with ImageButtons?... I´m confused :/

Thank you in advance :)

回答1:

I'm pretty sure relative layout would not be the way to go since your going to want them positioned according to the center of the circle and not relative to escorted. That being said, you will need to place them all specifically and not with a simple procedure because image buttons are square and you will get overlap the closer you get to the 45 degree angles unless you space them all far enough away from each other or you make them circular as well.



回答2:

I forgot to answer this question, I found the solution long time ago, I did it this way:

/**
 * Method that describe the circle equation to organize the buttons
 *
 * @param n Number of item to arrange around circle
 */
public void setButtons(int n) {

    /**
     * x = initial position
     * y = initial position
     * R = radius of circle
     * i = item/element/category to position
     * pi = Math.pi
     * nC = number of categories
     *
     *          X                   Y
     * (x+R*Cos(i*2*pi/n) , y-R*Sin(i*2*pi/n))
     *
     */

    int actionBarHeight = Utils.convertDp(8, this);
    DisplayMetrics displaymetrics = new DisplayMetrics();
    getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
    int height = displaymetrics.heightPixels + actionBarHeight;
    int width = displaymetrics.widthPixels;
    final int x = (width / 2) - Utils.convertDp(38, this);
    final int y = height / 2 - Utils.convertDp(70, this);
    final double pi = Math.PI;
    final int R = Utils.convertDp(13 * n, this); // 13 is a constants that 
    //assure a good distance when there n > 8
    final int nC = n;

    Log.i("DATOS ECUACION = ", "Height: " + height +
            " Width: " + width +
            " x: " + x +
            " y: " + y);

    final Handler mHandler = new Handler();

    for (int i = 0; i < nC; i++) {

        final ImageButton mIb = new ImageButton(DooActivity.this);
        final TextView mTv = new TextView(DooActivity.this);

        try {
            File f = new File(mList.get(i).getLocalURL_ImageCircle());
            Bitmap b = BitmapFactory.decodeStream(new FileInputStream(f));
            mIb.setVisibility(View.INVISIBLE);
            mIb.setImageBitmap(b);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        float xI = ((float) (x + R * Math.cos(i * 2 * pi / nC)));
        float yI = ((float) (y - R * Math.sin(i * 2 * pi / nC)));
        mIb.setX(xI);
        mIb.setY(yI);

        mTv.setX(xI + Utils.convertDp(15, this));
        mTv.setY(yI + Utils.convertDp(60, this));
        mTv.setTextSize(11);

        mIb.setAdjustViewBounds(true);
        mIb.setMaxHeight(Utils.convertDp(80, this));
        mIb.setMaxWidth(Utils.convertDp(80, this));
        mIb.setBackgroundColor(Color.TRANSPARENT);

        mTv.setMaxHeight(Utils.convertDp(80, this));
        mTv.setMaxWidth(Utils.convertDp(80, this));

        LinearLayout.LayoutParams vp = new  
        LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, 
        LinearLayout.LayoutParams.WRAP_CONTENT);
        mIb.setLayoutParams(vp);
        mIb.setId(mList.get(i).getCategoryId().intValue());
        mIb.setTag(mList.get(i));
        mIb.setOnClickListener(this);

        mListImageButton.add(mIb);

        mTv.setLayoutParams(vp);

        mHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                ScaleAnimation scale = new ScaleAnimation(0, 1, 0, 1,
                        ScaleAnimation.RELATIVE_TO_PARENT, .5f,
                        ScaleAnimation.RELATIVE_TO_PARENT, .5f);
                scale.setDuration(140);
                mIb.startAnimation(scale);
                mIb.setVisibility(View.VISIBLE);

                mTv.startAnimation(scale);
                mTv.setVisibility(View.VISIBLE);
                mFl.addView(mIb);
                mFl.addView(mTv);
            }
        }, 1000);

        Log.i("DATOS FOR = ", "x" + i + ": " + xI +
                " y" + i + ": " + yI +
                " CAT ID: " + mList.get(i).getCategoryId());
    }
}

And I had a RelativeLayout with a FrameLayout in my XML file, hope you find it useful.