In my app I use a GridView but my values for each cells are not same size, when I put my values in GridView, it automatically set a size for all cells(I think it consider first cell height for all cells), can you tell me how can I fix that?
GridView Adapter:
You should try to use custom view your row Item in Gridview
public class SquareRelativeLayout extends RelativeLayout {
public SquareRelativeLayout(Context context) {
super(context);
}
public SquareRelativeLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public SquareRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
if (widthMeasureSpec < heightMeasureSpec)
super.onMeasure(widthMeasureSpec, widthMeasureSpec);
else
super.onMeasure(heightMeasureSpec, heightMeasureSpec);
}
}
In GridView row XML
<SquareRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<ImageView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/image"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:adjustViewBounds="true"
android:contentDescription="#string/descr_image"
android:scaleType="centerCrop" />
</SquareRelativeLayout>
Hope this helps you.
I suggest please use RecyclerView with StaggeredGridLayoutManager, Throw this you can get layout same which you draw upside,
This is the link which will help you:
https://android--code.blogspot.in/2015/12/android-recyclerview.html
Related
i tried to create custom linear layout that have dynamic height and width = height. The custom layout is fine, but the child view not showing at my custom linear layout. i tried some way to fix it, but still cant solve it.
public class CustomLinearLayout extends LinearLayout {
public CustomLinearLayout(Context context) {
super(context);
}
public CustomLinearLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int height = MeasureSpec.getSize(heightMeasureSpec);
setMeasuredDimension(height, height);
}
}
this is the xml that contain my custom linear layout. the child view not showing.
<com.example.admin.antriclient.CustomLinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:autofit="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="100dp"
android:layout_height="100dp"
android:background="#drawable/bg_nomor_antrian"
android:padding="10dp"
>
<me.grantland.widget.AutofitTextView
android:id="#+id/service_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Teller"
android:textColor="#color/white"
android:textStyle="bold"
android:gravity="center_horizontal"
android:singleLine="false"
autofit:minTextSize="12sp"
/>
<me.grantland.widget.AutofitTextView
android:id="#+id/nomor_antrian"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="T21"
android:textSize="50sp"
android:textColor="#color/white"
android:textStyle="bold"
android:gravity="center_horizontal"
android:singleLine="true"
autofit:minTextSize="12sp"
/>
</com.example.admin.antriclient.CustomLinearLayout>
thanks in advance
My problem is because i didnt call the super.onMeasure() method. Thanks to Mike M.
my class should be like this
public class CustomLinearLayout extends LinearLayout {
public CustomLinearLayout(Context context) {
super(context);
}
public CustomLinearLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(heightMeasureSpec,heightMeasureSpec);
//int height = MeasureSpec.getSize(heightMeasureSpec);
//setMeasuredDimension(height, height);
}
}
For me I had to add a LayoutInflater for it to show
public class SidebarLayout extends LinearLayout {
private static final String TAG = "SidebarLayout";
public SidebarLayout(Context context) {
super(context);
}
public SidebarLayout(Context context, #Nullable AttributeSet attrs) {
super(context, attrs);
LayoutInflater.from(context).inflate(R.layout.sidebar, this);
}
public SidebarLayout(Context context, #Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
}
<com.example.a3danimationtester.SidebarLayout
android:id="#+id/layout_sidebar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/layout_topbar" />
For Android Image View .. how to scale 1081*373 Image Button to match the width of Image View and be fixed height ??
i tried match parent for width if image button but it' details not appear ... look like Zoomed image ?? and can't use Gravity ??
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="#drawable/mainempty"
/>
<ImageButton
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="#drawable/about"
/>
Try it!
public class MyBanner extends ImageView {
public MyBanner(Context context) {
super(context);
}
public MyBanner(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyBanner(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = width * 373 / 1081;
setMeasuredDimension(width, height);
}
}
in xml
<your.package.MyBanner
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/about"/>
I want something like this
<LinearLayout android:layout_width="auto"
android:layout_height="match_parent"
android:background="#fff"
android:orientation="vertical">
</LinearLayout>
The height of parent may be dynamic
If height of parent is 100dp, then the width will be 100dp
If height of parent is 200dp, then the width will be 200dp
I do not think that android has this by default. You can however create your own Linear layout that does this.
public class MyLinearLayout extends LinearLayout {
public MyLinearLayout(Context context) {
super(context);
}
public MyLinearLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyLinearLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int height = MeasureSpec.getSize(heightMeasureSpec);
setMeasuredDimension(height, height);
}
}
Please note that you might have problems if the width of the screen is not wide enough to display your layout at your desired height. In xml just set your width to match_parent as well.
I'm using GridView in my app:
<GridView
android:id="#+id/main_grid_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:numColumns="4" >
</GridView>
Every cell in this GridView is ImageView:
<?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" >
<ImageView
android:id="#+id/img"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:contentDescription="#string/img"
android:scaleType="centerCrop" />
</RelativeLayout>
All cells in my GridView must be square (height must equals width) and image must fit cell. But it always looks like rectangle... How I can to implements square cells in GridView?
Make sure your cell is square.
For this, you can set the width and height of the RelativeLayout programmatically with the value screen_width/4.
This can do the trick
#Override public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = MeasureSpec.getSize(heightMeasureSpec);
int size = width > height ? height : width;
setMeasuredDimension(size, size);
}
As mentioned in the answer here - Gridview with two columns and auto resized images
You can make a custom ImageView for this
public class SquareImageView extends ImageView {
public SquareImageView(Context context) {
super(context);
}
public SquareImageView(Context context, AttributeSet attributeSet) {
super(context, attributeSet);
}
public SquareImageView(Context context, AttributeSet attributeSet, int defStyle) {
super(context, attributeSet, defStyle);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
setMeasuredDimension(getMeasuredWidth(), getMeasuredWidth());
} else {
setMeasuredDimension(getMeasuredHeight(), getMeasuredHeight());
}
}
}
and then use this in your grid view cell layout as
<package_containing_SquareImageView.SquareImageView
android:layout_width="match_parent"
android:layout_height="match_parent" />
I'm trying to display 8 items inside a gridview. Sadly, the gridview height is always too little, so that it only shows the first row, and a little part of the second.
Setting android:layout_height="300dp" makes it work. wrap_content and fill_parent apparently not.
My grid view:
<GridView
android:id="#+id/myId"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:horizontalSpacing="2dp"
android:isScrollContainer="false"
android:numColumns="4"
android:stretchMode="columnWidth"
android:verticalSpacing="20dp" />
My items resource:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:minHeight="?android:attr/listPreferredItemHeight" >
<ImageView
android:id="#+id/appItemIcon"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:src="#android:drawable/ic_dialog_info"
android:scaleType="center" />
<TextView
android:id="#+id/appItemText"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="My long application name"
android:gravity="center_horizontal"
android:textAppearance="?android:attr/textAppearanceSmall" />
</LinearLayout>
The issue does not seem related to a lack of vertical space.
What can I do ?
After (too much) research, I stumbled on the excellent answer of Neil Traft.
Adapting his work for the GridView has been dead easy.
ExpandableHeightGridView.java:
package com.example;
public class ExpandableHeightGridView extends GridView
{
boolean expanded = false;
public ExpandableHeightGridView(Context context)
{
super(context);
}
public ExpandableHeightGridView(Context context, AttributeSet attrs)
{
super(context, attrs);
}
public ExpandableHeightGridView(Context context, AttributeSet attrs,
int defStyle)
{
super(context, attrs, defStyle);
}
public boolean isExpanded()
{
return expanded;
}
#Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
// HACK! TAKE THAT ANDROID!
if (isExpanded())
{
// Calculate entire height by providing a very large height hint.
// View.MEASURED_SIZE_MASK represents the largest height possible.
int expandSpec = MeasureSpec.makeMeasureSpec(MEASURED_SIZE_MASK,
MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
ViewGroup.LayoutParams params = getLayoutParams();
params.height = getMeasuredHeight();
}
else
{
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
public void setExpanded(boolean expanded)
{
this.expanded = expanded;
}
}
Include it in your layout like this:
<com.example.ExpandableHeightGridView
android:id="#+id/myId"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:horizontalSpacing="2dp"
android:isScrollContainer="false"
android:numColumns="4"
android:stretchMode="columnWidth"
android:verticalSpacing="20dp" />
Lastly you just need to ask it to expand:
mAppsGrid = (ExpandableHeightGridView) findViewById(R.id.myId);
mAppsGrid.setExpanded(true);
After using the answer from #tacone and making sure it worked, I decided to try shorting down the code. This is my result. PS: It is the equivalent of having the boolean "expanded" in tacones answer always set to true.
public class StaticGridView extends GridView {
public StaticGridView(Context context) {
super(context);
}
public StaticGridView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public StaticGridView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(MEASURED_SIZE_MASK, MeasureSpec.AT_MOST));
getLayoutParams().height = getMeasuredHeight();
}
}
Another similar approach that worked for me, is to calculate the height for one row and then with static data (you may adapt it to paginate) you can calculate how many rows you have and resize the GridView height easily.
private void resizeGridView(GridView gridView, int items, int columns) {
ViewGroup.LayoutParams params = gridView.getLayoutParams();
int oneRowHeight = gridView.getHeight();
int rows = (int) (items / columns);
params.height = oneRowHeight * rows;
gridView.setLayoutParams(params);
}
Use this code after setting the adapter and when the GridView is drawn or you will get height = 0.
gridView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
if (!gridViewResized) {
gridViewResized = true;
resizeGridView(gridView, numItems, numColumns);
}
}
});
Found tacones answer helpfull... so i ported it to C# (Xamarin)
public class ExpandableHeightGridView: GridView
{
bool _isExpanded = false;
public ExpandableHeightGridView(Context context) : base(context)
{
}
public ExpandableHeightGridView(Context context, IAttributeSet attrs) : base(context, attrs)
{
}
public ExpandableHeightGridView(Context context, IAttributeSet attrs, int defStyle) : base(context, attrs, defStyle)
{
}
public bool IsExpanded
{
get { return _isExpanded; }
set { _isExpanded = value; }
}
protected override void OnMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
// HACK! TAKE THAT ANDROID!
if (IsExpanded)
{
// Calculate entire height by providing a very large height hint.
// View.MEASURED_SIZE_MASK represents the largest height possible.
int expandSpec = MeasureSpec.MakeMeasureSpec( View.MeasuredSizeMask, MeasureSpecMode.AtMost);
base.OnMeasure(widthMeasureSpec,expandSpec);
var layoutParameters = this.LayoutParameters;
layoutParameters.Height = this.MeasuredHeight;
}
else
{
base.OnMeasure(widthMeasureSpec,heightMeasureSpec);
}
}
}
Jacob R solution in Kotlin:
class ExpandableHeightGridView #JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : GridView(context, attrs, defStyleAttr) {
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
val expandSpec = MeasureSpec.makeMeasureSpec(MEASURED_SIZE_MASK,
MeasureSpec.AT_MOST)
super.onMeasure(widthMeasureSpec, expandSpec)
layoutParams.height = measuredHeight
}
}
After adding GridView to RecyclerView I got a full-size GridView (all rows are visible), as expected.
Just calculate the height for AT_MOST and set to on measure. Here GridView Scroll will not work so. Need to use Vertical Scroll View explicitly.
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int heightSpec;
if (getLayoutParams().height == LayoutParams.WRAP_CONTENT) {
heightSpec = MeasureSpec.makeMeasureSpec(
Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
}
else {
// Any other height should be respected as is.
heightSpec = heightMeasureSpec;
}
super.onMeasure(widthMeasureSpec, heightSpec);
}