Issue
I'm developing an application where I load several Buttons in a GridView.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:paddingLeft="25dp"
android:paddingRight="25dp"
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical">
<GridView
android:id="@+id/gridview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:columnWidth="128dp"
android:numColumns="auto_fit"
android:verticalSpacing="5dp"
android:horizontalSpacing="5dp"
android:stretchMode="columnWidth"
android:gravity="center" />
</LinearLayout>
The buttons are dynamically added with an Adapter, but I cannot scale or auto fit the images as I would like to, if I predefined the boundaries (320x320) in some devices look great in other ones too small or too big and if I choose the Intrinsic boundaries they are always miniature.
Predefined boundaries (320x320):
Smartphone view:
Tablet view:
Intrinsic boundaries (136x136):
I'm storing the images in the Assets directory, your first question is why?
You could tell me me that I should save them in the Resources/drawable and I'm aware of it, but I have more than 100 images and each of them are stored in a sub-folders with a unique IDs, which can contains at least one image with an ID like this one: 1.jpg, 2.jpg, etc.
As you can appreciate if I move all those images and sub-directories to the drawable folder, it just not going to work (Can the Android drawable directory contain subdirectories?).
I have this function in order to get the Drawable from the Assets folder:
public Drawable GetImage(int ID)
{
var thumbnail = string.Format("Thumbnails/{0}/1.jpg", ID);
using (StreamReader sr = new StreamReader(Application.Context.Assets.Open(thumbnail)))
{
Drawable d = Drawable.CreateFromStream(sr.BaseStream, null);
d.SetBounds(0, 0, 320, 320);
return d;
}
}
Here is how I load the data in the Adapter to the Buttons:
btnRecipe.Text = data[position].name;
btnRecipe.SetHeight(560);
// btnRecipe.SetWidth(122);
// btnRecipe.SetCompoundDrawablesWithIntrinsicBounds();
btnRecipe.SetTextColor(new Android.Graphics.Color(255, 255, 255));
btnRecipe.SetCompoundDrawables(null, data[position].image, null, null);
I'd like to know if there is any way to deal or Auto Fit the images because I have another example that with data from the Drawable folder and XML code the image is scaled without anything else for example:
Code:
<Button
android:text="@string/BtnComidas"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/my_white"
android:id="@+id/BtnComidas"
android:drawableTop="@drawable/comidas" />
Also, I'd like to clarify that this image is smaller 128x128 than the previous ones (136x136), furthermore, it looks much better and I have just one copy of the image in the Drawable folder, I don't have a hdpi or a mdpi copies and as you can see it looks great in smartphones and tablets, I didn't need to do any additional change in order to scale it.
A possible questions and answer, why am I using a GridView in order to load the buttons? If I should use another control or Layout, for instance.
I didn't know another way in order to display an image and text at the same time and I was able to handle the click event as I expected.
Besides, I'm open to any suggestion if someone has another approach of how displaying several images with text in a GridView or something else that could solve my current problem. Thanks for your help, time, experience and worthy knowledge.
Solution
I was able to find a solution to my problem that could help more people too:
1) You need to share the Column Width of your GridView to the constructor:
GridDishes.Adapter = new GridViewAdapter(this, data, GridDishes.ColumnWidth, IsSmartphone());
2) Then you configure the ideal size:
public GridViewAdapter(Context c, List<CompatedInfo> data, int size, bool isSmartphone)
{
NotifyDataSetChanged();
context = c;
this.data = data;
//Define the size that you're going to use
if (Size > 0)
Size = (int)(size * 0.8);
//This is going to help you to have the same size for all elements
if (isSmartphone)
Height = (int)(Size * 1.65);
else
Height = (int)(Size * 1.7);
}
3) Define the new size in the adapter:
data[position].image.SetBounds(0, 0, Size, Size);
4) If you want that all views have the same Height, the height is predefined in the Constructor:
btnRecipe.SetHeight(Height);
Optional:
This function is useful if you want to determinate the screen and do some small changes as I did with the maximum size for the elements:
private bool IsSmartphone()
{
DisplayMetrics metrics = new DisplayMetrics();
WindowManager.DefaultDisplay.GetMetrics(metrics);
float yInches = metrics.HeightPixels / metrics.Ydpi;
float xInches = metrics.WidthPixels / metrics.Xdpi;
double diagonalInches = Math.Sqrt(xInches * xInches + yInches * yInches);
if (diagonalInches >= 6.5)
{
return false;
}
else
{
return true;
}
}
Source of the function:
https://stackoverflow.com/a/24701063/2889347
Answered By - Federico Navarrete
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.