I have the following code:
llColors = (LinearLayout) findViewById(R.id.llColorSpect);
llColors.setOnTouchListener(llTouch);
width = llColors.getWidth();
height = llColors.getHeight();
Log.i("LAYOUT WIDTH", "width" +width); //shows 0
Log.i("LAYOUT HEIGHT", "height" +h); //shows the correct height
What makes me confused is why is the LAYOUT WIDTH is 0. In the XML, I set the layout width to match_parent and height to wrap_content.
How do I take the Bitmap that I am decoding below and fill in the layout above width fill_parent? Do I use LayoutParams?
bitmap = BitmapFactory.decodeResource(this.getResources(), R.drawable.palette2);
The XML code is this:
<LinearLayout
android:id="#+id/llColorSpect"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#drawable/palette2"
android:layout_alignParentBottom="true" >
</LinearLayout>
What I am trying to accomplish is lehman term is, take the layout and fill it with a background image and use the pixel to get X and Y coordinate.
You are calling getWidth() too early. The UI has not been sized and laid out on the screen yet.
Try getting size after overriding the onWindowFocusChanged() function:
#Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
//Here you can get the size!
}
Have a look at this discussion
If you want your bitmap to match parent height and width you can use this:
LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
imageView.setImageBitmap(bitmap);
imageView.setLayoutParams(params);
Hope this helps :)
As far as the width being 0, the layout may not be finished being drawn yet. I used OnGlobalLayoutListener to know when it had been drawn. Here is a bit of code how I have done it to make my layout a Bitmap so I could print it. A little different but same concept.
#Override
public void onGlobalLayout()
{
String path = null;
try {
path = Environment.getExternalStorageDirectory().getPath().toString();
FileOutputStream out = new FileOutputStream(path + "/testPrint" + "0" + ".png");
Bitmap bm = Bitmap.createBitmap(root.getDrawingCache(), 0, 0,
root.getWidth(), root.getHeight());
bm.compress(Bitmap.CompressFormat.PNG, 90, out);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
where root is the inflated layout that I needed to get the width of.
and you can set the listener with something like
ViewTreeObserver vto = view.getViewTreeObserver();
vto.addOnGlobalLayoutListener((OnGlobalLayoutListener) root.getContext());
OnGlobalLayoutListener Docs
Related
Using the following XML and java code I add images taken with camera to LinearLayout within a ScrollView.
XML:
<HorizontalScrollView
android:layout_gravity="center_vertical"
android:scrollbars="none"
android:layout_width="wrap_content"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/detailsback"
android:layout_gravity="center_vertical"
android:id="#+id/imageSlider"
android:orientation="horizontal" >
</LinearLayout>
</HorizontalScrollView>
Java (runs in Fragment):
private void setTakePicButton(){
mTakePicButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mBitmap = mTextureView.getBitmap();
Date currentDateTime = Calendar.getInstance().getTime();
String filename = getFileName();
FileOutputStream fileOutputStream = null;
try {
fileOutputStream = new FileOutputStream( filename);
mBitmap.compress(Bitmap.CompressFormat.PNG, 100, fileOutputStream);// bmp is your Bitmap instance
ImageView imageView = new ImageView(getActivity());
imageView.setImageBitmap(mBitmap);
linearLayout.addView(imageView);
} catch (Exception e) {
e.printStackTrace();
} finally {
}
}
});
}
Problem is whenever I add a pic to linearLayout (id:imageSlider) it is added with large margins like shows in the picture
I want the images to show in a sequence like in the following pic.
Solution 01
You can set the image to bounds using FIT_XY scale type
imgview.setScaleType(ImageView.ScaleType.FIT_XY);
You can find all the ScaleTypes here
Solution 02
If you are trying to view images like a list you can use a RecyclerView:
Create a List with RecyclerView
Solution 03
If you want to display the images side by side, Set layout_weight to imageView
This is how to do that programmatically, (The Last param is the weight )
LinearLayout.LayoutParams param = new LinearLayout.LayoutParams(
LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT,
1.0f
);
imageView.setLayoutParams(param);
If I understand correctly, the problem is that the image in the bottom is centered instead of outlined to the left? This might be caused by the wrap_content width for the linear layout.
I would also suggest you to use some sort of a list view instead of a LinearLayout and adding items manually. A RecyclerView would be a nice solution and is able to be set to horizontal as well.
Actually I am using Relative layout for image view. This image view is for receiving images from the internet to the application. The thing I need is can I change the image size dynamically for a particular images (say jpeg) and another size for attachments(docx,pdf), etc.
I used if condition for images and another if for attachments. Now how to set image size for receiving images and another image size for receiving attachments. I need to do dynamically. Note I am using only one image view for both images and attachments.
<RelativeLayout>
<ImageView>
id=iv
width=wrap content
height=wrap content
</ImageView>
</RelativeLayout>
for class file
if("image/png"){
iv.setImageResource(R.drawable.abc);
or
code to get images from web
}
else if(mimetype("application/pdf")
{
iv.setImageResource(R.drawable.abc)
}
this is the model
Help me out!
/*
requestLayout()
Call this when something has changed which has
invalidated the layout of this view.
*/
imageView.requestLayout();
imageView.getLayoutParams().height = height;
imageView.getLayoutParams().width = width;
reference : https://android--code.blogspot.com/2015/08/android-imageview-set-width-and-height.html
RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams)imageView.getLayoutParams;
lp.width = x;
lp.height = y;
imageView.setLayoutParams(lp)
try this,
RelativeLayout.LayoutParams params=new RelativeLayout.LayoutParams(width,height);
ImageView ivImage=(ImageView)findViewById(R.id.image);
ivImage.setLayoutParams(params);
Try this code to change image aspect ratio dynamically,
private void setPicDimensions() {
Point screenDimensions = Utils.getScreenDimensions();
width = screenDimensions.x;
height = Utils.getHeightFromAspectRatio(width, 16, 9);// dynamically set aspect ratio value here its 16:9
}
// in your image view set layout params dynamically whereever you need to change
//Declare height and width as int and iv_pic as imageview
LayoutParams layoutParams = iv_offer_pic.getLayoutParams();
layoutParams.height = height;
layoutParams.width = width;
iv_pic.setLayoutParams(layoutParams);
most important is:
<imageview android:scaleType="fitXY" />
<RelativeLayout>
<ImageView>
id=iv
android:scaleType="fitXY"
width=wrap content
height=wrap content
</ImageView>
</RelativeLayout>
for class file
if("image/png"){
iv.setImageResource(R.drawable.abc);
or
code to get images from web
RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams)imageView.getLayoutParams;
lp.width = 100;
lp.height = 100;
imageView.setLayoutParams(lp)
}
else if(mimetype("application/pdf")
{RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams)imageView.getLayoutParams;
lp.width = 50;
lp.height = 50;
imageView.setLayoutParams(lp)
iv.setImageResource(R.drawable.abc)
}
this is the model
Help me out!
LayoutParams params = new FrameLayout.LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
imageView
mainimage = new ImageView(HLActivity.this);
mainimage.setLayoutParams(params);
loader.DisplayImage(_pageslist.get(j).getUrl(), mainimage);
I already tried mainimage.getwidth() and mainimage.getHeight();
Now i want to findout the orignalwidth and height of the ImageView after
place the image in the imageview. can you please help me.
getWidth() and getHeight() are the indeed ones you are looking for, but you are trying to ask for the width and the height when the view is not measured yet. To fix this, we post a message to the ImageView, which will get executed after the measurement is done.
LayoutParams params = new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
// mark it as final, so it can be accessed in the runnable.
final imageView mainimage = new ImageView(HLActivity.this);
mainimage.setLayoutParams(params);
mainimage.post(new Runnable() {
#Override
public void run() {
// get the width and the height
int width = mainimage.getWidth();
int height = mainimage.getHeight();
// do what you want to do with the sizes.
loader.DisplayImage(_pageslist.get(j).getUrl(), mainimage);
}
});
I want to put 8 image thumbs in one horizontal line, using the whole available width.
The images are retrieved from a webservice which lets me specify the dimensions.
I tried the following:
int widthPx = container.getWidth();
LinearLayout thumbs = (LinearLayout)curView.findViewById(R.id.thumbs);
for(int i=0; i<pics.length; i++) {
ImageView iv = new ImageView(mContextt);
int thumbSize = widthPx / 8;
try {
String url = "http://someurl/" + pics[i] + "&width=" + thumbSize + "&height=" + thumbSize;
URL imgUrl = new URL(url);
Drawable imgD = Drawable.createFromStream(imgUrl.openStream(), "src");
iv.setImageDrawable(imgD);
}
catch (Exception e) {
Log.e(TAG, "loading image failed");
e.printStackTrace();
}
thumbs.addView(iv);
}
The LinearLayout thumbs has android:layout_width="fill_parent set. The thumbs produced by this code are significantly smaller then 1/8 of the width. Why is this? What would be the correct way?
Update:
This code is inside onCreateView of a Fragment. While my width value is calculated based on the root-view and is correct, thumbs.getWidth() returns 0, although the view is inflated before and should also have a width of 480 because of layout_width is set to fill_parent. I'm not sure if that's a problem.
Is my assumption correct that the layout of the created ImageViews is set to wrap_content by default? If not, how to set this with Java code?
Add the ImageViews with a fixed size, i.e.:
thumbs.addView (iv, new LayoutParams(thumbSize, thumbSize));
To answer (partially) the questions in the comments:
The ImageView API says:
takes care of computing its measurement from the image so that it can be used in any layout manager
so it is probably assuming 60px for a 160 dpi (I may be wrong there).
I'd suggest using this:
widthPx = getWindowManager().getDefaultDisplay().getWidth();
In my Android App I have a Activity which show images which have following size 244 x 330.
I want to show those images in full device width.
My layout file looks like this:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<ImageView android:id="#+id/news_image"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:layout_marginLeft="18dip"
android:layout_marginRight="18dip"
android:background="#aaaaaa" />
</LinearLayout>
</ScrollView>
I tried to set the ScaleType of the ImageView but there is no ScalingType which scales the ImageView proportional.
How can I scale the image proportionally to fit the whole screen in landscape mode AND portrait mode?
Basically what I want is something like ScaleType.CENTER_CORP but which also sets the proportional height for the image so I can see all of it and not just a part of the image.
Edit cause I know I'm confusing you with my "weird" questing.
I want to show it to you with a image.
This is what I get at the moment with my layout. I want to fill the whole grey area by scaling the image as big as needed. How can I accomplish that?
When I set the ScaleType to CENTER_CROP I get this
but this is not what I want cause you are not seeing the whole image just a part from the center.
And this is what I want it to be:
I hope this helps you to understand what I'm trying to accomplish.
Anyone knows how to do that?
Edit 2:
It might look weird and little confusing that I'm trying to display a image which is bigger in the height than the screen size but since I'm using a ScrollView in my example layout this should be ok and the user could scroll if he want to see the not displayed area.
Hope this helps to understand what I'm trying to do.
I tried really every ScaleType in my ImageView with fill_parent and wrap_content but no of them worked. I also tried everything what I found on Google but nothing worked for me either so came up with something on my own.
It was clear that the ImageView is not scaling my image like I wanted to be scaled so I had to scale it on my own. After scaling the bitmap I would set the new Bitmap as the image source to the ImageView. This works pretty good and looks very good on the G1 and on the Motorola Milestone 2.
And here is all pieces of my code
Layout:
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/news_wrapper">
<ImageView android:id="#+id/news_image"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:layout_marginLeft="18dip"
android:layout_marginRight="18dip"
android:background="#aaaaaa" />
</LinearLayout>
</ScrollView>
Activity
public class ScalingImages extends Activity {
private ImageView imageView;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.test_margin);
this.imageView = (ImageView)findViewById(R.id.news_image);
// The image is coming from resource folder but it could also
// load from the internet or whatever
Drawable drawable = getResources().getDrawable(R.drawable.img);
Bitmap bitmap = ((BitmapDrawable)drawable).getBitmap();
// Get scaling factor to fit the max possible width of the ImageView
float scalingFactor = this.getBitmapScalingFactor(bitmap);
// Create a new bitmap with the scaling factor
Bitmap newBitmap = Util.ScaleBitmap(bitmap, scalingFactor);
// Set the bitmap as the ImageView source
this.imageView.setImageBitmap(newBitmap);
}
private float getBitmapScalingFactor(Bitmap bm) {
// Get display width from device
int displayWidth = getWindowManager().getDefaultDisplay().getWidth();
// Get margin to use it for calculating to max width of the ImageView
LinearLayout.LayoutParams layoutParams =
(LinearLayout.LayoutParams)this.imageView.getLayoutParams();
int leftMargin = layoutParams.leftMargin;
int rightMargin = layoutParams.rightMargin;
// Calculate the max width of the imageView
int imageViewWidth = displayWidth - (leftMargin + rightMargin);
// Calculate scaling factor and return it
return ( (float) imageViewWidth / (float) bm.getWidth() );
}
}
Util class
public class Util {
public static Bitmap ScaleBitmap(Bitmap bm, float scalingFactor) {
int scaleHeight = (int) (bm.getHeight() * scalingFactor);
int scaleWidth = (int) (bm.getWidth() * scalingFactor);
return Bitmap.createScaledBitmap(bm, scaleWidth, scaleHeight, true);
}
}
If there is an better or more accurate way to accomplish the same scaling please let me know because I can't believe that such a trivial thing is so hard to accomplish.
I'm really hoping to see a better way to do this.
Thank you for reading.
the easiest way is to add android:adjustViewBounds="true" to the ImageView and set the scale type to "fitCenter"
Slightly confused on what you're looking for, exactly. If you're scaling to fit the screen, you have three options, two of which are viable if you're keeping proportions. You can use ScaleType fitCenter, which will make the image fit within the bounds proportionally, or you can use centerCrop (which you said you tried), which will stretch the shortest side of the image to fit the container (meaning some will get cropped off on the longer dimension). You can't have it stretch to fit the width AND height without either cropping, or stretching disproportionately.
EDIT: Okay, I think I get your point now. First, I'd set your LinearLayout to wrap_content for the height. Second, in code, here's one way you can do it that I can think of. There's probably also another way you could do it by first getting the screen dimensions, and then doing createScaledBitmap with the new dimensions, and then setting the background resource.
final ImageView newsImage = (ImageView)findViewById(R.id.news_image);
//get details on resolution from the display
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
//going to set what happens as the layout happens
newsImage.getViewTreeObserver().addOnGlobalLayoutListener(
new ViewTreeObserver.OnGlobalLayoutListener() {
public void onGlobalLayout() {
int oldHeight, oldWidth, newHeight, newWidth;
//we want the new width to be as wide as the screen
newWidth = metrics.widthPixels;
oldHeight = newsImage.getDrawable().getIntrinsicHeight();
oldWidth = newsImage.getDrawable().getIntrinsicWidth();
//keeping the aspect ratio, the new height should be w1/h1 = w2/h2
newHeight = Math.floor((oldHeight * newWidth) / oldWidth);
LinearLayout.LayoutParams params =
(LinearLayout.LayoutParams)newsImage.getLayoutParams();
params.height = newHeight;
params.width = newWidth;
newsImage.setLayoutParams(params);
newsImage.setScaleType(ScaleType.CENTER);
newsImage.invalidate();
newsImage.getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
}
}
I googled everywhere and could not find a solution.
Here is what I did, that worked for me and with a scroll view.
XML file:
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true" >
<ImageView
android:id="#+id/manga_page_image"
android:layout_width="match_parent"
android:layout_height="0dp"
android:adjustViewBounds="true"
android:scaleType="fitCenter" />
</ScrollView>
Have you tried setting it programmatically via ImageView.setScaleType()?
setAdjustViewBounds( false ) might help as well.
Edit: sorry, I mis-read the question. Regardless, setAdjustViewBounds() still might help. Never used it though.
I want to show those images in full
device width.
This is simple. You just have the wrong margin settings. Remove these lines and your image will show in full device width:
android:layout_marginLeft="18dip"
android:layout_marginRight="18dip"
I don't see the images anymore and the question is old but just in case someone else finds this and has the same problem. Wouldn't it be better to just get float screenWidth = getResources().getDisplayMetrics().widthPixels and set the ImageView LayoutParamters programmatically to scale the image to screenWidth. Just an idea !!
manage to achieve what I wanted, which hopefully is the same as your aim:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.pgviewer);
ImageView PgContainer = (ImageView)findViewById(R.id.imageView1);
String Page = String.valueOf(getIntent().getExtras().getInt("Page"));
try {
PgContainer.setImageBitmap(getBitmapFromAsset(Page));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
PgContainer.setScaleType(ScaleType.FIT_CENTER);
PgContainer.scrollTo(0, 0);
PgContainer.setScrollBarStyle(0);
}
then to scale the bitmap:
private Bitmap getBitmapFromAsset(String strName) throws IOException
{
AssetManager assetManager = getAssets();
InputStream istr = assetManager.open(strName+".png");
Bitmap bitmap = BitmapFactory.decodeStream(istr);
float screenWidth = getResources().getDisplayMetrics().widthPixels;
int ih=bitmap.getHeight();
int iw=bitmap.getWidth();
float scalefactor = screenWidth/iw;
//w = 480, h=~
//int newh = bitmap.getHeight()/bitmap.getWidth();
return android.graphics.Bitmap.createScaledBitmap(bitmap, (int)(iw*scalefactor), (int)(ih*scalefactor), true);
//return bitmap;
}
One of the ways to do it is by setting android:adjustViewBounds="true" to the ImageView and set the scale type to "fitCenter" in the xml file.
This should work as expected.
You can also do this programatically by setting ImageView.adjustViewBounds(true) and ImageView.setScaleType(ScaleType.FIT_CENTER).