I have simple GridView (with one column and six rows), that displays ImageView with TextView in the cell (I create adapter). How to stretch rows to fill entire screen height?? Now I have some space below cells...
main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal">
<LinearLayout android:layout_height="fill_parent"
android:layout_width="150dp"
android:orientation="vertical"
android:id="#+id/left">
<include layout="#layout/menu_grid"></include>
</LinearLayout>
<LinearLayout android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:orientation="vertical"
android:id="#+id/right">
<ImageView android:src="#drawable/image"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:id="#+id/imageMain"
android:layout_gravity="center">
</ImageView>
</LinearLayout>
menu_grid.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="fill_parent">
<GridView android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:id="#+id/gridView"
android:padding="10dp"
android:verticalSpacing="10dp"
android:horizontalSpacing="10dp"
android:numColumns="1"
android:columnWidth="100dp"
android:stretchMode="columnWidth"
android:gravity="center"></GridView>
item.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical" android:gravity="fill_horizontal">
<ImageView android:src="#drawable/icon"
android:layout_height="70dp" android:id="#+id/imageIcon"
android:layout_width="70dp" android:layout_gravity="center_horizontal"></ImageView>
<TextView android:id="#+id/textIcon" android:text="TextView"
android:layout_gravity="center" android:layout_height="wrap_content"
android:layout_width="wrap_content"></TextView>
ImageAdapter.java
public class ImageAdapter extends BaseAdapter {
//....some code
//....
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view;
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater)_context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.item, null);
TextView text = (TextView) view.findViewById(R.id.textIcon);
text.setText(labels[position]);
ImageView image = (ImageView) view.findViewById(R.id.imageIcon);
image.setImageResource(icons[position]);
} else {
view = convertView;
}
return view;
}
}
As of what i understood, the question is- if i have 6 rows of data to be filled in the gridView, how can i make these 6 rows fill the whole screen, instead of showing 6 rows and some empty space under the last row.
To achieve this you must set minimum height of the gridView item layout (in your case its item.xml) to (height of the screen)/6, where 6 is the (no.of rows you have to fill). This minimum height can be set in the adapter you are using.
To find the height of the screen of the device:
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int width = metrics.widthPixels;
int height = metrics.heightPixels;
find these values in the Activity and make them public static and use them in the adapter, i had a problem in finding these values in the adapter class
then to set minimum height:
view = inflater.inflate(R.layout.item, null);
view.setMinimumHeight(GridViewActivity.height/6);
I tried this after seeing the post, and it worked perfectly.
If you just want to increase the space between the lines You can use padding it should work.
you can set padding through xml or programmatically based on your requirement.
// this you can set inside your view.
android:paddingLeft="5px"
android:paddingRight="5px"
android:paddingTop="10px"
android:paddingBottom="10px"
// this you can set to your any widgets like TextView/Layouts/Buttons etc..
setPadding(top, left, bottom, right);
Extend a layout say Framelayout then override the onMeasure method.
public class CameraView extends FrameLayout
public TextView titleView;
public CameraView(Context context,AttributeSet attrs) {
super(context, attrs)
titleView = rootView.findViewById(R.id.titleView);
}
#Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, widthMeasureSpec);
}
}
You can then use this view in your BaseAdapter and set the layout_width and layout_height to match_parent
I hope I am understanding you correctly, if so it is as easy as changing your GridView to fill_parent instead of wrap_content.
Change
<GridView android:layout_height="wrap_content"
to
<GridView android:layout_height="fill_parent"
If this is not the case then it is probably the layout height on the LinearLayout of the item.xml that you want to modify.
Related
I am putting this LinearLayout inside RelativeLayout.
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#66000000"
android:gravity="center">
<ImageView
android:layout_width="30dp"
android:layout_height="23dp"
android:src="#drawable/big_tick" />
</LinearLayout>
What I am trying to do is - to show which item has been chosen. I set LinearLayout's height and width match_parent. It is only matching parent(RelativeLayout)'s width, not height.
This is what I have intended to do:
This is what I am getting:
LinearLayout is not taking whole height of its parent.
There are 2 reasons, why I am using Relative layout as parent:
The LinearLayout should be in upside(should cover) book information with 40% black color
To show this symbol on the top of book
The whole XML looks like this:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal">
<LinearLayout
android:id="#+id/llBook"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="6dp"
android:gravity="center_horizontal"
android:orientation="vertical"
android:paddingBottom="5dp"
android:paddingLeft="11dp"
android:paddingRight="2dp"
android:paddingTop="8dp">
<ImageView
android:id="#+id/ivCover"
android:layout_width="95dp"
android:layout_height="146dp" />
<TextView
android:id="#+id/tvTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:textColor="#232425"
android:textSize="12sp" />
<TextView
android:id="#+id/tvAuthor"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:textColor="#848586"
android:textSize="10sp" />
</LinearLayout>
<ImageView
android:layout_width="22dp"
android:layout_height="22dp"
android:layout_alignRight="#id/llBook"
android:layout_marginRight="6dp"
android:background="#drawable/shape_round_book_status"
android:padding="8dp"
android:src="#drawable/icon_new" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#66000000"
android:gravity="center">
<ImageView
android:layout_width="30dp"
android:layout_height="23dp"
android:src="#drawable/big_tick" />
</LinearLayout>
</RelativeLayout>
I am using this RelativeLayout in BaseAdapter class using which I am filling GridView with items.
public class LibraryAdapter extends BaseAdapter {
Context context;
RealmResults<RBook> rBooks;
LayoutInflater inflater;
public LibraryAdapter(Context context, RealmResults<RBook> rBooks) {
this.context = context;
this.rBooks = rBooks;
this.inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return rBooks.size();
}
#Override
public Object getItem(int position) {
return rBooks.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
RBook rBook = (RBook) getItem(position);
View view = convertView;
if(view == null) {
// new row is needed to inflate new row
view = inflater.inflate(R.layout.listitem_library_book, parent, false);
}
Bitmap bitmap = BitmapFactory.decodeByteArray(rBook.getCover() , 0, rBook.getCover().length);
ImageView ivCover = (ImageView) view.findViewById(R.id.ivCover);
ivCover.setImageBitmap(bitmap);
TextView tvTitle = (TextView) view.findViewById(R.id.tvTitle);
tvTitle.setText(rBook.getTitle());
TextView tvAuthor = (TextView) view.findViewById(R.id.tvAuthor);
tvAuthor.setText(rBook.getAuthor());
return view;
}
}
EDIT:
Try1: as cj1098 suggested I have changed child LinearLayout to RelativeLayout. Unfortunately, no effect
Try2: as challenger suggested, I have used this inside my child LinearLayout, but effect was like this:
Try3: as codeMagic suggested, I have changed child LinearLayout's
gravity="center"
to ImageView's
layout_gravity="center"
In result, LinearLayout is not taking whole height.
So my question is how make child LinearLayout match parent RelativeLayout's height?
Try to add this to the LinearLayout:
android:layout_alignParentBottom="true"
android:layout_alignParentTop="true"
Any way use can use this without even using the LinearLayout (with fixing the size of the drawable "big_tick" ):
<ImageView
android:layout_width="30dp"
android:background="#66000000"
android:layout_height="23dp"
android:src="#drawable/big_tick" />
I think that using this layout by itself is fine. It is the fact that you are putting it into a ListView is causing some sort a havoc.
However, you can force the overlay to align itself bottom and top with the book layout:
android:layout_alignBottom="#id/llBook"
android:layout_alignTop="#id/llBook"
After that maybe you still have a few margins to fix, but the two lines above will make the overlay be as big as the book layout.
it is taking the full height of its parent. Get rid of the padding on your child linear layout. Then if that doesn't work. Switch your linearLayout to a relativeLayout. (It's better anyway) another limitation is the actual images you are using. Do they have differing heights?
Remove the LinearLayout totally, use the imageview with src 'tick' as a direct child of the Relative layout with:
andriod:centerInParent=true
and then add View with the desired background transparency that has
android:layout_alignParentBottom="true"
android:layout_alignParentTop="true"
I am having all sorts of issues with row heights in GridView.
I would like to set the size of the items (height/width) in XML and then just have the GridView autofit as many of them as it can with no stretching. If it can't fit the next element it should just add padding around the current number of elements it was able to fit.
Currently I get 2 columns (which to me almost seems fixed size) and the rows get stretched. Could someone please help explain what is happening and how to achieve what I want?
GridView:
<?xml version="1.0" encoding="utf-8"?>
<GridView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/main_grid"
android:numColumns="auto_fit"
android:gravity="center"
android:paddingRight="20dp"
android:paddingLeft="20dp"
android:clipToPadding="true"
android:fitsSystemWindows="true"
android:stretchMode="none"
android:background="#drawable/main_grid_background">
</GridView>
GridItem (I want it 320x320 as I later insert a background image into it which looks odd if its not a perfect square).
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="320dp"
android:layout_height="320dp"
android:padding="10dp" >
<TextView
android:id="#+id/grid_item_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:text="#+id/label"
android:layout_marginTop="5dp"
android:textColor="#color/black"
android:textSize="15sp"
android:visibility="invisible"
android:layout_centerInParent="true" >
</TextView>
</RelativeLayout>
Java:
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View gridView;
if (convertView == null) {
gridView = new View(context);
// get layout from mobile.xml
gridView = inflater.inflate(R.layout.main_grid_item, null);
} else {
gridView = (View) convertView;
}
TextView textView = (TextView) gridView
.findViewById(R.id.grid_item_label);
//SET TEXT AND BACKGROUND IMAGE HERE
//gridView.setBackgroundResource(R.drawable.main_grid_item_import);
return gridView;
}
In the CustomAdapter
v.setLayoutParams(new GridView.LayoutParams(GridView.AUTO_FIT, rowHigh));
rowHigh is the dimension you must change
So, this is not a perfect answer but this is how I got it to work. Ideas borrowed from this thread.
All of this works assuming I know my image sizes, which are 320x320. Also, in GridView I had to set android:columnWidth="320dp" or it would not work. If someone has a better idea please post it... for now I am moving on.
Grid Item XML:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp" >
<ImageView
android:id="#+id/grid_item_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"/>
<TextView
android:id="#+id/grid_item_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:text="#+id/label"
android:textColor="#color/black"
android:layout_alignLeft="#+id/grid_item_image"
android:layout_alignTop="#+id/grid_item_image"
android:layout_alignRight="#+id/grid_item_image"
android:layout_alignBottom="#+id/grid_item_image"
android:gravity="center"
android:textSize="15sp"
android:visibility="invisible">
</TextView>
</RelativeLayout>
GridView XML:
<GridView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/main_grid"
android:numColumns="auto_fit"
android:gravity="center"
android:columnWidth="320dp"
android:paddingRight="20dp"
android:paddingLeft="20dp"
android:clipToPadding="true"
android:fitsSystemWindows="true"
android:stretchMode="columnWidth"
android:background="#drawable/main_grid_background">
</GridView>
public class MyGridView extends GridView {
public MyGridView(Context context) {
super(context);
}
public MyGridView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyGridView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int heightSpec;
if (getLayoutParams().height == LayoutParams.WRAP_CONTENT) {
// The great Android "hackatlon", the love, the magic.
// The two leftmost bits in the height measure spec have
// a special meaning, hence we can't use them to describe height.
heightSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,MeasureSpec.AT_MOST);
} else {
heightSpec = heightMeasureSpec;
}
super.onMeasure(widthMeasureSpec, heightSpec);
}
}
In XML:
<MyGridView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/main_grid"
android:gravity="center"/>
My base layout is a ListView of LinearLayouts, and each item in the grid is the FrameLayout below. I am downloading an image to the ImageView. Prior to the image being loaded, there is no content and the layout is shrunk to the height of the small ProgressBar (first problem), when I expect it to be 240dp or 120dp. After the image is placed in the view, the layout does not adjust (second problem) and the height remains the shrunken dimension of a small ProgressBar.
loading image code:
#Override
public View getView(View convertView) {
// ...
// set up holder
// ...
new GetPhotoTask().execute(holder.my_tile_image, holder.my_loading, my_media_url);
holder.my_tile_image.setVisibility(View.INVISIBLE);
holder.my_loading.setVisibility(View.VISIBLE);
holder.my_tile_label.setText(activityObject1.track.name);
// ...
}
private final class GetPhotoTask extends AsyncTask<Object, Void, Drawable> {
ImageView iv;
ProgressBar pb;
#Override
protected Drawable doInBackground(Object... params) {
iv = (ImageView) params[0];
pb = (ProgressBar) params[1];
return new BitmapDrawable(getResources(), loadAsset(params[2]).media_url, true));
}
#Override
protected void onPostExecute(Drawable result) {
super.onPostExecute(result);
pb.setVisibility(View.GONE);
iv.setImageDrawable(result);
iv.setVisibility(View.VISIBLE);
}
}
the main xml:
<ListView
android:id="#+id/my_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="2dp" />
the xml for each row:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/my_row_type_3"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="240dp"
android:weightSum="3" >
<include layout="#layout/my_tile_layout"
android:id="#+id/my_tile_1"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2" />
<LinearLayout
android:id="#+id/my_row_type_2"
android:orientation="vertical"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:weightSum="2" >
<include layout="#layout/my_tile_layout"
android:id="#+id/my_tile_2"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<include layout="#layout/my_tile_layout"
android:id="#+id/my_tile_3"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
</LinearLayout>
</LinearLayout>
the xml for row content:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/my_tile_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="2dp" >
<ImageView
android:id="#+id/my_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:contentDescription="#string/foo" />
<ProgressBar
android:id="#+id/my_loading"
style="?android:attr/progressBarStyleSmall"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center" />
<TextView
android:id="#+id/my_tile_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/my_title"
android:layout_gravity="left|bottom" />
</FrameLayout>
Why does the initial layout shrink to the height of progress bar even though I've hard coded 240dp for each row? Why does setting a bitmap in the ImageView content not cause it to resize at that point either? The first question most important, as I believe it will nullify the second. Thanks in advance.
SOLUTION
To get the structure I want, I use RelativeLayout for the tiles (for layering ability), and for each row I am overriding the LinearLayout to enforce the sizing I want set for each row. As there is a potential for each tile's content to be larger or smaller than the view, this is screwing up my ability to rely on either centerCrop or fitCenter. So in my custom layout, I set the height to be proportional to the width of each row, and the mode of the MeasureSpec to be EXACTLY.
public final class MyRow3 extends LinearLayout {
// ...
#Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, makeMeasureSpec(getSize(widthMeasureSpec) * 2 / 3, MeasureSpec.EXACTLY));
}
I'm not sure why it isn't honouring it but why not do something like this instead:
Set an absolute height in your ImageView to guarantee some space.
<ImageView
android:layout_height="###dp"
/>
Then change the layout back to an auto adjusted state just before the image is loaded:
iv.setLayoutParams( new LinearLayout.LayoutParams( LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT ) );
To get the structure I want, I use RelativeLayout for the tiles (for layering ability), and for each row I am overriding the LinearLayout to enforce the sizing I want set for each row. As there is a potential for each tile's content to be larger or smaller than the view, this is screwing up my ability to rely on either centerCrop or fitCenter. So in my custom layout, I set the height to be proportional to the width of each row, and the mode of the MeasureSpec to be EXACTLY.
public final class MyRow3 extends LinearLayout {
// ...
#Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, makeMeasureSpec(getSize(widthMeasureSpec) * 2 / 3, MeasureSpec.EXACTLY));
}
Im trying to implement a GridView as part of a image gallery. I followed the following example from the Android developer portal.
The tutorial seems to work for all screen sizes. As you can see below the proportions for a small and a large screen size are displayed correctly (on the left - small screen size, on the right - large screen size.
But now to my problem. When I want to implement exactly the same GridView within a LinearLayout from my Android Project - the correct proportions are gone - as shown by the images below. The pictures begin to overlap so forth and so on.
I am quite sure that this has something to with my LinearLayout which looks like the following.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/widget64"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<LinearLayout
android:id="#+id/widget34"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="5dp"
android:background="#drawable/foto_detail_bg_cell_0"
>
<ImageView
android:id="#+id/flyer"
android:layout_width="100dp"
android:layout_height="80dp"
android:src="#drawable/icon"
android:scaleType="centerCrop"
/>
<LinearLayout
android:id="#+id/widget36"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5px"
android:orientation="vertical">
<TextView
android:id="#+id/toptext"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Beat.It"
android:textSize="16sp"
android:textStyle="bold"
android:textColor="#color/white"/>
<TextView
android:id="#+id/widget39"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="http://www.google.at"
android:textColor="#color/white"/>
<LinearLayout
android:id="#+id/widget40"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/widget41"
android:layout_width="58dp"
android:layout_height="40dp"
android:src="#drawable/facebook_share"/>
<ImageView
android:id="#+id/widget42"
android:layout_width="58dp"
android:layout_height="40dp"
android:layout_marginLeft="1dp"
android:src="#drawable/photocount"/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
<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:columnWidth="90dp"
android:numColumns="auto_fit"
android:verticalSpacing="10dp"
android:horizontalSpacing="10dp"
android:stretchMode="columnWidth"
android:gravity="center"
/>
</LinearLayout>
The MAIN QUESTION:
The Layout XML used by the tutorial on the Android developer portal only uses the GridView alone, without a LinearLayout and and it is shown with correct proportions on each screen size. Why is that? And why does it not work properly when I nest the GridView in a Linear Layout like in my project?
SOLVED:
I solved this issue by editing the ImageAdapter of the GridView. I calculated the size of the generated image views - density independent.
// 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;
}
To adjusting Gridview to screen size
In onCreate take rowHeight :
//Get root view
root = binding.root
// Or you can use findviewbyid(R.id.root)
view.onGlobalLayout {
rowHeight =
root.measuredHeight / currentPageNumberOfRow
fillView(appsList)
}
In adapter:
override fun getView(position: Int, ConvertView: View?, parent: ViewGroup?): View? {
var mConvertView = ConvertView
if (layoutInflater == null) {
layoutInflater =
context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as
layoutInflater!!.inflate(R.layout.item_app_shortcut, null)
}
if (mConvertView == null) {
mConvertView =
layoutInflater!!.inflate(R.layout.item_child_launcher_app, null)
//Add this:
mConvertView.layoutParams = AbsListView.LayoutParams(GridView.AUTO_FIT, rowHeight)
}
Dont forget set row image:
android:layout_width="0dp"
android:layout_height="0dp"
To fit on screen
Got a little problem. I'd like to create an android list view activity with all items in the list having a fixed height.
So, my item layout (thread_item.xml) looks like this:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="300dip"
>
<TextView android:id="#+id/thread_item_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="[dummy]"
android:textSize="20dip"
android:textStyle="bold"
/>
<ImageView android:id="#+id/thread_first_image"
android:layout_below="#id/thread_item_title"
android:scaleType="centerInside"
android:maxWidth="100dip"
android:maxHeight="100dip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:adjustViewBounds="true" />
<TextView
android:id="#+id/thread_item_preview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="#id/thread_first_image"
android:text="[dummy]"
android:textSize="15dip">
</TextView>
</RelativeLayout>
I set layout_height of the root element to 300dip and expect all items to have the same height, but they don't. When I run the application it looks like the height having a wrap_content value.
In addition the activity itself looks like this:
public class ThreadListActivity extends ListActivity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/*
Code to get items from the storage.
*/
setListAdapter(new ThreadItemAdapter(this, R.layout.thread_item, itemsArray)));
getListView().setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
/*Start new Activity. Unrelated stuff.*/
}
});
}
}
And adapter I'm using looks like this:
public class ThreadItemAdapter extends ArrayAdapter<ThreadItem> {
Activity context;
List<ThreadItem> items;
public ThreadItemAdapter(Activity context, int textViewResourceId, List<ThreadItem> items) {
super(context, textViewResourceId, items);
this.context = context;
this.items = items;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inf = this.context.getLayoutInflater();
View result;
if (convertView == null) {
result = inf.inflate(R.layout.thread_item, null);
} else {
result = convertView;
}
TextView tbTitle = (TextView) result.findViewById(R.id.thread_item_title);
TextView tbPreview = (TextView) result.findViewById(R.id.thread_item_preview);
ImageView ivFirstImage = (ImageView) result.findViewById(R.id.thread_first_image);
ThreadItem item = items.get(position);
tbTitle.setText(item.getThreadTitle());
ivFirstImage.setImageBitmap(item.getFirstImage());
SimpleLeadingMarginSpan span = new SimpleLeadingMarginSpan(item.getFirstImage() != null ? 5 : 0, 115); // TODO: const
SpannableString previewText = new SpannableString(item.getThreadPreview());
previewText.setSpan(span, 0, previewText.length(), 0);
tbPreview.setText(previewText);
return result;
}
}
I can't see why all list items still wrap their content and don't stay 300dip in height. They might be both smaller or bigger then 300dip.
I'm using android 2.3.3, testing on HTC Evo 3D device and an emulator (both show same result).
Thanks a lot in advance.
UPD:
Thanks to Miguel and Sam. The solution is to set maxHeight to the textView, that makes my list item grow (that would be +id/thread_item_preview) and setting the RelativeLayout's minHeight to 300dip as well, to prevent it from shrinking.
when inflating for convertView, instead of just
result = inf.inflate(R.layout.thread_item, null);
do
result = inf.inflate(R.layout.thread_item, parent, false);
The method in question is inflater.inflate(int viewId, ViewGroup parent, boolean attachToRoot) -- because you're not honoring the supplied parent (which in this case is the ListView), whatever dimension you supply to the listview item will by default be set to layout_width=fill_parent, layout_height=wrap_content, ignoring the 300dip height you specified in xml. By supplying the parent view and passing false, the inflater will honor the 300dip height, while not attaching it to the root (parent).
What if you change all the child view heights in the row from wrap_content to match_parent?
From comments
Have you tried the minHeight and maxHeight attributes? For example:
android:minHeight="300dp"
You should also watch Android's Romain Guy discuss efficiency in adapters and getView().
Try changing this
android:layout_height="300dip"
to
android:minHeight="300dip"
This worked for me using an ExpandableListView, so I suppose it will work for this case.
You can achieve this by specifying the same dimension for Min and Max. This fixed my problem.
<ImageView
android:id="#+id/appIconImageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginBottom="8dp"
android:layout_marginLeft="8dp"
android:layout_marginTop="8dp"
android:adjustViewBounds="true"
android:maxHeight="50dp"
android:maxWidth="50dp"
android:minHeight="50dp"
android:minWidth="50dp"
android:src="#drawable/ic_launcher" />
Try setting the content TextView's height to 0dp and then setting its layout_alignParentBottom to true.
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:minHeight="60dp"
android:layout_height="match_parent"
android:orientation="horizontal"
android:gravity="center"
android:weightSum="1"
android:background="#color/main_color">
<ImageView
android:id="#+id/img_left_menu"
android:layout_weight="0.4"
android:focusable="false"
android:maxHeight="50dp"
android:maxWidth="50dp"
android:minHeight="50dp"
android:minWidth="50dp"
android:layout_width="0dp"
android:scaleType="centerInside"
android:adjustViewBounds="true"
android:layout_height="wrap_content"/>
<TextView
android:id="#+id/tx_left_menu"
android:layout_width="0dp"
android:textSize="18dp"
android:layout_gravity="center_vertical"
android:layout_weight="0.6"
android:singleLine="true"
android:layout_height="wrap_content"
android:focusable="false"
/>
</LinearLayout>
If I'm not mistaken, the listView automatically modifies the LayoutParams of a custom view to wrap_content, wrap_content. However, the answers above are correct, if you set a minHeight or minWidth it will work brilliantly.