Fitting DialogFragment to image size - android

I have a DialogFragment with a ViewPager that shows some pictures. The problem that there's a weird black stripe on top, and these pictures are deformed.
This is what I currently have, and as you can see, the picture doesn't really look good and there's a weird black stripe on top of the dialog.
This is how it should look, without black stripes and the picture fits the width of the screen.
How could I do this?
Thanks a lot in advance.

To get rid of the black frame at the top, try calling the DialogFragment.setStyle(int style, int theme) method in your DialogFragment.onCreate(Bundle savedInstanceState) method, e.g. setStyle(DialogFragment.STYLE_NO_TITLE, 0) or setStyle(DialogFragment.STYLE_NO_FRAME, 0).
I'm also having problems like you getting a DialogFragment to be a certain width. The layout_width value of my DialogFragment (as specified in my DialogFragment's xml layout file) seems to get overridden somewhere and sometimes my DialogFragment expands and sometimes it shrinks depending on the content. A bit of a hack I know but the best I've been able to come up with is to call the getDialog().getWindow().setLayout(int width, int height) method in my DialogFragment.onResume() method, e.g. getDialog().getWindow().setLayout(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT).
To then resize your images to fit within your DialogFragment, use the ImageView.setScaleType(ImageView.ScaleType scaleType) method as the other answers in this thread have alluded to.

You could set the imageview android:scaleType="centerCrop" or perhaps just setting the height of the viewpager and images to wrap_content.

you should set the attribute android:adjustViewBounds="true" in your imageView

Related

Avoid animation on orientation change to prevent ugly view stretching

Introduction
My app should show a button that fills up the entire screen, but stays quadratic. I have accomplished that by referencing orientation-dependend dimen-values:
activity_main.xml
<ImageButton
android:id="#+id/fartbutton"
android:layout_width="#dimen/fartbuttonWidth"
android:layout_height="#dimen/fartbuttonHeight"
android:layout_gravity="center"
android:src="#drawable/sel_fart_button"
android:scaleType="fitCenter"
android:adjustViewBounds="true"
android:background="#android:color/transparent"
android:clickable="false"/>
dimens-land/dimens.xml
<resources>
<dimen name="fartbuttonWidth">#dimen/wrap_content</dimen>
<dimen name="fartbuttonHeight">#dimen/match_parent</dimen>
</resources>
dimens-port/dimens.xml
<resources>
<dimen name="fartbuttonWidth">#dimen/match_parent</dimen>
<dimen name="fartbuttonHeight">#dimen/wrap_content</dimen>
</resources>
This was to ensure, that the ImageButton couldn't be pressed by touching the top of the screen, which would be far away from the image.
I since have implemented a check to ensure, that the button only reacts to presses on an opaque part of the image, ignoring touch on transparent areas. There this might not be as necessary anymore.
I also have programmed a widget on which I think I'm not able to change the layout programmatically. That's why solutions to the following problem that work entirely within the XML-files are prefered.
The problem
I know that when I change the orientation of my device, the activity gets completely destroyed and recreated. In that process, the OS transitions between the two states with a nice (and wanted) rotation. However, it also stretches and fades the two buttons in an ugly way, as shown in the image.
I assume that it tries to respect the match_parent attribute of the old button and therefore stretches the image to match the full new width.
I already searched for how to disable activity transitions and tried to find an existing solution to my problem. Sadly, since most people would like to add custom animation to orientation changes or disable the rotation animation completely, my searches for this problem haven't been successfull.
Is there an easy way to circumvent this ugly stretching? Would a shared element activity transition work? What solutions come to you mind? :)
Edits
First edit
Seems like setting all dimensions to wrap_content (even that of the FrameLayout) and fixing the button's dimension to 200dp don't work. Now I assume that the OS is simply taking a screenshot and stretching it to the new landscape proportions or vice versa.
Is there a way to disable this behavior? The new button is fully opaque and rotates just fine. It probably would be enough to disable the fading animation.
Second edit
I now noticed this behaviour in all the apps on my phone. I could not find a way to tell Android to just not do it... :(
You can create a square FrameLayout by subclassing FrameLayout and overriding onMeasure:
#Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = MeasureSpec.getSize(heightMeasureSpec);
int size = width > height ? height : width;
setMeasuredDimension(size, size);
}
Then wrap your button in this FrameLayout in your layout.
As Rahil2952 pointed out referring to this answer, there seems to be no solution. It is a "feature" Android provides, over which the programmer does not have easy control.

Android ViewPager center item on screen

I am trying to show a dialog over my screen. And that dialog should have ViewPager in it with FragmentPagerAdapter. Each item in adapter has width set to .7f. What is important to me is that when some item is selected it should be snapped to center of the ViewPager with parts of next and previous fragments visible (exactly as image shows). Unfortunately the default behavior is snap to the left.
Is there any way of achieving it please?
Thank you
(Just if anybody asks: On that picture the ViewPager is not stretched over dialog. In real the dialog matches parent's width and is layouted the way so it doesn't look like it)
Just in case anyone is looking for the same thing, I've come to solution:
Simply set left and right padding to ViewPager and then set clipToPadding to false. That will result into one fragment to be centered and pieces of neighbor fragments in sides as it is in picture. Then to add space between fragments use viewPager.setPageMargin(); in code.
That's it :)
EDIT://
Here is some sample code
<android.support.v4.view.ViewPager
android:id="#+id/viewPager"
android:clipToPadding="false"
android:paddingLeft="40dp"
android:paddingRight="40dp"
android:layout_width="match_parent"
android:layout_height="match_parent" />
ClipToPadding=false ensures that fragments will be drawn even when they are positioned out of the viewPager's content area.
And then in code add spaces between viewPager's items:
mViewPager.setPageMargin(100);
Please note that setPageMargin takes number of pixels as parameter, not number of display points. You probably should convert some dp value to pixels to have correct spacing across all devices. This method should work fine:
public static float dipToPixels(Context context, float dipValue) {
DisplayMetrics metrics = context.getResources().getDisplayMetrics();
return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dipValue, metrics);
}
I was facing a similar issue and no one tried to approach it this way, it might not be completely accurate but visually looks centered.
Use DisplayMetrics to get the device height dimension, and then set the padding for your viewpager as follows:
int height = Resources.getSystem().getDisplayMetrics().heightPixels;
pager.setPadding(0,height/6,0,0);
Note that the layout of the items of the viewpager must be set to "wrap_content" and viewpager in the activity/fragment's height must be "match_parent".
In my case, height/6 as the top padding makes it look centered. Play around with this number for your best results.

Set background behind image

I got a picture that I want to use.
I set it as following:
ImageView menu = new ImageView(this);
menu.setLayoutParams(new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.MATCH_PARENT,
RelativeLayout.LayoutParams.MATCH_PARENT));
menu.setImageResource(R.drawable.menu);
They annoying thing is that I get white pixels on the sides of it cause I want to keep the aspect of the pic.
I can stretch the image by using menu.setScaleType(ScaleType.FIT_XY); but that will make the person on it look really fat. The picture is dark and the pixels are white so they do show quite well. :/
Is there I way I can first apply black color and then the image above that color?
To set a background color to any view on android you can use android:background attribute in layout xml or by calling setBackgroundColor(int id) in java code.
But if you really want just to set the image in bounds you can give a try to android:scaletype="centerCrop"
Using set BackgroundColor will also remove any padding, borders and what not attached to the object.
If that is the result you want, that is a reasonable approach.
If blasting the objects current style will cause problems, I would look to use CSS to set the background color and change the css styles through code if things are happening after page load.
Consider using a border around the image that is colored the way you want to hide what is underneath?

Android: scaling a button with a background image

I'm probably just being daft but my Google searches are not working out well.
I have a bunch of buttons i add in code that all have dynamic text. I've set a background image for each of these buttons since the default greybutton doesn't work well for my application.
This works perfectly and when the text size (or content) changes, the button automatically grows to accommodate the expanded text. What doesn't work is that I'd like the button to scale proportionally - i.e. if the background image is round, i'd like it to stay round rather than oval as the button gets bigger.
With an imagebutton, there is a property "Adjust view bounds" that does exactly this but I cant put text on an imagebutton. Is there something equivalent for a regular button?
or am I going about this wrong?
i also tried setting the width of the button in code, but I can't seem to determine the new height (button.getHeight() returns 0)
ok i found one way to do it...
I modified the patch-9 to have its expandable area be the maximum on both axis.
then used the DisplayMetrics like this:
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
buttonView.setGravity(Gravity.CENTER);
int buttonSize=(int) Math.floor(metrics.density*1.6*fontSize);
buttonView.setWidth(buttonSize);
buttonView.setHeight(buttonSize);
where fontSize is the size of the font in DIP that i'm placing on each button. In this case, since I only have a single letter on each button, i don't need to worry about the text length, but one could obviously tweak this to handle that situation as well.

Moving views inside a layout/view in Android

I have more than one question, but I'll start with the more important and problematic one:
I have a FrameLayout with a ImageView inside it. I need to get the size of the "usable area" of the screen my activity is ocupping, so I set the onSizeChanged on my View (I extended the ImageView class). Everything worked fine here. Now I have a 1000x1000 image that I want to show on the screen, but without scaling. I want it to be clipped, really. If I set the ImageView dimensions using viewObject.setLayoutParams(new Gallery.LayoutParams(1000, 1000)); I get the image being showed correctly, but then the onSizeChanged event returns me always the "1000 x 1000" custom size rather than the real screen size value.
Any ideas of how can I show an image with its real size (no scale!) and still get the view to report the screen available space? I can change the layout as needed as well, of course.
. Amplexos.
Are you asking to get the dimensions of the ImageView? If so then you can get that using getLocalVisibleRect. Here's roughly how it's done:
ImageView yourImageView;
public void onCreate(...){
setContentView(...)
yourImageView = (ImageView) findViewById(...);
(...)
}
getImageViewSize(){
Rect imageViewSize = new Rect();
yourImageView.getLocalVisibleRect(imageViewSize);
// imageViewSize now has all the values you need
Log.d("Your log tag", "ImageView width = " + (imageViewSize.right -
imageViewSize.left));
}
There is however a catch. You have to make sure that you don't try to get the size of the view until after view is finished being laid out on the screen. In other words, if you try to get its size in onCreate, its size will be 0. You have to get it afterwards, for example at the same time as you resize your image, assuming that's done with a button. (If you're using a SurfaceHolder you can also call it during the surfaceCreated callback, but I doubt you're using one of those...)

Categories

Resources