I have a GridView in my Android app, which is having images. I have 10 rows and 2 columns in the GridView. With that, I have same size images in every grid i.e. 20 images.
The grid code is,
<GridView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/gridview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:columnWidth="140dp"
android:drawSelectorOnTop="true"
android:gravity="center"
android:numColumns="2"
android:stretchMode="columnWidth"
android:verticalSpacing="5dp"
android:focusable="true"
android:clickable="true"
/>
Meanwhile in the java code, I have used an Adapter. Here's the code, which sets the individual grid size and images, with the scaleType,
imageView = new ImageView(mContext);
imageView.setLayoutParams(new GridView.LayoutParams(340, 400));
imageView.setScaleType(ImageView.ScaleType.FIT_XY);
imageView.setPadding(10, 10, 10, 10);
It's working fine on device screen size 5'0, but on other devices such as 5'7, 4'5, it's not working in the same way. The grids (and their individual images) are somewhat hiding/ cropping. Even under 5'0, it is showing some extra space, which looks poor.
How GridView works correctly on different screen sizes.
Here's a sample, how is it looking like in 5'7,
Here's a sample, how is it looking like in 5'0.
This is how I want it to be visible on every screen size.
Here's a sample, how is it looking like in 4'0. Here the images are getting overlapped.
You can use item view for your GridView same as ListView in your adapter as below:
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = LayoutInflater.from(mContext).inflate(R.layout.item_grid, null);
holder = new ViewHolder();
holder.mImage = (ImageView) convertView.findViewById(R.id.img);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.mImage.setImageResource(imageIDs[position]);
return convertView;
}
public class ViewHolder {
private ImageView mImage;
}
I have created item_grid as below:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:id="#+id/grid_image"
android:layout_width="match_parent"
android:layout_height="130dp" />
</LinearLayout>
Suggestion: You can use RecyclerView with GridLayoutManager with 2 columns
This code works like a charm for me in the Adapter:
// create a new ImageView for each item referenced by the Adapter
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null) {
//Calculation of ImageView Size - density independent.
//maybe you should do this calculation not exactly in this method but put is somewhere else.
Resources r = Resources.getSystem();
float px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 60, r.getDisplayMetrics());
imageView = new ImageView(mContext);
imageView.setLayoutParams(new GridView.LayoutParams((int)px, (int)px));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
//imageView.setPadding(8, 8, 8, 8);
imageView.setBackgroundColor(Color.BLUE);
} else {
imageView = (ImageView) convertView;
}
imageView.setImageResource(mThumbIds[position]);
return imageView;
}
Source:
https://stackoverflow.com/a/11485625/7639113
After adding the code above, I also create a different layout for bigger screen, something like this:
normal_layout.xml
<GridView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/gridview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:numColumns="2"
android:verticalSpacing="5dp"
/>
bigscreen_layout.xml
<GridView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/gridview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:numColumns="4"
android:verticalSpacing="5dp"
/>
Note that I set numColumns differently for those layouts above.
Here is how I created layout for different screen sizes:
Create new Android resource directory in res
Change resource type to layout, select smallest screen width for the available qualifiers, then click ">>"
Fill in 600 in the smallest screen width, Android Studio will automatically generate layout-sw600dp directory. Click OK.
Now all you have to do is place normal_layout.xml in the layout directory, and place bigscreen_layout.xml in the layout-sw600dp directory.
You can look at the different screen size detail in the official Android guide Supporting Multiple Screens:
Related
I have a problem in my application Life Gallery. In this application, I have a fragment that displays the user's media directory in a gridView. Here is a screenshot :
As you can see, each directory is represented with an ImageView and a TextView, this latter containing the name of the directory. If you check the third line, you will see that the text of two TextView are empty...This is my bug. The elements of my gridview that present such a bug varies if I scroll or if rotate my phone...
Here is my layout for an element of the gridView :
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/layout_global"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="1dp" >
<ImageView
android:id="#+id/directory_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:contentDescription="#string/content_description_album_imageview" />
<TextView
android:id="#+id/directory_text"
style="#style/Act_MyOwnLife_TextView_large"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignBottom="#id/directory_image"
android:background="#color/black_transparent"
android:gravity="right"
android:paddingRight="4dp"
android:singleLine="true"
/>
</RelativeLayout>
And here is the code for my Adapter, focusing on the function getView:
#Override
public View getView(int position, View view, ViewGroup parent) {
ViewHolder viewHolder = null;
if (view == null) {
LayoutInflater inflater = this.activity.getLayoutInflater();
view = inflater.inflate(R.layout.fragment_directory_gridview, parent, false);
viewHolder = new ViewHolder();
viewHolder.relativeLayout = (RelativeLayout)view.findViewById(R.id.layout_global);
viewHolder.textViewDirectory = (TextView) view.findViewById(R.id.directory_text);
viewHolder.imageViewDirectory = (ImageView) view.findViewById(R.id.directory_image);
view.setTag(R.id.viewHolder, viewHolder);
}else{
viewHolder = (ViewHolder) view.getTag(R.id.viewHolder);
}
viewHolder.relativeLayout.setLayoutParams(this.viewFragmentDirectory.layoutParams);
viewHolder.imageViewDirectory.setTag(position);
viewHolder.imageViewDirectory.setImageBitmap(null);
viewHolder.position = position;
ModelDirectoryAndMedia directoryAndImage =this.directoriesAndMedias.get(position);
viewHolder.textViewDirectory.setText(directoryAndImage.directoryView);
ImageView imageView = viewHolder.imageViewDirectory;
// creation/retrieve the thumbnail with a thread
job = new Job(imageView,
directoryAndImage.media, Options.OPTIONS_THUMBNAIL,
position);
this.bitmapCreate.addJobThumbnail(job);
return view;
}
What I did to find the bug :
I check that my String was not empty when I call "viewHolder.textViewDirectory.setText(s);"
I try to check with hierarchyViewer, but I can not browse an element if the TextView is empty...I do not know why...
I remove the transparency of the background, remove the background property of the textView, I set "ImageView.setImageBitmap(null);" to check that it was not due to the ImageView...
But without success...the bug was still here...
After more test, I found the reason of the bug: it is due to this line of code in the getView method :
viewHolder.relativeLayout.setLayoutParams(this.viewFragmentDirectory.layoutParams);
I use this line to display the empty ImageView to the correct size. So that when the thumbnail is ready, the insertion in the ImageView will not change its size ( the settings of my LayoutParams is done with the size of my thumbnail )
Any idea ? any comments on my code ?
Thanks a lot !
Ok...The bug was due to the call to :
viewHolder.relativeLayout.setLayoutParams(this.viewFragmentDirectory.layoutParams);
But I do not understand why...anyway, I did this to ensure that my ImageView had the correct initial size to display the thumbnail, loaded by a thread.
So I found an other solution to set a minimum size to the ImageView even if they are empty :
viewHolder.imageView.setMinimumHeight(this.viewControlerAlbum.sizeThumbnail);
viewHolder.imageView.setMinimumWidth(this.viewControlerAlbum.sizeThumbnail);
My layout.xml file is a bit updated :
<ImageView
android:id="#+id/image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:contentDescription="#string/content_description_album_imageview"
android:scaleType="centerCrop"
android:adjustViewBounds="true"/>
I added the adjustViewBounds attribute.
I have created grid view for my wallpaper application but I am facing a problem with my layout. My grid view layout changes with different devices. I want the same view for all devices. Help me out.
This is my xml file.
android:layout_width="match_parent"
android:layout_height="match_parent"
android:columnWidth="30dp"
android:gravity="center"
android:horizontalSpacing="2dp"
android:numColumns="2"
android:stretchMode="columnWidth"
android:verticalSpacing="2dp"
android:orientation="vertical"
android:id="#+id/gridview"
And this is Imageadapter file in which I have set my grid view.
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imgGrid;
if (convertView == null)
{
imgGrid = new ImageView(current);
imgGrid.setLayoutParams(new AbsListView.LayoutParams(300,200));
imgGrid.setPadding(2, 2, 2, 2);
imgGrid.getScaleType();
imgGrid.setScaleType(ScaleType.FIT_XY);
}
else
{
imgGrid = (ImageView)convertView;
}
imgGrid.setImageResource(images[position]);
return imgGrid;
}}
replace this line
imgGrid.setLayoutParams(new AbsListView.LayoutParams(300,200));
with
imgGrid.setLayoutParams(new GridView.LayoutParams(70, 70));
feel change to pass layout params parameter. But don't give large values it won't look good on other devices.
I made a layout with a gridview for small screens (2.7 inch). My icons are 48 x 48 px. Now i want the gridview on a tablet so i created a new layout and changed the settings to large and landscape. I want to use larger icons for the tablet: 72 x 72 px. The problem is that the larger icons not showing up but the small icons does. My small icons are in the folder drawable-mdpi and the large icons are in the folder drawable-hdpi. I tried allready to move the large icons to the drawable-xhdpi folder but without success. I also tried to change the scaletype and the layoutparams of the imageadapter but also without any success Can someone help me to get the larger icons on the tablet?
Here is my code of the large layout:
<?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:background="#drawable/back" >
<GridView
android:id="#+id/Menu"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_below="#+id/imageView1"
android:columnWidth="80dp"
android:gravity="center_horizontal|top"
android:horizontalSpacing="130dp"
android:numColumns="auto_fit"
android:paddingTop="10dp"
android:scrollbars="none"
android:stretchMode="columnWidth"
android:verticalSpacing="50dp" android:layout_marginTop="50dip">
</GridView>
<ImageView
android:id="#+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:src="#drawable/title" />
</RelativeLayout>
The java code of my imageadapter for the gridview is:
public class ImageAdapter extends BaseAdapter
{
private Context context;
public ImageAdapter(Context c)
{
context = c;
}
//---returns the number of images---
public int getCount() {
return menu_icon.length;
}
//---returns the ID of an item---
public Object getItem(int position) {
return null;
}
public long getItemId(int position) {
return 0;
}
//---returns an ImageView view---
public View getView(int position, View convertView, ViewGroup parent)
{
ImageView imageView;
if (convertView == null) {
imageView = new ImageView(context);
imageView.setLayoutParams(new GridView.LayoutParams(150, 150)); imageView.setScaleType(ImageView.ScaleType.CENTER);
imageView.setPadding(5, 5, 5, 5);
} else {
imageView = (ImageView) convertView;
}
imageView.setImageResource(menu_icon[position]);
return imageView;
}
}
Try this,
imageView.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT);
This may work.
This might solve your problem:
imageView.setScaleType(ImageView.ScaleType.FIT_XY);
http://developer.android.com/reference/android/widget/ImageView.html#setScaleType(android.widget.ImageView.ScaleType)
http://developer.android.com/reference/android/widget/ImageView.ScaleType.html
I want to display a custom view, composed of a TextView above an ImageView in a vertical LinearLayout, one at a time in a Gallery.
The problem is that my custom view does not fill the screen. I can see a part of the other views on the sides and I don't want this issue.
Here is the xml of my custom view : gallery_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/gallery_item_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<TextView
android:id="#+id/gallery_item_cardname"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:textSize="20dp"
android:textStyle="bold"
android:text="#string/contrebandiers_lvl1"
android:textColor="#android:color/darker_gray"
/>
<ImageView
android:id="#+id/gallery_item_cardimg"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerInside"
android:contentDescription="#string/app_name"
android:src="#drawable/contrebandiers_lvl1"
/>
</LinearLayout>
Here is the code of the method getVew of my adapter : GTRoundDeckAdapter
public View getView(int position, View convertView, ViewGroup parent)
{
GalleryItem galleryItem;
if(convertView == null)
{
galleryItem = new GalleryItem();
convertView = mInflater.inflate(R.layout.gallery_item, null);
galleryItem.cardName = (TextView) convertView.findViewById(R.id.gallery_item_cardname);
galleryItem.cardImg = (ImageView) convertView.findViewById(R.id.gallery_item_cardimg);
convertView.setTag(galleryItem);
}
else
{
galleryItem = (GalleryItem) convertView.getTag();
}
GTCard gtCard = (GTCard) mRoundDeck.get(position);
galleryItem.cardName.setText(gtCard.getNameId());
galleryItem.cardImg.setImageResource(gtCard.getImgId());
return convertView;
}
I thank you for your help.
Samuel
I would recommend that you use the ViewPager instead of Gallery. In my personal experience, I have found Gallery to slightly buggy. If your requirement is to show only one View at a time, then ViewPager (which lets you swipe left and right to go one by one) should suit your needs.
You will need to include the Android Support package to use ViewPager.
Link to support package: http://developer.android.com/sdk/compatibility-library.html
Link on how to use ViewPager: http://blog.stylingandroid.com/archives/537
you should use both the width of textview and imageview fillparent.then it will be fill the screen of the gallery...
I have 4 buttons that I want to show in a gridview. I want them to fill the screen as much as possible, but I never made it. I've tried all kind of ScaleTypes and it won't work. Right now I have the scale type in FIT_CENTER but i get an unexpected result. Here's the code I have so far:
Main.java
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Display screenSize = getWindowManager().getDefaultDisplay();
int screenWidth = screenSize.getWidth();
int screenHeight = screenSize.getHeight();
int iconWidth = screenWidth/4;
int iconHeight= screenHeight/2;
GridView gridview = (GridView) findViewById(R.id.gridview);
gridview.setAdapter(new ImageAdapter(this, iconWidth, iconHeight));
}
ImageAdapter.java
public View getView(final int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null) {
imageView = new ImageView(m_Context);
imageView.setLayoutParams(new GridView.LayoutParams(m_width, m_height));
imageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
imageView.setPadding(8, 8, 8, 8);
} else {
imageView = (ImageView) convertView;
}
imageView.setImageResource(mThumbIds[position]);
return imageView;
}
GridViewLayout.xml
<?xml version="1.0" encoding="utf-8"?>
<GridView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/gridview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:verticalSpacing="10dp"
android:horizontalSpacing="10dp"
android:columnWidth="90dp"
android:stretchMode="columnWidth"
android:gravity="center"
android:numColumns="2"
android:background="#FFFFFF"/>
The result of the code looks like this:
This is what i would like it to look like:
Note that the last screen shot is hard coded which is obviously not my wish. I want this to work in every screen size without hard coding.
You can achieve it using recycler view with GridLayoutManager.
there you can define size of a single item to match half of device height and width. Then it'll be you expected result.