-->

RemoteView setLayoutParams - Change ImageView Size

2019-07-20 20:13发布

问题:

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

回答1:

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

});