How to show image and video as thumbnail in grid view?
Yes..
I got the answer after a long experiment: here it is:
public class GridGallery extends Activity
{
ArrayList<String>list;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.grid_gallery);
DataModel dbModel = new DataModel(this);
list = dbModel.selectAll();
GridView sdcardImages = (GridView) findViewById(R.id.sdcard);
sdcardImages.setAdapter(new ImageAdapter(this));
}
/**
* Adapter for our image files.
*/
private class ImageAdapter extends BaseAdapter {
private final Context context;
public ImageAdapter(Context localContext) {
context = localContext;
}
public int getCount()
{
return list.size();
}
public Object getItem(int position)
{
return position;
}
public long getItemId(int position)
{
return position;
}
public View getView(int position, View convertView, ViewGroup parent)
{
ImageView picturesView;
if (convertView == null) {
picturesView = new ImageView(context);
if(list.get(position).contains(".jpg"))
{
bitmap = BitmapFactory.decodeFile(list.get(position)); //Creation of Thumbnail of image
}
else if(list.get(position).contains(".mp4"))
{
bitmap = ThumbnailUtils.createVideoThumbnail(list.get(position), 0); //Creation of Thumbnail of video
}
picturesView.setScaleType(ImageView.ScaleType.FIT_CENTER);
picturesView.setPadding(8, 8, 8, 8);
picturesView.setLayoutParams(new GridView.LayoutParams(100, 100));
}
else
{
picturesView = (ImageView)convertView;
}
return picturesView;
}
}
}
This works fine for me
How to layout a 'grid' of images in the center of the screen
I figured this shouldn't be too hard using a custom view, which should be an interesting exercise. This is my first custom view; feedback is welcome!
Limitations
AspectGrid
completely ignores the size that its children want to be. For your purposes, this appears to be okay. If something fancier is needed,onMeasure
needs a lot of extra work.- The size that is suggested by
AspectGrid
's parent is used without a second thought. This is related to the previous issue.
Screenshots
Landscape screenshot http://tinypic.com/images/404.gif
How it works
A main parameter is the number of columns. The number of rows is computed automatically, because we know the number of children. Another main parameter is the aspect ratio we want to use for the children (set to 1 for squares).
In onLayout
, we receive the final size of the grid, so we can compute the maximum width and height of the children.
We then check this against the aspect ratio. If the children are too tall, we make them shorter (as in the portrait example). If they are too wide, we make them narrower (as in the landscape example).
That's all there is to it; the rest is just plumbing.
The code
com/photogrid/AspectGrid.java
: The actual ViewGroup
class
package com.photogrid;
import android.content.Context;
public class AspectGrid extends ViewGroup {
private int mNumColumns = 1;
private int mHorizontalSpacing = 0;
private int mVerticalSpacing = 0;
private float mChildAspectRatio = 1.0f;
public AspectGrid(Context context) {
super(context);
}
public AspectGrid(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public AspectGrid(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
try {
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.AspectGrid);
setNumColumns(a.getInt(R.styleable.AspectGrid_numColumns, mNumColumns));
setHorizontalSpacing(a.getDimensionPixelSize(R.styleable.AspectGrid_horizontalSpacing, mHorizontalSpacing));
setVerticalSpacing(a.getDimensionPixelSize(R.styleable.AspectGrid_verticalSpacing, mVerticalSpacing));
setChildAspectRatio(a.getFloat(R.styleable.AspectGrid_childAspectRatio, mChildAspectRatio));
a.recycle();
} catch (RuntimeException ex) {
throw ex;
}
}
public int getNumColumns() {
return mNumColumns;
}
public void setNumColumns(int numColumns) {
if (numColumns < 1)
throw new IllegalArgumentException("numColumns must be at least 1");
if (numColumns != mNumColumns) {
mNumColumns = numColumns;
requestLayout();
}
}
public int getHorizontalSpacing() {
return mHorizontalSpacing;
}
public void setHorizontalSpacing(int horizontalSpacing) {
mHorizontalSpacing = horizontalSpacing;
}
public int getVerticalSpacing() {
return mVerticalSpacing;
}
public void setVerticalSpacing(int verticalSpacing) {
mVerticalSpacing = verticalSpacing;
}
public float getChildAspectRatio() {
return mChildAspectRatio;
}
public void setChildAspectRatio(float childAspectRatio) {
if (childAspectRatio <= 0)
throw new IllegalArgumentException("childAspectRatio must be positive");
if (childAspectRatio != mChildAspectRatio) {
mChildAspectRatio = childAspectRatio;
requestLayout();
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int measuredWidth = widthSize;
int measuredHeight = heightSize;
int width = Math.max(measuredWidth, getSuggestedMinimumWidth());
int height = Math.max(measuredHeight, getSuggestedMinimumHeight());
setMeasuredDimension(width, height);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int childCount = getChildCount();
if (childCount <= 0)
return;
int innerWidth = r - l - getPaddingLeft() - getPaddingRight();
int innerHeight = b - t - getPaddingBottom() - getPaddingTop();
int numRows = (childCount + mNumColumns - 1) / mNumColumns;
int leftEdge = getPaddingLeft();
int topEdge = getPaddingTop();
int horizontalStride = (innerWidth + mHorizontalSpacing) / mNumColumns;
int verticalStride = (innerHeight + mVerticalSpacing) / numRows;
int childWidth = horizontalStride - mHorizontalSpacing;
int childHeight = verticalStride - mVerticalSpacing;
if (childHeight * mChildAspectRatio > childWidth) {
childHeight = (int)(childWidth / mChildAspectRatio);
verticalStride = childHeight + mVerticalSpacing;
topEdge = (innerHeight + mVerticalSpacing - numRows * verticalStride) / 2;
} else {
childWidth = (int)(childHeight * mChildAspectRatio);
horizontalStride = childHeight + mHorizontalSpacing;
leftEdge = (innerWidth + mHorizontalSpacing - mNumColumns * horizontalStride) / 2;
}
for (int i = 0; i < childCount; ++i) {
View child = getChildAt(i);
int row = i / mNumColumns;
int column = i % mNumColumns;
int left = leftEdge + column * horizontalStride;
int top = topEdge + row * verticalStride;
child.layout(
left,
top,
left + childWidth,
top + childHeight);
}
}
}
res/values/attrs.xml
: Declaration of attributes for use in the XML
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="AspectGrid">
<attr name="numColumns" format="integer"/>
<attr name="horizontalSpacing" format="dimension"/>
<attr name="verticalSpacing" format="dimension"/>
<attr name="childAspectRatio" format="float"/>
</declare-styleable>
</resources>
res/layout/main.xml
: The example used in the screenshots above
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res/com.photogrid"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<com.photogrid.AspectGrid
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="5dp"
app:numColumns="3"
app:horizontalSpacing="5dp"
app:verticalSpacing="5dp"
app:childAspectRatio="1.0"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#ffcccc"
android:text="Item 1"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#ccffcc"
android:text="Item 2"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#ccccff"
android:text="Item 3"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#ffffcc"
android:text="Item 4"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#ffccff"
android:text="Item 5"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#ccffff"
android:text="Item 6"
/>
</com.photogrid.AspectGrid>
</LinearLayout>
CSS simple thumbnail grid shows weird spacing
The broken formatting is because some images are taller in the second example. The taller images take up more space and because the thumbnails have float:left
set, they flow around the taller one. This explains why the first example works, since they all have the same height.
That said, float:left
is also overriding the display:inline-block
with display:block
- see css display property when a float is applied
If you remove float:left
or set the height of the .thumb
class the thumbnails will also line up as expected.
Responsive image gallery using CSS flexbox or grid-layout
Using flex
capabilities should be sufficient for your task. Be aware of partial support in IE11: http://caniuse.com/#feat=flexbox.
Put these styles on your container:
.gallery {
display: flex;
flex-wrap: wrap;
align-content: flex-start;
justify-content: space-between;
}
Styles for wrappers:
.gallery a {
flex-grow: 1;
flex-basis: 125px;
max-width: 300px;
margin: 5px;
}
Styles for images:
.gallery img {
height: 100%;
width: 100%;
}
Space between images can be simply defined using margin
.
In order to preserve image ratio you can use for example links (<a>
) as a wrappers for images (<img>
).
Furthermore, in order to prevent enlarging images, you can apply flex-grow
, flex-basis
and max-width
attributes on anchors.
There was also a problem with stretching images in the last row - hack for that is to put n - 1
(where n
is number of images) empty items inside container.
Setting width
and height
to 100%
on the images enforces them to grow automatically up to the width defined by max-width
attribute, while maintaining aspect ratio.
Please check the working example:
FIDDLE
Fit full thumbnails in a masonry display
On the <img>
tag that the thumbnails are displayed, object-fit: cover
is applied.
Change that to
object-fit: contain;
And it will stay inside the container.
The replaced content is scaled to maintain its aspect ratio while fitting within the element’s content box. The entire object is made to fill the box, while preserving its aspect ratio, so the object will be "letterboxed" if its aspect ratio does not match the aspect ratio of the box.
MDN Docs
Here's what happens:
BEFORE
AFTER
Controlling the size of an image within a CSS Grid layout
You have two different problems here.
I'll address the first one, which is to contain the image in its container. You almost had it.
Your code:
.photo > img {
object-fit: cover;
width: 100%;
}
You just needed to specify a maximum height on the image so it could not overflow the container:
.photo > img {
object-fit: cover;
width: 100%;
max-height: 100%;
}
JSFiddle demo
The second problem, which is to scale the size of the image container, and drag up the grid items below when the image gets smaller, is significantly more complex.
This isn't an issue relating to the image. In fact, you can remove the image altogether when trying to solve this problem.
This is an issue of dynamically sizing a grid item (the image container). Why would this grid item change size in relation to the image size, when its size is being controlled by grid-template-columns
and grid-template-rows
?
In addition, why would the bottom row of grid items (tag
, album
, rotate
) follow the image container either up or down? They would have to exit their row.
Scaling the entire grid container wouldn't be a problem. But it seems like you only want to scale one grid item (the image container). It's tricky. You're probably looking at additional containers, auto
values for lengths, and possibly scripting.
Here's what happens if you give the image rows an auto
value: JSFiddle demo
Related Topics
Why Does Runtime.Exec(String) Work for Some But Not All Commands
Which Overload Will Get Selected for Null in Java
Scale the Imageicon Automatically to Label Size
How to Wire One Pane to Another
Why Does the Division of Two Integers Return 0.0 in Java
Java Code for Calculating Leap Year
Static Method in a Generic Class
Why Can't Strings Be Mutable in Java and .Net
The JPA Hashcode()/Equals() Dilemma
How to Kill a Thread? Without Using Stop();
How to Write a Custom JSON Deserializer for Gson
How to Make an Image Move While Listening to a Keypress in Java
Centering a Jlabel on a JPAnel
Java "Void" and "Non Void" Constructor
How to Decrypt File in Java Encrypted with Openssl Command Using Aes
How to Map an Entity Field Whose Name Is a Reserved Word in JPA