RemoteView setLayoutParams - Change ImageView Size Inside HomeScreen Widget
Asked Answered
I

1

2

My app shows a widget with a total of 8 buttons. I would like to give the user the possibility to style that widget and customize the size of the ImageViews which are below the buttons. The aim is to leave the Buttons as they are, but to change the ImageView sizes dynamically.

For this the User gets to set an icon Size, which is stored in a SharedPreference as an Integer iconSize.

How can I change the size of an ImageView in a Widget?

For now, the ImageViews are created with the size set in the xml file. How can I achieve a redraw with another size?

I assume there is not much code to post here but I will be glad to do so if necessary, just tell me if you have an idea what code could help here.

What I don't want to do:

  • resize the entire widget

  • create tons of layout files to switch according to the iconSize

Some Code:

This is how I set the ImageView size in my activity as a preview of the widget. icons is an array of ImageViews, progress refers to a ProgressBar that is used to choose iconSize.

for (ImageView icon : icons) {
    icon.requestLayout();

    // convert into actual Pixels
    progress = (int) TypedValue.applyDimension(
            TypedValue.COMPLEX_UNIT_PX,
            progress,
            getResources().getDisplayMetrics()
    );

    // set width and height
    icon.getLayoutParams().height = progress;
    icon.getLayoutParams().width = progress;

    sizeText.setText("" + progress);
}
Inform answered 8/4, 2015 at 22:38 Comment(4)
Let's pretend for a moment that rather than doing this in an app widget, you were doing this in an activity or fragment. What exactly would iconSize control? Would you be pulling in different icons that happen to be different sizes, with your android:layout_width and android:layout_height set to wrap_content? Would you be using the same icons, but using android:layout_width and android:layout_height to control the size? Would you be doing something else? That would help us visualize the effect that you are seeking.Greene
@Greene I edited my question and added code to show what happens in the preview of the widget, inside the activity.Inform
Yeah, OK, that's what I was afraid of. I am not aware of a way to affect the LayoutParams in a RemoteViews, other than through the initial load in the constructor.Greene
@Greene I found a workaround, it might also be interesting for you.Inform
I
6

Here is a little workaround I found:

simply use

views.setViewPadding(R.id.vieId, left, top, right, bottom);

(views = RemoteViews)

You just have to make some calculation, so that an iconSize of 100% (of the biggest possible size) equals 0 padding and 1% iconSize equals max padding.

It worked without, too but I think it can'T harm to add the

android:cropToPadding="true"

attribute to ImageViews if you use this method.

Edit:

I forgot to mention that at some point after setting the padding you should update the widget (I do it in onPause() when the user quits the application to look at the widget). Using the setPadding() in an activity will also lead to nowhere without calling invalidate() on the View, to force a redraw/update of it.

Here more code:

seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
    @Override
    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
        // Map the values, 100 is the custom max of my seekBar
        // I am adding 1 to because the seekBar goes from 0-99,
        // but the size from 1% to 100%
        int iconSize  = 100 - (progress+1);

        for (ImageView icon : icons) {
            // set the padding
            icon.setPadding(iconSize, iconSize, iconSize, iconSize);

            // force the ImageView to redraw with the new padding, this
            // serves as a live preview of the icons' sizes.
            icon.invalidate();
        }
    }

    @Override
    public void onStartTrackingTouch(SeekBar seekBar) {
        // you might want to do something here
    }

    @Override
    public void onStopTrackingTouch(SeekBar seekBar) {
        // map the value
        int iconSize = 100 - (seekBar.getProgress()+1);

        // save it in your SharedPreferences or somewhere else
        Utils.setDefaultsInt(Con._ICONSIZE, iconSize, MainPage.this);
    }

});
Inform answered 10/4, 2015 at 11:3 Comment(2)
Bear in mind that you are changing the size of the image, not the size of the button. This is not what you asked for ("I would like to give the user the possibility to... customize the size of those buttons"). If this gives you what you want, though, that's cool.Greene
@Greene That's right, actually I wanted only the image to become smaller, but the button to stay as it is. I will correct this in my question. Thanks again!Inform

© 2022 - 2024 — McMap. All rights reserved.