I would like to create an Android custom component for a game. The basic idea is that the custom component would be square in shape and contain other square ImageView components inside it. The ImageView components inside may be scaled and/or cropped as needed, but must remain square. The number of rows == columns, always. The difficulty level determines the exact value of rows and columns at runtime. As the game gets more difficult, the number of rows and columns will increase equally, but the scaled size of each ImageView will shrink accordingly. I would like the components to have some fixed small spacing between them, mostly so it looks nice. The display won't be scrollable, all items must fit on the display at the same time.
After a bunch of failed attempts, I'm getting frustrated and I'm not sure what is the best approach is to make this custom component.
My latest idea would be to do roughly the following:
I create my custom component class by "extends FrameLayout". In my constructor, I create an arbitrary small square ImageView object in code. I'd like others to reuse my custom component someday, so I do it in code rather than XML so that the custom component doesn't rely on any external XML drawable having to be defined. I set the scale type so that the ImageView retains it's "squareness" (I think I want fitStart?). I set the square ImageView's layout_width and layout_height to "fill_parent", so the ImageView fills in as big a space as is available in the containing FrameLayout. I add the now large and square ImageView to my layout using addView().
Next I create a RelativeLayout object and also programmatically add it to myself using addView(). Because my base class is a FrameLayout, I think this will make the size of the RelativeLayout the same as the square ImageView previously added. At least that's how I read the documentation.
Next I measure the ImageView to see how large it is. I don't think I can measure myself because my previous attempts failed at this. I kept getting 0 for my size. My research said this was because I can't measure myself during construction. This turned into a Catch-22. When I tried to scale my image to the available space, I couldn't because there was no space available yet. My hope is that because I changed to using the FrameLayout as my base class and I add the ImageView to it, I will be able to measure my newly created and correctly scaled large square ImageView.
If all goes as planned, I now know how big the space available is on the user's device for my RelativeLayout because it's the same as my ImageView. By knowing how much space is available and how many rows and columns need to be displayed, I can correctly scale each ImageView I add accordingly, assuming I remember to account for the spacing between the ImageViews I add. Now I no longer need the square ImageView and can make it go away if I want.
If reasonable, I would like the large ImageView to have rounded corners and each ImageView added also have rounded corners. With a small gap between ImageViews added, this would look cool for gameplay. This way I can leave it as a background.
This seems like a good solution, and better than my previous attempts that didn't work, but if there's a better way..., I'm listening.
Here's some psuedo-code that says mostly the same thing as above to the best of my understanding:
construct() { ImageView squareImageView = new ImageView(Square); LayoutParams squareImageLayoutParams = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT); squareImageLayoutParams.addRule(fitStart); addView(squareImageView, squareImageLayoutParams); RelativeLayout relativeLayout = new RelativeLayout(context); LayoutParams relativeLayoutParams = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT); addView(relativeLayout, relativeLayoutParams); int size = squareImageView.getWidth(); // Should be the scaled size and square. squareImageView.setVisibility(INVISIBLE); // maybe? loop for each row and col { crop, scale and add each image to the relativeLayout object. } }
My most basic question is if this seems like a reasonable solution? If so, there's a bunch of things in the psuedocode I don't know how to do (yet).
- How do I create a small square ImageView in code?
- How do I set the scaleType in code?
- Will I be able to measure my square ImageView and get the correct size?
- Is there a better way to remove the square ImageView other than making it invisible?
- Will making my square ImageView invisible make it unmeasurable?
- I see something called a ShapeDrawable, would this be better than an ImageView for making a square?
- How do I crop an ImageView to be square, distributing the loss equally to both sides?
I certainly don't expect anyone to know all these answers, but if you know any answers you can share, I would appreciate it.
Thanks.