Intereting Posts
Комбинировать как фоновое изображение, так и стиль фона на кнопке Почему невозможно использовать ViewPager внутри фрагмента? Это на самом деле Java.lang.NumberFormatException: недопустимый int: "" ИСКЛЮЧЕНИЕ Android-код для записи видео с помощью удаленной IP-камеры, к которой осуществляется доступ с помощью URL-адреса Не удалось загрузить модуль memtrack -2 Android N не отправляет трансляцию android.net.conn.CONNECTIVITY_CHANGE? Передавать переменные String по ссылке setOnItemSelectedListener из нескольких Spinners Разработчик уведомлений Android getNotification () vs build () Android: ярлык приложения должен быть восстановлен после обновления Почему мы можем вызвать getActivity () в onCreateView, который выполняется до onActivityCreated? Удаление приложения для Android Android BottomSheet как рухнуть при нажатии на внешнюю сторону? Как можно скорее применить PageTransformer к PagerView RxJava: узнайте, было ли BehaviorSubject повторяющимся значением или нет Как бороться с удалением разрешения для широковещательного приемника в Android M?

Android Hexagon Grid

Мне нужно разработать приложение, в котором кнопки представляют собой шестиугольники, и все они расположены рядом друг с другом, создавая сетку. Учитывая мой небольшой опыт работы с Android, я задаюсь вопросом, подходит ли GridView для этого. Если это так, как я могу разместить шестиугольники рядом друг с другом?

У меня есть это к настоящему времени

Введите описание изображения здесь

Используя этот макет в main.xml:

<?xml version="1.0" encoding="utf-8"?> <GridView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/gridview" android:layout_width="fill_parent" android:layout_height="fill_parent" android:padding="0dp" android:verticalSpacing="0dp" android:horizontalSpacing="0dp" android:numColumns="4" android:columnWidth="0dp" android:stretchMode="columnWidth" android:gravity="top" /> 

И это то, что я пытаюсь получить:

Шестиугольная сетка

Мне нужна была бы помощь по размещению шестиугольников, привязанных друг к другу в фиксированной структуре. Я играю со значениями макета без каких-либо успехов. Будет ли TableView лучшим подходом? большое спасибо

Вот код, который я использовал в приложении (он называется «Connect3», если вы хотите воспроизвести его :)). Это пользовательский класс макета, который рисует гексагональные изображения в сетке. Сетка может быть треугольной или наклонной прямоугольником.

Код вычисляет границы (в пикселях относительно начала hexgrid) каждого изображения и затем вызывает imageView.layout(left,top,right,bottom) чтобы установить расчетные границы. Расчеты не так уж трудны. Основным параметром является radius шестиугольника. Исходя из этого, общая высота, общая ширина, эффективная высота и эффективная ширина (высота / ширина изображения соответственно – расстояние между верхними / левыми границами двух последовательных видов). Затем это сводится к некоторым простым циклам для их рисования.

Чтобы сделать просмотр доступным, просто установите onClickListener при их создании. (Я сделал его членом класса, потому что это упростило ситуацию).

Функция onMeasure просто вычисляет общую ширину и высоту представления и вызывает setMeasuredDimension с этими значениями.

Изображения, используемые для всего этого, – это только одно шестиугольники, как вы видите их прямо под панелью действий. Обратите внимание, что изображения представляют собой квадраты.

  @Override protected void onLayout(final boolean changed, final int l, final int t, final int r, final int b) { Log.d(TAG, "board.onlayout called with size "+mSize+" l: "+l+" r: "+r+" t: "+t+" b: "+b); //If the dimensions of the board haven't changed, a redraw isn't necessary. Just update the images of the views instead by calling invalidate(). if (!changed && !mSizeInvalidated) { invalidate(); return; } int childCount = getChildCount(); //Calculate some useful parameters. float radius = getResources().getDimension(R.dimen.radius); float verticalMargin = -radius / 4; float horizontalMargin = ((float) Math.sqrt(3) / 2 - 1) * radius; float height = 2 * radius; float width = height; float effectiveHeight = height + 2 * verticalMargin; float effectiveWidth = width + 2 * horizontalMargin; float totalHeight=(radius * (3 * mSize + 1)) / 2; float totalWidth; switch (mGameType) { case Connect3Turn.GAME_TYPE_HEX: totalWidth = (((float) mSize * 3 - 1)/ 2) * ((float) Math.sqrt(3)) * radius; break; case Connect3Turn.GAME_TYPE_Y: default: totalWidth = mSize * ((float) Math.sqrt(3)) * radius; } LayoutParams layoutParams = new LayoutParams((int) width, (int) height); //Code to calculate the offsets for horizontal and vertical centering (this is an option in the .xml file) //The GAME_TYPE_HEX creates a tilted rectangular board and GAME_TYPE_Y creates a triangular board. float x_offset_row; switch (mGameType) { case Connect3Turn.GAME_TYPE_Y: x_offset_row=(mSize - 1) * effectiveWidth / 2 + horizontalMargin; break; case Connect3Turn.GAME_TYPE_HEX: default: x_offset_row=0; } switch (mCenterHorizontal) { //the left side of the grid should be at non-negative coordinates. case 1: { x_offset_row += Math.max(0,(rl-totalWidth)/2); break; } case 2: {x_offset_row += Math.max(0,(rl-totalWidth)); break; } case 0: default: { break; } } //calculate the y_offset for vertical centering. float y_offset = 0; switch (mCenterVertical) { case 1: { y_offset = Math.max(0, (b - t - totalHeight) / 2); break; } case 2: { y_offset = Math.max(0, (b - t -totalHeight)); break; } } int cell = 0; for (int row = 0; row < mSize; ++row) { float x_offset = x_offset_row; int rowLength; //The row length depends on the board-type we want to draw. switch (mGameType){ case Connect3Turn.GAME_TYPE_HEX: rowLength=mSize; break; case Connect3Turn.GAME_TYPE_Y: default: rowLength=row+1; } Log.d(TAG, "Drawing row "+row+" with "+rowLength+" cells."); for (int col = 0; col < rowLength; ++col) { ImageView v; if (cell < childCount) { v = (ImageView) getChildAt(cell); } else { v = new ImageView(super.getContext()); v.setLayoutParams(layoutParams); v.setOnClickListener(onClickListener); addViewInLayout(v, cell, v.getLayoutParams(), true); } //Set the image (color) of the cell and put its index in a tag, so we can retrieve the number of the clicked cell in the onClickListener. v.setImageResource(mImageIds[mImages[cell]]); v.setTag(cell); //Set the bounds of the image, which will automatically be cropped in the available space. v.layout((int) x_offset, (int) y_offset, (int) (x_offset + width), (int) (y_offset + height)); x_offset += effectiveWidth; ++cell; } y_offset += effectiveHeight; //The offset of the next row, relative to this one, again depends on the game type. switch(mGameType){ case Connect3Turn.GAME_TYPE_Y: x_offset_row -= effectiveWidth / 2; break; case Connect3Turn.GAME_TYPE_HEX: x_offset_row += effectiveWidth / 2; } } //We updated all views, so it is not invalidated anymore. mSizeInvalidated=false; } 

hexgrid1hexgrid2

Hexgrid – это проект Github, реализующий гексагональную (шестнадцатеричную) сетку.

Вы всегда можете работать с ним, как если бы это была нормальная сетка. Но вместо того, чтобы рисовать квадрат, вы рисуете шестиугольник.

http://img811.imageshack.us/img811/9229/uyje.png

Но тогда вы перемещаете нечетные линии на половину ширины шестиугольника таким образом, чтобы они соответствовали парам.

http://img822.imageshack.us/img822/2298/e5cq.png