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.
Related
Hei, I have a hor scrollview which holds a LinearLayout (orientation: hor).
<HorizontalScrollView
android:id="#+id/adImageScroller"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:id="#+id/adImageViewContainer"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="horizontal"
android:layout_gravity="left"
android:background="#color/material_blue_grey_950">
</LinearLayout>
</HorizontalScrollView>
I am populating this LinearLayout dynamically with ImageViews (all images have random aspect ratios).
This is the onCreateView method which populates the LinearLayout:
for (int i = 0; i < reObjectPicUrls.size(); i++) {
String url = reObjectPicUrls.get(i).getContent();
ImageView imageView = new ImageView(getActivity());
imageView.setId(i);
imageView.setPadding(2, 2, 2, 2);
new DownloadImageTask(imageView)
.execute(url);
imageView.setScaleType(ImageView.ScaleType.FIT_START); //<-- WORKS IN XML
imageView.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.MATCH_PARENT)); //<-- WORKS IN XML
imageViewContainer.addView(imageView);
}
What I need but don't get is all images to be scaled to the height of the grey area (horizontalScrollView height) while sustaining their aspect ratio.
The images are all scaled down with options.inSampleSize = 4;
Problem is in the image below. The images are not scaled to fit the height of the LinearLayout.
I have tried different scaleType but nothing seems to fix it.
Thanks for any tips on how to fix this.
Finally cracked it.
Didn't have to change the layout xml but did alter the onCreateView code and added setAdjustViewBounds(true) also used FIT_CENTER scale type.
for (int i = 0; i < reObjectPicUrls.size(); i++) {
String url = reObjectPicUrls.get(i).getContent();
ImageView imageView = new ImageView(getActivity());
imageView.setId(i);
imageView.setPadding(2, 2, 2, 2);
new DownloadImageTask(imageView)
.execute(url);
imageView.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.MATCH_PARENT));
imageView.setAdjustViewBounds(true); <--- THIS DID THE TRICK
imageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
imageViewContainer.addView(imageView);
}
I have a linearLayout I'd like to change the background of programatically:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/downloadLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:weightSum="1" >
...
and I've attempted to set the background Image of the XML layout using the following:
LinearLayout linearLayout2 = (LinearLayout) findViewById(R.id.downloadLayout);
int resId = getResources().getIdentifier(background,
"drawable", getPackageName());
linearLayout2.setBackgroundResource(resId);
However the background image never loads, there is no NPE, the image simply never loads. Any suggestions are appreciated.
I've done a bit of debugging and I currently have the following values:
linearLayout2 = android.widget.LinearLayout{529b3f58 V.E..... ......I. 0,0-0,0 #7f0a008e app:id/downloadLayout}
background = http://xxx.xxx.x.xxx/bgs/big_lebowski_bg.jpg
resID = 0
P.S.
I've also tried accomplishing the same using Picasso - I'm not sure how to get around the error stated and load it successfully:
Source:
final LinearLayout downloadLayout = (LinearLayout) findViewById(R.id.downloadLayout);
Picasso.with(this).load("http://i.imgur.com/DvpvklR.png").into(downloadLayout);
Error:
The method into(Target) in the type RequestCreator is not applicable for the arguments (LinearLayout)
Picasso works with ImageViews only, not layouts.
You could put an ImageView inside your layout, set it to match parent's width and height, and inject the image into the ImageView.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/downloadLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:weightSum="1" >
<ImageView
android:id="#+id/imageView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
This should work then:
ImageView imageView = (ImageView) findViewById(R.id.imageView);
Picasso.with(this).load("http://i.imgur.com/DvpvklR.png").into(imageView);
You have to do so in the background thread and not on the main thread . Consider using image loading libraries such as Picasso
Example is
UPDATED
Make sure you have an image view in the LinearLayout and let it fill_parent (i.e the LinearLayout), Picasso is not applicable to an ImageView directly hence the error.
ImageView imageView = (ImageView) findViewById(R.id.imageView);
Picasso.with(context).load("http://i.imgur.com/DvpvklR.png").into(imageView);
ALTERNATIVELY
LinearLayout linearLayout=(LinearLayout)findViewById(R.id.yourLinearLayoutid);
BitmapDrawable drawableBitmap=new BitmapDrawable(getBitmap(urlString));
linearLayout.setBackgroundDrawable(drawableBitmap);
This method getBitMap, like the one in the Piccasso library should be sufficient without needing the library .
private Bitmap getBitmap(String url)
{
//from web
try {
Bitmap bitmap=null;
URL imageUrl = new URL(url);
HttpURLConnection conn = (HttpURLConnection)imageUrl.openConnection();
conn.setConnectTimeout(30000);
conn.setReadTimeout(30000);
conn.setInstanceFollowRedirects(true);
InputStream is=conn.getInputStream();
OutputStream os = new FileOutputStream(f);
Utils.CopyStream(is, os);
os.close();
bitmap = decodeFile(f);
return bitmap;
} catch (Exception ex){
ex.printStackTrace();
return null;
}
}
In my application I want to display the image with aspected ratio like the gallery.In my application I have to display the marker image on image.Because the marker image having dragging functionality.So that the following is the xml for that
<RelativeLayout
android:background="#000000"
android:layout_above="#+id/buttonlayout"
android:id="#+id/imagelayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<RelativeLayout
android:layout_centerInParent="true"
android:id="#+id/image"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</RelativeLayout>
</RelativeLayout>
And in my activity after select the image from gallery, In onactivityresult method the following code I am using.
try {
// bmGallayImage = decodeFile(selectedImagePath);
bmGallayImage = MediaStore.Images.Media.getBitmap(this.getContentResolver(), selectedImageUri);
bmRotated = InventorySubmitImagesActivity.rotateBitmap(bmGallayImage, orientation);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(bmRotated!=null){
Drawable dr = new BitmapDrawable(bmRotated);
old_width=bmRotated.getWidth();
old_height=bmRotated.getHeight();
Log.e("gal bitmap height and width",""+old_height+" "+old_width);
relImage.getLayoutParams().height = old_height;
relImage.getLayoutParams().width = old_width;
relImage.setBackgroundDrawable(dr);
}
relImage.removeAllViews();
imgMarker = new ImageView(this);
final RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT,
RelativeLayout.LayoutParams.MATCH_PARENT);
layoutParams.leftMargin = 0;
layoutParams.topMargin = 0;
relImage.addView(imgMarker, layoutParams);
imgMarker.setScaleType(ImageView.ScaleType.MATRIX);
bmdragImage=BitmapFactory.decodeResource(getResources(), R.drawable.image_marker);
imgMarker.setImageBitmap(bmdragImage);
In this code relImage is the referance of relative layout and imgMarker is the referance of image view. And the gallery image is set to the relative layout.And My device resolution is 480 by 800 and image resolution is 1920 by 1080.So this is the out put i am getting.
And gallery image view is like the bellow screen shot.
But my requirement is like the gallery image, i want to display the image with aspected ratio.So please suggest me how to do this. Thanks In Advance to all..
You can do this with FrameLayout put image view in this and put your marker ImageView like this http://chiuki.github.io/images/android-layout-101/frame-layout-center.png
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
I want to create my entire app's UI using Droid.Dialog in MvvmCross. More specifically setting the background image and then adding a header image to the view, as well as input fields and buttons.
I am stuck trying to get a header image into the view. Firstly here is a wireframe explaining what I mean by header image:
I have managed to set the background gradient image using:
using (var drawable = Resources.GetDrawable(Resource.Drawable.Backgroud))
Window.SetBackgroundDrawable(drawable);
I have then tried to add the header image using the Cirrious.MvvmCross.Dialog.Droid stuff like this:
var img = new ImageView(this.BaseContext);
img.LayoutParameters = new Gallery.LayoutParams(330, 110);
img.SetImageResource(Resource.Drawable.Header);
Root = new RootElement()
{
new Section(){new ImageElement(img)}
};
However, the image appears as a tiny blotch in the UI.
Doing this in AXML I would set the image as follows:
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:layout_centerInParent="true"
android:orientation="vertical">
<ImageView
android:layout_width="330dp"
android:layout_height="110dp"
android:src="#drawable/Header" />
</LinearLayout>
I'm basically stuck trying to figure out how to get the image into the view at the top of the screen and with the right dimensions!
Any help would be greatly appreciated. Or am I better off creating the views using the native AXML and IB respectively?
If you look what is inside the ImageElement and what happens when you call the ctor with the ImageView argument, then you will discover that the image is scaled to 48x44.
https://github.com/MvvmCross/MvvmCross/blob/v3/CrossUI/CrossUI.Droid/Dialog/Elements/ImageElement.cs#L52:
private const int dimx = 48;
private const int dimy = 44;
...
private ImageView Scale(ImageView source)
{
var drawable = (BitmapDrawable) source.Drawable;
var bitmap = drawable.Bitmap;
var bMapScaled = Bitmap.CreateScaledBitmap(bitmap, dimx, dimy, true);
source.SetImageBitmap(bMapScaled);
return source;
}
So you have a couple of options:
Create your own Element, where you are in the control of what is done with the ImageView
Do it by creating a native Android Layout instead.