I am programatically adding ImageView elements into a horizontal Linear Layout. Then I set the scaleX and scaleY properties to "2" on one of the ImageView resources. The image gets scaled properly, but it doesn't move the other ImageView elements, instead of that it overlaps them. I don't like the image to overlap with other images. How can I fix that? Here's my code:
int resources[] = {R.drawable.desert, R.drawable.koala, R.drawable.jellyfish,
R.drawable.lighthouse, R.drawable.desert};
for(int i=0; i<5; i++) {
ImageView logo = new ImageView(this);
logo.setLayoutParams(new LinearLayout.LayoutParams(100, 75));
logo.setImageResource(resources[i]);
logosContainer.addView(logo);
}
ImageView middleImage = (ImageView) logosContainer.getChildAt(2);
middleImage.setScaleX(middleImage.getScaleX() * 2);
middleImage.setScaleY(middleImage.getScaleY() * 2);
The result from the code looks like this:
http://imageshack.us/a/img15/2811/scaleal.jpg
You can clearly see that the scaled image overlaps with the other images.
Your ImageViews are already measured and placed in the container when you leave the loop. You would have to refresh your layout to make this work, which is tricky and often leads into "removing all views and adding them again". So why don't you just do the "scaling" in the loop?
for(int i=0; i<5; i++) {
ImageView logo = new ImageView(this);
if(i==middleImageIndex){
logo.setLayoutParams(new LinearLayout.LayoutParams(100*2, 75*2,1));
} else {
logo.setLayoutParams(new LinearLayout.LayoutParams(100, 75,1));
}
logo.setImageResource(resources[i]);
logosContainer.addView(logo);
}
The last parameter (100,75, 1) is the weight of the view, which makes sure that each ImageView is equally important and doesn't get overlapped.
Another note: setScale requires API level 11 or higher, which could cut a lot of users out there
Related
I have to create a stack of images programmatically (because they have to be dynamic).
I want to stack ImageViews like this:
I've tried this, but the images all land up on top of each other:
for(int i=0; i<limit; i++){
dynamicButtons[i] = new ImageView(contextSosFragment);
int offsetLeft = 15 * i;
int offsetTop = 15 * i;
layoutParamsDynamicButton.setMargins(offsetLeft, offsetTop, 0, 0);
dynamicButtons[i].setAdjustViewBounds(true);
dynamicButtons[i].setScaleType(ScaleType.FIT_CENTER);
dynamicButtons[i].setImageResource(R.drawable.img_badge_dynamic_loading);
dynamicButtons[i].setTag(id);
containerDynamicButtons.addView(dynamicButtons[i], layoutParamsDynamicButton);
}
I've even removed the android:gravity="center" from my xml layout file.
I've also tried to add the layout params on the ImageView after setting the margins (dynamicButtons[i].setLayoutParams(layoutParamsDynamicButton);), but I read that that this might not take effect, because the layout params are for the parent and not the child of the container to which I add the ImageViews, that's why I tried to use addView(view, layoutParams).
How can I position the ImageViews like this, programmatically?
SOLUTION:
The solution was that I had to create a new layout params instance for each image - just like Devunwired suggested. However, I also found that I had to change the LinearLayout.LayoutParams to be RelativeLayout.LayoutParams. Only then did the change take effect.
The final for loop looks like this:
for(int i=0; i<limit; i++){
RelativeLayout.LayoutParams layoutParamsDynamicButton = new RelativeLayout.LayoutParams(width, height);
layoutParamsDynamicButton.bottomMargin = (int) getActivity().getResources().getDimension(R.dimen.margin_badges);
int offsetLeft = AppConstants.dynamic_button_offset_multiplier * i;
int offsetTop = AppConstants.dynamic_button_offset_multiplier * i;
layoutParamsDynamicButton.setMargins(offsetLeft, offsetTop, 0, 0);
Log.d(TAG, "offset = "+offsetLeft);
dynamicButtons[i] = new ImageView(contextSosFragment);
dynamicButtons[i].setAdjustViewBounds(true);
dynamicButtons[i].setScaleType(ScaleType.FIT_CENTER);
dynamicButtons[i].setImageResource(R.drawable.img_badge_dynamic_loading);
dynamicButtons[i].setTag(id);
containerDynamicButtons.addView(dynamicButtons[i], layoutParamsDynamicButton);
}
Each view needs its own LayoutParams object. It looks like your code just updates the same LayoutParams instance each time and passes it to addView(). If this is the case, all your views are pointing to the same params when it comes time to do layout...and their margins will all be the last value set.
As a performance optimization, if you are just placing several static images on top of each other, you could achieve the same effect (including the offsets) with a LayerDrawable (docs link) inside a single ImageView. This is the object created by <layer-list> in XML, but since you need to dynamically set the offset you could create one in code as well. Fewer views typically leads to cleaner UI.
Hey I have a grid of ImageButtons that is being scaled by display width and contains a PNG file as image. I add the whole thing to the linear layout like this:
public void createButtons(){
int buttonX = 9;
int buttonY = 9;
int size = 80;
int tag = 0;
TableLayout layout = new TableLayout (this);
layout.setLayoutParams( new TableLayout.LayoutParams(900,900) );
layout.setPadding(1,1,1,1);
layout.setBackgroundColor(0xff00af00); //green
RelativeLayout ll = (RelativeLayout)findViewById(R.id.rel);
ll.addView(layout);
for(int x=0;x<buttonX;x++) {
TableRow tr = new TableRow(this);
for(int y=0;y<buttonY;y++) {
but[x][y] = new ImageButton(this);
but[x][y].setBackgroundColor(0xff0000af); //blue
but[x][y].setImageResource(R.drawable.buttonmask3);
but[x][y].setScaleType(ImageButton.ScaleType.CENTER_INSIDE);
tr.addView(but[x][y], height/10,height/10);
}
layout.addView(tr);
}
}
The problem is, that the layout now looks like the following:
whereas it is supposed to look like:
(this one was a quick photoshop but you get the idea, that the scale is supposed to fill the button completely)
What can I do about these tiny images? I tried CENTER_INSIDE, FITXY and all the other ScaleTypes but I haven't been lucky so far :/
The width is taken from the screen width (or height in landscape)
the buttonmask3.png is about 170*170 px.
The problem is the padding that the ImageButton comes with naturally.
adding
but[x][y].setPadding(0, 0, 0, 0);
along with
but[x][y].setScaleType(ImageButton.ScaleType.CENTER_CROP);
Solved it for me.
I am making a puzzle game for which I have to display 16 images (4 X 4) on the screen at the same time. I am trying to set the height and width of images but no value of hieght and width is changing the image size. Moreover only 4 images are appearing instead of 16 images. I am using the folloing code to display images:
public void display()
{
LinearLayout llMain = new LinearLayout(this);
for(int i=0;i<4;i++)
{
LinearLayout llRow = new LinearLayout(this);
for(int j=i*4;j<tiles.length/4;j++)
{
ImageView iv = new ImageView(this);
iv.setImageBitmap(tiles[j]);
iv.setAdjustViewBounds(true);
iv.setMaxHeight(tileHeight);
iv.setMaxWidth(tileWidth);
iv.setMinimumHeight(tileHeight);
iv.setMinimumWidth(tileWidth);
LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
iv.setLayoutParams(params);
llRow.addView(iv);
}
llMain.addView(llRow);
}
setContentView(llMain);
}
Can somebody please tell me that What am I doing wrong?
Thanks in advance
Try using the layout_weight attribute of LinearLayout to divide the screen into the parts you need. The ratio of the values you set to the different parts makes the parts become bigger or smaller.
On my code i need to create some table that each column contain Bitmap and text - and i create this table dynamically.
So i doing this by using this code:
for (int i = 0; i < collection.size(); i++)
{
ObjectITem item = collection.get(i);
LinearLayout linearLayout = new LinearLayout(this);
linearLayout.setOrientation(LinearLayout.HORIZONTAL);
TextView textView = new TextView(this);
textView.setText(item.getText());
linearLayout.addView(textView);
linearLayout.addView( (new ImageButton(this)).setImageBitmap(item.getBitmap());
layout.addView(linearLayout, LayoutParams.WRAP_CONTENT);
}
this code is working good - but because the originaly images are not in same size - i see that the images that appear on the ImageButton are look not good.
How can i make all the images on the ImageButton to look the same ?
Is there some better way to make the layout that i did here ?
1) You can use Bitmap.createScaledBitmap() to scale all the images to a desired size. Like this...
Bitmap buttonBmp = Bitmap.createScaledBitmap(item.getBitmap(), buttonW, buttonH, true);
linearLayout.addView((new ImageButton(this)).setImageBitmap(buttonBmp);
2) You might want to consider using a ListActivity and a ListView. This is more complicated, but may be more efficient if your collection is large and needs to scroll over many pages.
Right now, I'm struggling to accomplish something as simple as adding margin space between my child ImageViews within a custom LinearLayout (modified RadioGroup that is designed to take in a custom ImageView that implements Checkable, didn't override onMesarue). Long story short, these images are of a fixed dimension (60x60dip), and since they are dynamic (from the web), I had to add them dynamically like so:
for(int i = 0; i < num; i++){
ImageViewRadioButton childImage = new ImageViewRadioButton(mContext);
float imagehWidthHeight = getResources().getDimension(R.dimen.image_width_and_height);
LinearLayout.LayoutParams imageParams = new LinearLayout.LayoutParams((int) imageWidthHeight, (int) imageWidthHeight);
int imageSpacing = Utils.dipsToPixels(10, mContext);
int innerPadding = Utils.dipsToPixels(5, mContext);
imageParams.leftMargin = imageSpacing;
imageParams.rightMargin = imageSpacing;
childImage.setAdjustViewBounds(true);
childImage.setLayoutParams(imageParams);
childImage.setBackgroundDrawable(getResources().getDrawable(R.drawable.blue_pressed));
childImage.setPadding(innerPadding, innerPadding, innerPadding, innerPadding);
childImage.setClickable(true);
//other non-image properties...
imageContainer.addView(childImage);
}
The only thing that does work is the padding, which it spaces it out properly. However, I am not seeing any space between the padding of each child (margins). Am I doing this correctly, or is there a better way of doing it short of overriding onMeasure to factor in each child's margins?
You had create imageParams but you are not using that parameters in your code instead of imageParams you are using swatchParams parameter. And you had not put a code of swatchParams parameter.