¿Posible hacer un diseño XML de colmena en Android?
Un diseño de colmena debería ser así
- Línea multi de Android EditText
- LayoutInflater y onFinishInflate ()
- ¿Dónde debo colocar los archivos "ttf" en un proyecto de Android?
- Android: mostrar el teclado mueve mis componentes hacia arriba, quiero ocultarlos en su lugar
- Diseño en blanco - eglSurfaceAttrib no implementado
Las colmenas coloreadas son sólo para que entiendas cómo tengo que establecer elementos.
¿Qué widget de Layout
sugieres de usar?
Intenté con GridView
pero no puedo hacer tales células, entonces FrameLayout
pero no quiero ocuparse de los valores del pixel (o del dp) al fijar la localización de la colmena.
Estoy en mi ingenio final. Estoy cerca de la conclusión de que algo así no se puede hacer en Android de una manera de alta calidad y sin el uso de bibliotecas como el juego. Espero que alguien me dé una pista buena a la solución.
- NullPointerException en la animación de dissapearence de RecyclerView desde soporte v.23.2.0
- Enlace de datos de spinner de Android con diseño de xml
- Desarrollando PhoneGap para Android - Mejor práctica para diferentes tamaños de pantalla / densidad de píxeles
- Cómo agregar texto a la imagen y guardar como nueva imagen
- Uso de vistas personalizadas en XML sin utilizar el nombre de clase totalmente calificado
- Android - Uso Linear o Diseño de la tabla
- Elipse de TextView y símbolos rotos
- Margen de la vista raíz de un fragmento no registrada (cuando se utiliza en ViewPager)
Como no estoy seguro del propósito o requisitos previstos, lo siguiente es meramente prueba de concepto. La clase HoneycombView
no tiene chequeos de argumentos ilegales, o manejo de excepciones de ningún tipo, realmente. La mayoría de las propiedades son "codificadas", como el color y el ancho de la pared, los colores y la orientación de las celdas, etc. Todos estos son fácilmente modificados con la adición de los setters y getters apropiados. He incluido una clase de Activity
simple para demostrar su uso.
public class HoneycombView extends View { private Paint wallPaint = new Paint(); private Paint fillPaint = new Paint(); private Paint cachePaint = new Paint(); private Path combPath; private Bitmap cacheBmp; private Canvas cacheCan; private int cellWidth; private int columns; private int rows; private boolean[][] cellSet; private OnCellClickListener listener; public HoneycombView(Context context) { this(context, null); } public HoneycombView(Context context, AttributeSet attrs) { super(context, attrs); wallPaint.setColor(Color.YELLOW); wallPaint.setStyle(Paint.Style.STROKE); wallPaint.setStrokeWidth(5f); fillPaint.setStyle(Paint.Style.FILL); cachePaint.setStyle(Paint.Style.FILL); } public void initialize(int columns, int rows) { this.columns = columns; this.rows = rows; this.cellSet = new boolean[columns][rows]; } public interface OnCellClickListener { public void onCellClick(int column, int row); } public void setOnCellClickListener(OnCellClickListener listener) { this.listener = listener; } public void setCell(int column, int row, boolean isSet) { cellSet[column][row] = isSet; invalidate(); } public boolean isCellSet(int column, int row) { return cellSet[column][row]; } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); cacheBmp = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); cacheCan = new Canvas(cacheBmp); cellWidth = 2 * w / (2 * columns + columns - 1); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawColor(Color.WHITE); boolean oddRow; int xOff; combPath = getHexPath(cellWidth / 2f, cellWidth / 2f, (float) (cellWidth * Math.sqrt(3) / 4)); for (int r = 0; r < rows; r++) { oddRow = (r & 1) == 1; xOff = 0; for (int c = 0; c < columns; c++) { if (!(oddRow && c == columns - 1)) { fillPaint.setColor(cellSet[c][r] ? Color.RED : Color.WHITE); canvas.drawPath(combPath, fillPaint); canvas.drawPath(combPath, wallPaint); cachePaint.setColor(Color.argb(255, 1, c, r)); cacheCan.drawPath(combPath, cachePaint); combPath.offset((int) (1.5f * cellWidth), 0); xOff += 1.5f * cellWidth; } } combPath.offset(-xOff + (oddRow ? -1 : 1) * 3 * cellWidth / 4, (float) (cellWidth * Math.sqrt(3) / 4)); } } @Override public boolean onTouchEvent(MotionEvent event) { if (event.getAction() != MotionEvent.ACTION_DOWN) return true; int pixel = cacheBmp.getPixel((int) event.getX(), (int) event.getY()); int r = Color.red(pixel); if (r == 1) { int g = Color.green(pixel); int b = Color.blue(pixel); if (listener != null) { listener.onCellClick(g, b); } } return true; } private Path getHexPath(float size, float centerX, float centerY) { Path path = new Path(); for (int j = 0; j <= 6; j++) { double angle = j * Math.PI / 3; float x = (float) (centerX + size * Math.cos(angle)); float y = (float) (centerY + size * Math.sin(angle)); if (j == 0) { path.moveTo(x, y); } else { path.lineTo(x, y); } } return path; } }
Y la Activity
:
public class MainActivity extends Activity implements HoneycombView.OnCellClickListener { HoneycombView honey; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); getWindow().requestFeature(Window.FEATURE_NO_TITLE); honey = new HoneycombView(this); honey.initialize(4, 8); honey.setOnCellClickListener(this); setContentView(honey); } @Override public void onCellClick(int column, int row) { honey.setCell(column, row, !honey.isCellSet(column, row)); } }
Fui con mi sugerencia inicial de alterar ligeramente el color de un área para determinar dónde ocurrirían los eventos de toque, pero terminé haciéndolo en un Bitmap
miembro para que los colores en pantalla no se vean afectados. Como se puede ver en el código, las celdas de este Bitmap
se rellenan de tal manera que codifican información de celda relevante en los componentes RGB del Color
. El componente Rojo se establece en 1 para indicar que un píxel dado está dentro de la región pertinente (es decir, dentro de todo el "nido de abeja"). La columna de la celda y las posiciones de fila dentro de la cuadrícula se codifican en los componentes Verde y Azul y se recuperan fácilmente en el método onTouchEvent()
.
El método initialize()
establece el número de columnas y filas en la cuadrícula y en la Activity
muestra se establecen para favorecer una orientación horizontal. Sólo para mayor claridad, en mi implementación, con las celdas orientadas para que el eje largo sea horizontal, defino una fila para que conste de las celdas cuyos ejes son co-lineales. El enlace que había publicado en mi comentario hizo las cosas de manera diferente.
Casi se me olvidó dar crédito: Tengo el código de Path
hexagonal de esta pregunta .
- SetOnItemClickListener no funciona
- Android: Cambia la imagen de un elemento en particular en listview