Aligning a Gridview with another view - android

I have an ImageView. Below it, I want to have a GridView containing lots of smaller images. I want it to look neat... 4 per line, with even spacing top and bottom.
Currently, the spacing is not too bad (even though to my eye the left-to-right-spacing looks a little thinner than the top-to-bottom-spacing) but the thing that I'm really struggling with is the extra margin on the far right.
I want the right edge of the images in the grid view to align perfectly with the right edge of the big image. What am I doing wrong?
Here is an image of what I currently have:
Here is my layout:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageView
android:id="#+id/items_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/placeholder"
android:scaleType="fitStart"
android:adjustViewBounds="true"
style="#style/ItemsImage" />
<GridView
android:id="#+id/items_all_images"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:numColumns="4"
android:stretchMode="columnWidth"
android:clipToPadding="false"
android:scrollbarStyle="outsideOverlay"
android:verticalSpacing="20dp"
style="#style/ItemsImage"
/>
</LinearLayout>
</LinearLayout>
The ItemsImage style is this:
<style name="ItemsImage">
<item name="android:gravity">top|left</item>
<item name="android:layout_gravity">top|left</item>
<item name="android:paddingRight">25dp</item>
</style>

I don't know this is the best way to do this but it can solve the problem.
Add these lines to your activity's onCreate method :
YOUR_GRIDVIEW.post(new Runnable()
{
#Override
public void run(){
YOUR_GRIDVIEW.setWidth(YOUR_IMAGE.getWidth());
}
});

Define fix width and height for grids and also for image in gridView. In code after grid instance initialized, you can set spacing as follow.
GridView gridView;
int gridWidth = 1280;
int gridHeight = 500;
int gridItemWidth = 60;
int gridItemHeight = 50;
int gridRows = 3, gridColumns = 4;
int vSpacing = (gridHeight - (gridItemHeight * gridRows))/gridRows;
int hSpacing = (gridWidth - (gridItemWidth * gridColumns))/gridColumns;
gridView.setLayoutParams(new LayoutParams(gridWidth, gridHeight));
gridView.setColumnWidth(gridItemWidth);
gridView.setNumColumns(gridColumns);
gridView.setHorizontalSpacing(hSpacing);
gridView.setVerticalSpacing(vSpacing);
Set grid width equal to the size of large image above GridView.
Hope it helps you.

Related

How to put views on top of an ImageView, in relation to the ImageView's content size?

Background
Suppose I want to show an image of the something using an ImageView, and I want to put new views on top of it (animated ImageViews that show pins on a world map image, for example, or a Switch view on top of a smartphone image).
This means that no matter how the ImageView shows the image, the views should be in it, inside correct spot, with the same size as specified, or in a size related to the imageView itself
The problem
As opposed to other views, the ImageView can have a certain size, but its content is something else (to keep aspect ratio).
What I tried
I tried to use ConstraintLayout, but this can't really help, because the ImageView can change its size (for example when changing orientation), and thus ruining the position I've given the views compared to the ImageView.
I've found some libraries that can handle a similar thing (like here) and I even asked a similar question before (here), but all those solutions are for a static image within the ImageView, yet what I search for is adding a view on top of an ImageView.
The question
How do I put the views on top of the ImageView's content correctly?
How do I also scale the views down/up compared to the size of the ImageView's content ?
Can ConstraintLayout be used to change the scale of the views according to the ImageView's size ?
Make FrameLayout with wrap_content around ImageView. Then you could set SwitchView on top of ImageView. You could align it to center, side or corners and using margins to get some fine position.
It still won't scale with image, but you can get pretty good results. If that doesn't fit you, you can programatically get width/height of ImageView and alter position (or margins) of SwitchView accordingly.
With below you can manage width of switch or any other view as per image view width
android:layout_alignLeft="#+id/imageView"
android:layout_alignRight="#+id/imageView"
<Switch
android:id="#+id/swi"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/imageView"
android:layout_alignRight="#+id/imageView" />
<ImageView
android:id="#+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/swi"
android:src="#drawable/download" />
In Java,
ImageView imgView = (ImageView) findViewById(R.id.imageView);
imageView.setBackgroundResource(R.drawable.yourDrawable);
int width = imgView.getDrawable().getIntrinsicWidth();
Switch switchKey = (Switch) findViewById(R.id.switchKey);
switchKey.setMinimumWidth(width);
And in XML, align it with alignLeft and alignRight with ImageView.
As far as i get it, you need the image size displayed inside the image view and set that as the max width of your switch view right?
You need both Java and XML for this,
The XML file is basically as RelativeLayout with the view stacked as needed.
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:src="#drawable/nonet_icon"
android:id="#+id/iconView"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<android.support.v7.widget.SwitchCompat
android:layout_width="wrap_content"
android:visibility="gone"
android:layout_centerInParent="true"
android:layout_height="wrap_content"
android:id="#+id/switchView"/>
</RelativeLayout>
And the Java Code gets the imageWidth and sets it to the SwitchView.
mSwitchCompat.setVisibility(View.VISIBLE);
// 20% x 25% of Content in ImageView
final float x = mImageView.getDrawable().getIntrinsicWidth()*.2f;
final float y = mImageView.getDrawable().getIntrinsicHeight()*.25f;
// waiting for the view to be drawn
mSwitchCompat.post(new Runnable() {
#Override
public void run() {
// scale current view W.r.t. x and y values
mSwitchCompat.setScaleX((float)mSwitchCompat.getWidth()/x);
mSwitchCompat.setScaleY((float)mSwitchCompat.getHeight()/y);
}
});
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT);
// 30% x 35% of content, for location
int xMargin = Math.round(mImageView.getDrawable().getIntrinsicWidth()*.3f);
int yMargin = Math.round(mImageView.getDrawable().getIntrinsicHeight()*.35f);
// set margin values, can optionally add for top and bottom
layoutParams.setMargins(xMargin,0,yMargin,0);
mSwitchCompat.setLayoutParams(layoutParams);
Ref: Getting Displayed image size of an ImageView
Trying to get the display size of an image in an ImageView
Ref: Dynamic size values
Do comment if you need a detailed explaination.
Example: Check this image!
Scaled View on Image: Scaled View on Image!
You can use MarginLayoutParams with Relative Layout to set left and top position in ImageView.
image = (ImageView) findViewById(R.id.imageID);
MarginLayoutParams marginParams = new MarginLayoutParams(image.getLayoutParams());
marginParams.setMargins(left_margin, top_margin, right_margin, bottom_margin);
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(marginParams);
image.setLayoutParams(layoutParams);
find complete information for this in below link :
MarginLayoutParams
Try this, may be it will help you.
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/img_background"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"/>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/semi_transparent"
android:layout_margin="#dimen/spacing_small"
android:layout_alignTop="#+id/img_background"
android:layout_alignBottom="#id/img_background">
//this layout will expand according to your image size
</RelativeLayout>
</RelativeLayout>
Do you want to show switch that lay on imageview ?
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/ll_download"
android:layout_width="100dp"
android:layout_height="60dp"
android:layout_centerInParent="true"
android:orientation="vertical">
<ImageView
android:src="#android:drawable/btn_star_big_on"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<Switch
android:id="#+id/mySwitch"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Switch" />
</RelativeLayout>

ScrollView not working with Drawables Android

I am using Html.fromHtml() to get content and display it on my activity. To do this I am using an ImageGetter. I was having a problem that if the phone could not connect to the internet the app crashed as the pictures could not load. Instead I wanted to have a placeholder image saved in my ldpi/mdpi/...etc folders that would be inserted whenever a picture could not be loaded.
My ImageGetter uses URLImageParser which has the following onPostExecute() method:
#Override
protected void onPostExecute(Drawable result) {
//check to see if an image was found (if not could
//be due to no internet)
if(result ==null){
//the drawable wasn't found so use the image not found
//png
Drawable imageNotFound = a.getResources().getDrawable(R.drawable.image_not_found);
result = imageNotFound;
}
intrinsicHeight = result.getIntrinsicHeight();
intrinsicWidth = result.getIntrinsicWidth();
DisplayMetrics dm = new DisplayMetrics();
((WindowManager) c.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getMetrics(dm);
int width = dm.widthPixels -50;
int height = width * intrinsicHeight / intrinsicWidth;
result.setBounds(0, 0, 0 + width, 0
+ height);
urlDrawable.setBounds(0, 0, 0+width, 0+height);
// change the reference of the current drawable to the result
// from the HTTP call
urlDrawable.drawable = result;
// redraw the image by invalidating the container
URLImageParser.this.container.invalidate();
// For ICS
URLImageParser.this.container.setHeight((URLImageParser.this.container.getHeight()
+ height));
// Pre ICS
URLImageParser.this.container.setEllipsize(null);
}
I have simply inserted the if(result==null) statement at the top of this method. But now if the pictures can be loaded the app works perfectly. If the images cannot be loaded and the placeholders are used instead I get some odd behavior.
The scrollview never scrolls to the bottom of the screen, and I have no idea why this is. In theory there should be no difference between my imageNotFound drawable (which is a png file) and the files downloaded off the internet. The scrollview will only move slightly.
I have no idea what is causing this. When searching online most people seem to be having problems with RelativeLayouts. I couldn't find anyone having trouble with drawables or TableLayouts.
My xml for the layout is as follows:
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:paddingBottom = "0dip"
android:orientation = "vertical" >
<TableLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:stretchColumns="0,1"
android:shrinkColumns="0,1"
android:id = "#+id/SharedTableLayout"
android:paddingBottom = "0dip" >
<TableRow
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:paddingBottom = "0dip">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id = "#+id/SharedTableContent"
android:layout_span="2"
android:gravity = "left"
android:paddingLeft = "10dip"
android:paddingRight = "10dip"
android:paddingTop = "20dip"
android:paddingBottom = "0dip"/>
</TableRow>
</TableLayout>
</ScrollView>
I would really appreciate any suggestions on this, I've been stuck on it for weeks.
Thanks for your time
The TextView with id SharedTableContent displays a string that was converted from html using Html.fromHtml() so the images may be surrounded by text which means I cannot hard code a solution into xml as there is no way of telling how many images there will be to download in advance, thats all done programmatically.
Try changing the layout width of the scrollview to match_parent.
android:layout_width="match_parent"
android:layout_height="match_parent"
Or try this
<?xml version="1.0" encoding="utf-8"?>
<ScrollView android:id="#+id/ScrollView02"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
xmlns:android="http://schemas.android.com/apk/res/android">
<HorizontalScrollView android:id="#+id/HorizontalScrollView01"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView android:id="#+id/ImageView01"
android:src="#drawable/pic"
android:isScrollContainer="true"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:adjustViewBounds="true">
</ImageView>
</HorizontalScrollView>
</ScrollView>

how to center an image programatically in a layout described by resource

First let's introduce me, I'm new in Android and mobile device programming, I previously worked on embedded systems running on QNX.
I hope I will respect the rules of this forum which seem to be quite stricts ;-).
I'm wrinting an application where I declare a layout for a welcome screen populated, between other things with a image view.
There is a first image placed in this image view in the xml file, but I will replace it by an other one later in the application's code and this second image will be potentially of a different size.
My problem is to resize and center my second image. According to my tests, it's quite automatic by using resources in Lint but it seems not so obvious by program, even if I read in the docs that it should be similar.
After reading several posts on the subject, I finally have a doubt; Can I center an image in an ImageView, or do I have to center the ImageView in the available space?
I tried the first solution without success.
So my layout is:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/fragmentInit"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.cabbonline.ndguidelt.MainActivity" >
<TextView
android:id="#+id/textViewAppName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#+id/textViewAppVersion"
android:layout_centerHorizontal="true"
android:text="#string/app_name" />
<TextView
android:id="#+id/textViewAppVersion"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#+id/TextViewDevelopCabb"
android:layout_centerHorizontal="true"
android:text="#string/app_version" />
<TextView
android:id="#+id/TextViewDevelopCabb"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#+id/imagecaBB"
android:layout_centerHorizontal="true"
android:text="#string/develop_cabb" />
<ImageView
android:id="#+id/imagecaBB"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#+id/textViewCabbUrl"
android:layout_centerHorizontal="true"
android:contentDescription="#string/logo_caBB"
android:maxHeight="150dp"
android:src="#drawable/logo_cabb_100x51_or" />
<TextView
android:id="#+id/textViewCabbUrl"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:text="#string/cabb_url" />
<ImageView
android:id="#+id/imageSite"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="#+id/textViewAppName"
android:contentDescription="#string/logo_Site"
android:scaleType="centerInside"
android:src="#drawable/image_guide_320x400" />
</RelativeLayout>
Here I can say tht the "imageSite" ImageView is well displayed, centered and occupies the whole area. Right.
Now I have a piece of code to replace this image in this same ImageView:
Bitmap imageSite = site.getSitePictureBitmap();
if (imageSite != null) {
imageGuide.setImageBitmap(imageSite);
}
If I only do that, despite en center_inside flag, the new bitmap, smaller and rectangular horizontally compare to the first one which is almost sqaure, the image is displayed very small on the bottom right corner of the ImageView, or the area taken by the ImageView, Idon't really know.
So I add this piece of code to resize it:
imageSite = site.getSitePictureBitmap(); // here I read the bitmap in a file.
if (imageSite != null) {
float maxWidth = imageGuide.getWidth();
float maxHeight = imageGuide.getHeight();
float width = imageSite.getWidth();
float height= imageSite.getHeight();
float hRatio = width / maxWidth;
float vRatio = height / maxHeight;
if (Math.abs(1 - hRatio) < Math.abs(1 - vRatio)) {
// We match horizontal available size
width = width / hRatio;
height = height / hRatio;
} else {
width = width / vRatio;
height = height / vRatio;
}
Bitmap reSizedBitmap = Bitmap.createScaledBitmap(imageSite, (int)width, (int)height, true);
imageGuide.setImageBitmap(reSizedBitmap);
So the image is now of the good width but as its vertical dimension is lower than the first picture, it's close to the textViewAppName. So as it's a rule for the ImageView in the layout description, I wonder if my image is not in the center of the ImageView in fact and my problem would come from the fact that the ImageView is now of a smaller height and doesn't fill up the whole space available at the top of the layout.
I also wondered if setting a new image doesn't reset the positionning flags. I didn't see that in the doc AFAIR but...
So I add this line after setImagebitmap() without success:
imageGuide.setScaleType(ScaleType.CENTER_INSIDE);
Can you tell me a bit more about ImageView behavior in this case and how to get my image vertically in the center of the available space. Do I have to calculate padding?
Regards,
Al

Android GridView imperfection, how to remove extra white space to the right

I have a GridView based calendar. I have the following XML layout with the selector set to null thus android:listSelector="#null" in accordance with advise I have got from this site. Now I am getting a few pixels wide strip to the right of the GridView. Why? I have tried everything I can but to avail. Here is my XML layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<GridView
android:id="#+id/calendar"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:horizontalSpacing="-1px"
android:numColumns="7"
android:stretchMode="columnWidth"
android:gravity="center"
android:verticalSpacing="-1px"
android:listSelector="#null" >
</GridView>
</LinearLayout>
What I get is this picture:
This space is due to imperfect calculation for each row of your grid.
For example your device width is 320 px and you have 7 rows, try any calculation that meets 320 px. If the width of each cell is 45.71428571428571 px, only then it can be reduced.
Other option
apply
android:gravity="center"
property in you grid so that spaces will equally divided from left to right
in my case I had horizontal spacing as 1dp
android:horizontalSpacing="1dp"
so to solve this I just put the right padding as -1dp
android:paddingRight="-1dp"
even though I expected to get a space on the left side due to this , but it worked properly
Try using
android:layout_margin="0dp"
android:padding="0dp"
Also you might have that space allocated for the scroll bar.
And why do you have your vertical and horizontal spacing with negative values?
I had the same problem though in my case I didn't have control over the GridView instance so I couldn't read the column width. Nevertheless I could subclass its container.
This isn't very orthodox but you can override the onMeasure method and add a few pixels. Something like this:
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
final int RIGHT_MARGIN_OVERSIZE_DIP = 6;
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int width = this.getMeasuredWidth()
int overSize = (int)((getResources().getDisplayMetrics().density*RIGHT_MARGIN_OVERSIZE_DIP) + 0.5f);
widthMeasureSpec = MeasureSpec.makeMeasureSpec(width + overSize, MeasureSpec.getMode(widthMeasureSpec));
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
grid.setColumnWidth(grid.getColumnWidth()+1);
This will get the current ColumnWidth and add 1 pixel to it.
Remember to use this after onCreateView,since the grid needs to be initialized before that.
Also,your grid view,should use match_parent (height and width).The image/layout in the column should be also match_parent.

How to remove the space between rows of grid view in android

In android grid view there is extra space between the rows of grid view. I am not adding any space to the gridview.
here is my xml files
<GridView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/grid"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:horizontalSpacing="5px"
android:numColumns="3"
android:columnWidth="50dip"
android:verticalSpacing="0dip"
android:gravity="center"
/>
and the other xml for the imageview which is adding view to the gridview is
<ImageView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/singlePhoto"
android:layout_gravity="top"
android:layout_width="145dip"
android:layout_height="145dip"
android:layout_marginTop="0dip"
android:layout_marginBottom="0dip"
>
</ImageView>
In Adapter class the code is
if(mView == null){
mView = mLayoutInflater.inflate(R.layout.newsgridthumbpic, null);
}
ImageView mImage = (ImageView)mView.findViewById(R.id.singlePhoto);
PhotoGridInfoSet mInfo = (PhotoGridInfoSet)details.get(position);
if(mImage != null){
mImage.setTag(mInfo.getPhotoThumbNailString());
mImage.setVerticalScrollBarEnabled(true);
mImage.setVerticalFadingEdgeEnabled(true);
}
}!
The space is between the rows of gridview. I have not added any space anywhere in the code Still the there is vertical spacing.I am not able understand why there is space in between gridview rows. This space is not appearing in the hdpi device/emulator. This problem is in the mdpi and ldpi devices/emulator.
I got the solution for this problem.
To solve this i need to add 1 line in my xml file
android:adjustViewBounds="true"
and after adding this. the space is not appearing now
Just put last 2 lines in gridView
<GridView
android:numColumns="2"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/gridView"
android:horizontalSpacing="0dip"
android:verticalSpacing="0dip"/>
Put the following line in ur getView() method...
mImage.setPadding(0, 0, 0, 0);
I hope this will help you.
It looks like your picture is being scaled to fit the column width of 50dp while maintaining the aspect ratio. This is introducing a bunch of unfilled space in the vertical layout. If you want your column to be 50dp wide, the easiest way to work out these spacing issues will be to adjust your imageview to have a width of 50dp and adjust the imageviews height proportional to that.
just check that your "newsgridthumbpic" layout does not contain the extra padding or any background image having a large height that your grid view element.Also double check that you are supplying column_width as 50dip but your "imageview's" width is 145 dip.
<GridView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/grid"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:horizontalSpacing="5px"
android:numColumns="3"
android:columnWidth="50dip"
android:verticalSpacing="0dip"
android:gravity="center"/>
<ImageView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/singlePhoto"
android:layout_width="145dip"
android:layout_height="145dip"
android:scaleType="fitXY">
</ImageView>
Setting android:verticalSpacing in the gridview to negative values.
will remove the vertical space.
(Eg: android:verticalSpacing="-10dp")
test with some number to get the right value
I have another way as a fixing for the same issue while one using RecyclerView.
Just pass the number of SpanCount like I have given 6 in GridLayoutManager(this, 6) and change the SpanCount to reduce or increase the gap between the items in the RecyclerView.
Check this sample code-
GridLayoutManager gridLayoutManager = new GridLayoutManager(this, 6);
rvSizes.setLayoutManager(gridLayoutManager);
SizeSelectorAdaptersizeChooserAdapter = new SizeSelectorAdapter(this, sizes);
rvSizes.setAdapter(sizeChooserAdapter);
Hope this will be useful.
Thank you

Categories

Resources