I have some pictures stored on internal storage, that have different sizes and i would like to show it inside a scrollview contains imageview. I would that in each dimension case (image wider than higher, image higher than wider, squared image) image occupy entire screen width.
But code i've write for do that doesn't work well. If an image is squared or higher than wider everithing works well, but not if image is wider than higher.
this is xml of scrollview
<RelativeLayout
....
>
<ScrollView
android:id="#+id/scrollView"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:id="#+id/linearInsideScroll"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" />
</ScrollView>
</RelativeLayout>
and this is xml of single imageView that i will inflate inside layout:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<!--
othed widget
-->
<ImageView
android:id="#+id/picture"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</RelativeLayout>
and this is how i fill my view (pics is a list object contains image informations):
LinearLayout linearLayout = (LinearLayout) findViewById(R.id.linearInsideScroll);
for (int i = 0; i < pics.size(); i++) {
View new_element = inflater.inflate(R.layout.single_element, null,
false);
if (pics.get(i).getWidth() > pics.get(i).getHeight()) {
imageView.getLayoutParams().width = width_px;
imageView.getLayoutParams().height = LayoutParams.WRAP_CONTENT;
} else if (pics.get(i).getWidth() < pics.get(i).getHeight()) {
imageView.getLayoutParams().height = height_px;
imageView.getLayoutParams().width = LayoutParams.MATCH_PARENT;
}
else {
imageView.getLayoutParams().height = width_px;
imageView.getLayoutParams().width = width_px;
}
linearLayout.addView(new_element);
}
For the imageView, set scaleType.
http://developer.android.com/reference/android/widget/ImageView.ScaleType.html
Related
I prepared a layout with 2 images of same size in a vertical LinearLayout so both appear with exact same size in AS.
The layout is as follow:
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="#+id/frame_container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/partner_background"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitXY"
android:src="#drawable/fake_background" />
<LinearLayout
android:id="#+id/partner_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:padding="0dp">
<ImageView
android:id="#+id/imageGuide"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:contentDescription="#string/logo_Site"
android:scaleType="centerInside"
android:src="#drawable/my_logo"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true" />
</RelativeLayout>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/partner_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:padding="0dp"
>
<ImageView
android:id="#+id/partner_logo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_gravity="center_horizontal"
android:contentDescription="#string/logo_Site"
android:scaleType="centerInside"
android:src="#drawable/my_logo" />
</RelativeLayout>
</LinearLayout>
</FrameLayout>
<ListView android:id="#+id/left_drawer"
android:layout_width="300dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:choiceMode="singleChoice"
android:divider="#android:color/white"
android:dividerHeight="1dp"
android:background="#F2F2F2"/>
<ListView android:id="#+id/right_drawer"
android:layout_width="300dp"
android:layout_height="match_parent"
android:layout_gravity="end"
android:choiceMode="singleChoice"
android:divider="#android:color/white"
android:dividerHeight="1dp"
android:background="#F2F2F2"/>
</android.support.v4.widget.DrawerLayout>
The RelativeLayouts are here because I will have some other objects in.
If I execute it on my device, everything is ok, I get the exact same rendering.
But now, I want to change the bottom logo with one downloaded from my server.
I download the exact same image and then, I set it like that:
ImageView partnerLogo = (ImageView) findViewById(R.id.partner_logo);
file = new File(getApplicationContext().getFilesDir(), "/partner/partnerLogo.png");
uri = Uri.fromFile(file);
bitmap = null;
try {
bitmap = MediaStore.Images.Media.getBitmap(getApplicationContext().getContentResolver(), uri);
} catch (IOException e) {
e.printStackTrace();
}
if (bitmap != null) {
partnerLogo.setImageBitmap(bitmap);
}
When I look at bitmap in the debugger, the image is 512x512 as expected.
But the result is that one:
Could you tell me why the layout is modified?
Edit
I made some tests to try to set both images programmatically and I discovered that using:
try {
bitmap = MediaStore.Images.Media.getBitmap(getApplicationContext().getContentResolver(), uri);
} catch (IOException e) {
e.printStackTrace();
}
if (bitmap != null) {
partnerLogo.setImageBitmap(bitmap);
}
set an image smaller than using:
partnerLogo.setImageDrawable(getResources().getDrawable(R.drawable.my_logo));
But both images are exactly the same PNG images!?!
So I think the problem comes from setImageBimap() and not from the layout.
EDIT 2
According to many post about similar problems, it seems that Android needs a drawable to be able to scale it as needed.
That would confirm my experiment given in first EDIT.
So I tried that:
ImageView partnerLogo = (ImageView) findViewById(R.id.partner_logo);
file = new File(getApplicationContext().getFilesDir(), "/partner/partnerLogo.png");
uri = Uri.fromFile(file);
BitmapDrawable drawable = null;
try {
bitmap = MediaStore.Images.Media.getBitmap(getApplicationContext().getContentResolver(), uri);
if (bitmap != null) {
drawable = new BitmapDrawable(getResources(), bitmap);
}
} catch (IOException e) {
e.printStackTrace();
}
if (bitmap != null) {
partnerLogo.setImageDrawable(drawable);
}
But that doesn't work better !?!
On your layout on the LinearLayout add android:weightSum="2"
On your both RelativeLayout containing a ImageView change android:layout_height="wrap_content" to android:layout_height="0dp"
But those RelativeLayout are superfluous you can remove it and put on the ImageView's
android:layout_height="0dp"
android:layout_weight="1"
This ensures that the vertical space will be divided between the two images
Just modified relevant code. Add it and check.
Modification Like:
Adding weightSum to LinearLayout
Giving equal weight to the LinearLayout's immediate children
Modified your LinearLayout (partner_layout ).
This is just modified piece of your XML file.
<LinearLayout
android:id="#+id/partner_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:weightSum="1"
android:orientation="vertical">
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.5"
android:padding="0dp">
<ImageView
android:id="#+id/imageGuide"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:contentDescription="#string/logo_Site"
android:scaleType="centerInside"
android:src="#drawable/my_logo"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true" />
</RelativeLayout>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/partner_container"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.5"
android:padding="0dp">
<ImageView
android:id="#+id/partner_logo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_gravity="center_horizontal"
android:contentDescription="#string/logo_Site"
android:scaleType="centerInside"
android:src="#drawable/my_logo" />
</RelativeLayout>
</LinearLayout
Our first aim should be how to resolve the issue.It seems that it could be handled by your xml layout.
So in my suggestion if you are using relative layout try to fix width and height of your imageView.
Other wise try some other layout like tableLayout, frameLayout or gridLyout and try to change width and height of your imageview with various available option(match_parents/wrap_content etc or also try with fix size).and also add
android:scaleType="fitXY"
Hope this will resolve your issue.
When You set Images from Drawable then Android system Automatically resize that image accrding available width and height but when you set Any image using setImageBitmap() method it dose not resize and actual image shown.
Although the system performs scaling and resizing to make your
application work on different screens, you should make the effort to
optimize your application for different screen sizes and densities. In
doing so, you maximize the user experience for all devices and your
users believe that your application was actually designed for their
devices—rather than simply stretched to fit the screen on their
devices.
Find your solution and more details regarding Images,Bitmap scaling and resizing ,drawables in below links :
How to stop Android form automatically scaling drawables?
Supporting Multiple Screens
So the only solution I found is to scale the image by hand, based on the layout built with fake images.
And the code is based on the one found quiet a long time ago somewhere in SO:
final ImageView myLogo = (ImageView) findViewById(R.id.image_logo);
bitmap = BitmapFactory.decodeResource(getApplicationContext().getResources(), R.drawable.my_logo_512x512);
final ImageView partnerLogo = (ImageView) findViewById(R.id.partner_logo);
file = new File(getApplicationContext().getFilesDir(), "/partner/partnerLogo.png");
uri = Uri.fromFile(file);
try {
bitmap2 = MediaStore.Images.Media.getBitmap(getApplicationContext().getContentResolver(), uri);
} catch (IOException e) {
e.printStackTrace();
}
if (bitmap != null) {
ViewTreeObserver vto = myLogo.getViewTreeObserver();
vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
public boolean onPreDraw() {
myLogo.getViewTreeObserver().removeOnPreDrawListener(this);
finalHeight = myLogo.getMeasuredHeight();
finalWidth = myLogo.getMeasuredWidth();
pictureWidth = bitmap.getWidth();
pictureHeight = bitmap.getHeight();
float ratioImage = (float)pictureWidth / (float)pictureHeight;
float ratioView = (float)finalWidth / (float)finalHeight;
if (ratioView > ratioImage) { // finalHeight is the limit
finalWidth = (int)((float)pictureWidth * ((float) finalHeight / (float) pictureHeight));
} else { // finalWidth is the limit
finalHeight = (int)((float)pictureHeight * ((float) finalWidth / (float) pictureWidth));
}
bitmap = Bitmap.createScaledBitmap(bitmap, finalWidth, finalHeight, false);
myLogo.setImageBitmap(bitmap);
if (bitmap2 != null) {
bitmap2 = Bitmap.createScaledBitmap(bitmap2, finalWidth, finalHeight, false);
partnerLogo.setImageBitmap(bitmap2);
}
return true;
}
});
}
I saw that a comic downvoted my question, I hope that next time he will motivate it.
I know there are lots of question about this topic. But still I need help. I want to show my ImageView has equal width and height in my TableLayout. But on different devices I couldn't be able to do this.
Here is I get the image using URL in AsyncTask, and set the ImageView on onPostExecute method.
protected Bitmap doInBackground(String... urls) {
String urldisplay = urls[0];
Bitmap mIcon11 = null;
try {
InputStream in = new java.net.URL(urldisplay).openStream();
mIcon11 = BitmapFactory.decodeStream(in);
} catch (Exception e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return mIcon11;
}
protected void onPostExecute(Bitmap result) {
// set the imageview
bmImage.setImageBitmap(result);
}
Here is my XML file (news.xml) where my ImageView located
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingRight="10dp"
android:paddingEnd="10dp"
android:layout_marginRight="10dp"
android:layout_marginEnd="10dp"
android:paddingBottom="10dp"
android:id="#+id/mylayout"
>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/image"
android:clickable="true"
android:background="#drawable/border"/>
<TextView
android:layout_width="match_parent"
android:layout_height="75dp"
android:maxLines="4"
android:id="#+id/text"
android:layout_below="#+id/image"
android:layout_alignEnd="#+id/image"
android:layout_alignRight="#+id/image"
android:clickable="true"
android:textSize="18sp"
android:background="#e3e3e3"
android:paddingTop="10dp"
android:gravity="center_vertical"
/>
</RelativeLayout>
I thought that I can create a TableLayout, and locate the View (above) inside a TableRow like, side by side 2 view.(view is above)
To do this I get the screen width and subtract the paddings and divide by 2 and give that width to the ImageView to be able to get same size for all image views.
Here is my code,
DisplayMetrics metrics = new DisplayMetrics();
getActivity().getWindowManager().getDefaultDisplay().getMetrics(metrics);
screenWidth = metrics.widthPixels;
tableLayout = (TableLayout) view.findViewById(R.id.tableLayout);
Log.e("screenwidth",":"+screenWidth);
// here is my paddings converted to pixel and will be subtracted from screen width
int pixValue = (int) (20 * Resources.getSystem().getDisplayMetrics().density);
int imageWidthPix = ( screenWidth - pixValue ) / 2;
Log.e("imageWidthPix ",":"+imageWidthPix );
for (int i = 0; i < categoryNews.get(myString).size(); i++) {
if (i % 2 == 0) {
tr = new TableRow(getActivity());
tableLayout.addView(tr);
}
//here is where my ImageView layout (news.xml)
View oneNews = inflater.inflate(R.layout.news, null);
ImageView imageView = (ImageView) oneNews.findViewById(R.id.image);
TextView textView = (TextView) oneNews.findViewById(R.id.text);
//here I set the width as I want
imageView.setLayoutParams(new RelativeLayout.LayoutParams(imageWidthPix, RelativeLayout.LayoutParams.WRAP_CONTENT));
String imagePath = "http://my.url.com/" + categoryNews.get(myString).get(i).getImagePath();
new DownloadImageTask(imageView,getActivity().getApplicationContext())
.execute(imagePath);
I got the perfect result on my phone. But on the different device which has different screen size, ImageView has spaces on top and bottom. I tried to convert nine patch chunk and convert that into again bitmap but there were no difference. If I wouldn't get the images from web service, I would put other resolution images into mipmap-hpdi, mipmap-mdpi etc folders and there would be no error. But I am getting images dynamically so how can achieve that ImageView has half of screen width?
Thanks in advance.
Here I have edited your xml
Try Linear layout with weights,change the weight according to your need, change the layout_weight to make your image view and textview smaller or larger.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingBottom="10dp"
android:orientation="vertical"
android:id="#+id/mylayout"
android:weightSum="10">
<ImageView
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="3"
android:id="#+id/image"
android:src="#drawable/sd"
android:clickable="true"/>
<TextView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:maxLines="4"
android:id="#+id/text"
android:clickable="true"
android:textSize="18sp"
android:background="#e3e3e3"
android:paddingTop="10dp"
android:gravity="center_vertical"
/>
</LinearLayout>
I have a Horizonal scroll view with Images. Then the output is this.
I loaded 2 same pictures but the Gap is too much.
I just want it to make like 5Margins on left but didn't get the result.
Here's my Code.
<HorizontalScrollView
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_marginBottom="1dp"
android:background="#FFF"
android:scrollbars="none"
>
<LinearLayout
android:id="#+id/imgLayout"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="horizontal"
>
</LinearLayout>
</HorizontalScrollView>
And here is my code of Adding imageviews to linear layout.
public void setImageViews() {
LinearLayout linearLayout = (LinearLayout) findViewById(R.id.imgLayout);
LinearLayout.LayoutParams parms = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT);
parms.setMargins(5,5,5,5);
for(int i=0;i<6;i++){
ImageView imageView =new ImageView(this);
imageView.setLayoutParams(parms);
imageView.setImageResource(R.drawable.bsu);
linearLayout.addView(imageView);
}
}
The results i got.
I want it to be 5margins apart.
i am trying to add images to my relative layout with an for loop but it isn't working.
I tried to remove the for loop and making one image longer and the scroll view seems to work the but when i try to add more than one image to the relative layou it adds it but i cant scroll through them.
Meaning that i can see that there are 5 images but i can only see the top half of it and cant scroll to see the bottom half.
Here is my xml that i use for the activity.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/ScrollView01"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
android:scrollbars="none" >
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/MainRelativeLayout"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
tools:context="com.tutecentral.tvtimeschedule.app.MainActivity"
android:background="#87CABE"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true">
</RelativeLayout>
</ScrollView>
</LinearLayout>
And here is the activity that i use to add the images
int amountOfChannels = 9;
int paddingTopOfImage = 0;
for(int i = 1; i <= amountOfChannels; i++) {
//ImageView Setup
ImageView imageView = new ImageView(this);
//setting image resource
imageView.setImageResource(R.drawable.channel_1);
//setting image position
imageView.setLayoutParams(new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.MATCH_PARENT,
RelativeLayout.LayoutParams.MATCH_PARENT));
imageView.getLayoutParams().height = 400;
imageView.getLayoutParams().width = 1000;
imageView.setPadding(10, 10, 10, 10);
imageView.setBackgroundColor(Color.WHITE);
imageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
imageView.setY(paddingTopOfImage);
//adding view to layout
RelativeLayout mainRelativeLayout = (RelativeLayout) findViewById(R.id.MainRelativeLayout);
mainRelativeLayout.addView(imageView);
paddingTopOfImage = paddingTopOfImage + 450;
}
I don't think you have to put ScrollView under LinearLayout, because ScrollView by default is LinearLayout. Try Removing the LinearLayout.
I have a problem, I'm trying to resize a ImageView and its parent container but the problem is that the ImageView has ScaleType:"matrix", and I cant`t resize the image or its container
this is my code:
public void resize() {
LayoutParams contet = relativeLayout.getLayoutParams();
LayoutParams photo = image.getLayoutParams();
int widPhoto = image.getWidth();
int hePhoto = image.getHeight();
photo.width = ((widPhoto * 6) / 2);
photo.height = ((hePhoto * 6) / 2);
contenedor.width = widPhoto * 2;
contenedor.height = hePhoto * 2;
relativeLayout.setLayoutParams(contenedor);
image.setLayoutParams(photo );
}
and my xml
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/containerImg"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ImageView
android:id="#+id/imageView1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scaleType="matrix" />
</RelativeLayout>
setLayoutParams() does nothing but remove the property ScaleType if I resize everything correctly, but I cant´t remove that property. Any way to resize? they could put the property ScaleType: NONE? thank you very much and sorry for my bad English
To resize your ImageView, I suggest to use FrameLayout:
<FrameLayout
android:id="#+id/fm_id"
android:layout_width="img_width"
android:layout_height="img_height"
... ...
>
<ImageView
android:id="#+id/imageView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:adjustViewBounds="true"
android:layout_gravity="center"
android:gravity="center"
/>
</FrameLayout>
then you just need to resize 'img_width' and 'img_height' in your codes
I got the solution, if you are using the Layout ScaleType: matrix
you need to use matrix.setScale (); for Resizing