marienke
marienke

Reputation: 2475

Position ImageViews with an offset programmatically

I have to create a stack of images programmatically (because they have to be dynamic).

I want to stack ImageViews like this: stack of images

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);
        }

Upvotes: 1

Views: 1405

Answers (1)

devunwired
devunwired

Reputation: 63293

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.

Upvotes: 1

Related Questions