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...)
Related
I have a number of shared elements that I'm transitioning between two activities via ActivityOptions.makeSceneTransitionAnimation. When I enter the second activity, I would like to determine what the final target size that the ImageView will be so I can set the appropriate width of the ImageView. I believe that doing so will allow the object to the right of it (also a shared element) to transition smoothly.
The ImageView is a fitStart scaleType with a fixed height and a wrap_content width. The image will be dynamically loaded and is being shrunk down from the first activity to the second, so I don't know the final width. Before the transition starts, I want to set the ImageView's LayoutParams width to match the final width that it will be after the transition ends.
Currently, the wrap_content property of this ImageView is causing the element to the right of it to not know where its final resting place will be, so it goes off the screen to the right before coming back in and landing in the right place.
Here's a gif of the animation. FIRST ELEMENT is the ImageView, animating correctly, and Second Element is the button to the right of the ImageView:
Notice that when the second activity goes back to the first activity, the Second Element transitions smoothly back to the left of the screen because the end position is known.
When I give the ImageView a specific width like 100dp instead of wrap_content (and then change it back to wrap_content after the transition finishes), Second Element moves more smoothly to its final resting place, but since the ImageView will be dynamically loaded and scaled, I won't know the true width of the image in XML beforehand so there would always be a jerky movement of the Second Element when I change it to wrap_content after the transition.
So I would like to determine the target width of the ImageView and set it programmatically before the transitions begin in the second activity so that Second Element knows how far to the left it needs to go. I've tried playing with ViewTreeObserver and TransitionValues but am missing how to get the final width the ImageView is transitioning to.
Is there something I can call in onCreate of the second activity to determine what width the ImageView will end up at after the transition?
EDIT
I tried the solution in this answer but it's reporting back the ImageView's beginning width, not the final width it's transitioning to. For reference, these are the layouts of the two activities I'm switching between:
Note that I'm moving AND shrinking the ImageView.
I tweaked the answer's code since I'm not using the support library and had to move to imageView.getViewTreeObserver() in the onPreDraw() call to avoid an IllegalStateException:
postponeEnterTransition();
final ImageView imageView = (ImageView) findViewById(R.id.image_view);
final ViewGroup.LayoutParams imageViewLayoutParams = imageView.getLayoutParams();
final ViewTreeObserver viewTreeObserver = imageView.getViewTreeObserver();
viewTreeObserver.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
#Override public boolean onPreDraw() {
imageView.getViewTreeObserver().removeOnPreDrawListener(this);
// You can acquire the width here
logoLayoutParams.width = imageView.getWidth();
Log.i(TAG, "width is " + imageViewLayoutParams.width);
imageView.setLayoutParams(imageViewLayoutParams);
// `imageView` has been laid out, but not yet been drawn
startPostponedEnterTransition();
return true;
}
});
The log is reporting a width of 998, which is the larger size of the imageView in Activity 1 (its starting size before the transition). So the Second Element is still flying off the screen.
Now that I have this code in place, I can use the aspect ratio information of the larger image to figure out the final width that the smaller image will be since I know the final height, but is that guaranteed with the fitStart scaleType?
It would be really nice to know if Android can tell me the final size the shared element targeting.
Here's the case: if you change in the second activity the resource from #drawable/first_element to #drawable/first_element_thumb, you'll no long experience that behavior. The downside is, that you'll see a glitch each time the transition is starting, that's because the drawable is being changed from high resolution to a low resolution right before transition starts.
Here's with 300ms animation time:
Here's with 5000ms animation time:
If you want the transitioning to be without that glitch, than the solution is to start the transition from high resolution drawable and substitute that drawable to a low resolution whilst transitioning the view. You can see Nick Butcher describing the feature in his "Animatable" talk. You'll end up writing your custom transition class like this one.
I know there are lots of questions like these. However, they all seek to bring imageView on full screen after clicking.
I want to bring an imageView on Full Screen without clicking on it. In other words, when I click my bitmap, I should get a full-screen imageView. I tried a lot but could not achieve desired results.
So far, I have tried this thread's all possible solutions.
Moreover, I tried to use multiple scaling options.
I am self-learning android using a big nerd's ranch guide. I am attaching my code and images below
public View onCreateView(LayoutInflater inflater,
ViewGroup parent, Bundle savedInstanceState) {
imageView=new ImageView(getActivity());
String path= (String) getArguments().getSerializable(FILE_PATH_NAME);
BitmapDrawable image = PictureUtils.getScaledDrawable(getActivity(), path);
float rotation= rotateImage(getActivity(), path);
Log.i("RotateImagee", "Rotate valuee: " + rotation);
imageView.setRotation(rotation + 90);
imageView.setImageDrawable(image);
imageView.setScaleType(ImageView.ScaleType.FIT_XY);
imageView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
return imageView;
}
Images:
I want screen fully covered with this image with a proper scaling. Therefore, please show me an appropriate solution with proper scaling.
You can use only one scaletype and CENTER_INSIDE overrides FIT_XY.
Use only FIT_XY.
Senconly when you create your ImageView you don't give it layoutparams(default is wrap_content), so you need to set layoutparams to match_parent. Without it imageView will change size to wrap_content and FIT_XY will not take affect.
Here is a link if you want to make activity full screen.
you also need to remove ActionBar, Here.
The fact that the background and Toolbar are greyed-out makes me think you are displaying your ImageView inside a DialogFragment, not a normal Fragment. DialogFragments are a bit different. Getting them to display full screen is a non-trivial task. If you are not trying to display a Dialog then I suggest using a normal Fragment to display the ImageView.
Side notes:
consider rotating the Bitmap, not the ImageView
consider putting the ImageView in a layout file and inflating that layout file (you already have a LayoutInflater passed to you in onCreateView)
I'm trying to place a small image on the top of a big one in a custom dialog.
I want the small one to be placed in a different place depending on a variable, which I called "pos". It contains a int value from 0 to 100, meaning percentage of the dialog width.
If pos = 0, I want to place the image in the left margin of the big one, if pos = 30 it should be placed in the 30% of the screen, starting from the left.
If pos = 50 I want it to able placed right in the middle, being 100 the maximum value for it and placing it in the right margin.
I include a draft to explain myself a bit better.
I tried with RelativeLayout.LayoutParams but I never get expected output.
Perhaps a simpler strategy is to extend ImageView, then create a custom image using Canvas commands in the onDraw method that draw the bitmap appropriately on the x axis with a background set to match your layout.
You can determine the width of the custom dialog in the the onMeasure method of your custom ImageView, so the returned bitmap (including empty background) can be the correct width, and the position of the smaller bitmap can be correctly apportioned.
Once you've created the class, which will take just a few minutes, you can add it to your XML layout with something like:
<com.domain.yourapp.YourCustomerImageView
android:id="#+id/bitmap_graph"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="3dp"/>
I have to set an image in my activity and in my scenario the image covers fairly large portion of the activity. However I want to keep its width/height to be no more than 33% of its parent viewGroup's width.
I am dynamically changing the ImageView's dimension at runtime using this code.
#Override
protected void onResume() {
super.onResume();
//try to resize the imageview according to current width of container layout
int nWidthPix = findViewById(R.id.layout_info).getWidth();
ImageView imView = (ImageView)findViewById(R.id.imageView_main);
imView.setAdjustViewBounds(true);
int imViewWidth = nWidthPix/3;
imView.setMaxWidth(imViewWidth);
imView.setMaxHeight(imViewWidth);
//
}
The problem is that nWidthPix which is width of RelativeLayout which contains my ImageView is returned 0 in the first call to onResume() that is when the app is launched for first time. As a result image is not shown , in the subsequent calls to onResume() it returns 720 which is correct.
I am guessing that since the view is not really shown yet before the first call on onResume it does not know the width ? but then we can find views on the other hand even before the activity is shown for the first time. .. Not sure what's causing it.
Help
You can use the ViewTreeObserver of the root layout and set an OnGlobalLayoutListener to know when the layout finishes loading. Take a look at this answer for a reference.
View always report 0 as their width and height before they've been measured by the framework. onResume() is too soon to query this information, unfortunately.
If the parent view is the Activity itself, then you can get the window's dimensions (for example with this method) and use those values. Otherwise you need to postpone execution of this code until the layout pass is complete (via an OnGlobalLayoutListener).
Is there a way the this problem can be fixed? I tried invalidate() but, it still displays the same problem. What happens is that, after opening the page/ the Activity, the images behaves like the one in Figure A. It only renders to my desired layout (Figure B) after scrolling it back and forth.
What I'm trying to do is set the width and heigth of the image during runtime. So this is also in relation to my previous questions : Images in my HorizontalListView changes it size randomly and ImageView dynamic width and height which received a very little help.
Any tips regarding this matter, please?
EDIT: btw, my classes are:
MyCustomAdapter (extends baseadapter, this calls the displayimage() from ImageLoader ),
MyActivity and
ImageLoader (this is where my image url are loaded, decoded, displayed asynchronously)
Im also confused as to where i will set the height and width of the imageView. For now, i set it at ImageLoader. It was okay. but i dont know if i did the right thing.
If you want to set the width and height manually at runtime, grab a reference to the ImageView's LayoutParams AFTER the View has been measured by the layout system. If you do this too early in the rendering phase, your view's width and height as well as its parent view and so on will be 0.
I have some code in an open source library that might help you. The process is two parts:
Set up an OnPreDrawListener attached to the ViewTreeObserver for your control. My example does this inside of a custom control, but you can do this in your activity as well.
Inside the onPreDraw method, your image and it's parent will now have their width and height values assigned to them. You can make your calculations and then set your width and/or height manually to the LayoutParams object of your view (don't forget to set it back).
Check out this example where I'm applying an aspect ratio to a custom ImageView just before it's rendered to the screen. I don't know if this exactly fits your use case, but this will demonstrate how to add an OnPreDrawListener to a ViewTreeObserver, removing it when you're done, and applying dynamic sizing to a View at runtime
https://github.com/aguynamedrich/beacon-utils/blob/master/Library/src/us/beacondigital/utils/RemoteImageView.java#L78
Here's a modified version that removes my particular resizing logic. It also grabs the ViewTreeObserver from the imageView, which is a more likely scenario if you're not implementing a custom control and you only want to do this in the Activity
private void initResizeLogic() {
final ViewTreeObserver obs = imageView.getViewTreeObserver();
obs.addOnPreDrawListener(new OnPreDrawListener() {
public boolean onPreDraw() {
dynamicResize();
obs.removeOnPreDrawListener(this);
return true;
}
});
}
protected void dynamicResize() {
ViewGroup.LayoutParams lp = imageView.getLayoutParams();
// resize logic goes here...
// imageView.getWidth() and imageView.getHeight() now return
// their initial layout values
lp.height = someCalculatedHeight;
lp.width = someCalculatedWidth;
imageView.setLayoutParams(lp);
}
}