Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to manage GridView

I have following code for Gridview (To make the Calendar).

    <GridView
    android:id="@+id/calendar"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:layout_above="@+id/rl1"
    android:layout_below="@+id/ll2"
    android:columnWidth="250dp"
    android:numColumns="7" >
    </GridView>

Grid_Cell is as follows.

<?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="fill_parent"
android:background="@drawable/calendar_button_selector" >

<Button
    android:id="@+id/calendar_day_gridcell"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="@drawable/calendar_button_selector"
    android:gravity="center"
    android:textAppearance="?android:attr/textAppearanceSmall"
    android:textColor="#000"
    android:textSize="14.47sp" >
</Button>

<TextView
    android:id="@+id/num_events_per_day"
    style="@style/calendar_event_style"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:gravity="center" >
</TextView>

I want to set no space between the rows and columns. like this

Existing view is as following.

Existing image

Please help me out... Thanks in Advance .

like image 826
Varun Vishnoi Avatar asked Dec 03 '12 10:12

Varun Vishnoi


5 Answers

I will try to give you a snippet, but to be honest, there is no point of using a GridView for your case since all you items are there on the screen anyway. You can create a couple of LinearLayouts in a small loop that will get the result.

I would advice you to set the columnWidth on Runtime according to the screen width.

And your adapter should be fed with the column width and height to set them when inflating child views. And in this case, you need to get rid of numColumns. Remember that using numColumns along with columnWidth makes no sense especially when you want to fill the whole space. If you want to set the numColumns, remove the columnWidth.

SOLUTION:

Here is the outcome: enter image description here First, we create our layout. In my case, it is the MainActivity's layout and is called activity_main.xml. (Notice there is no GridView because I'll add that later in code):

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity" >

    <TextView
        android:id="@+id/header"
        android:background="#444"
        android:gravity="center"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:textColor="@android:color/white"
        android:text="Dynamic Static GridView" />

    <TextView
        android:id="@+id/footer"
        android:gravity="center"
        android:background="#444"
        android:textColor="@android:color/white"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:text="Shush" />

</RelativeLayout>

Our GridView element's layout is here in the item_grid.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:background="#fff"
    android:layout_height="match_parent" >

    <TextView
        android:id="@+id/text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:textAppearance="?android:attr/textAppearanceLarge" />

</RelativeLayout>

Now the trick is in MainActivity (I have commented some of the code for you to understand):

package com.example.dynamicstaticgridview;

import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.GridView;
import android.widget.RelativeLayout;
import android.app.Activity;
import android.graphics.Color;

/**
 * @author Sherif elKhatib
 *
 */
public class MainActivity extends Activity {

    private static String items[]; //these are temporary items :p do not use them
    static {
        items = new String[7*7];
        for(int i=0;i<7*7;i++) {
            items[i] = String.valueOf(i);
        }
    }

    int numberOfColumns = 7; //defaulting to 7, you can change it when you know
    int numberOfRows = 7; //defaulting to 7, you can change it when you know
    GridView mGrid;
    ArrayAdapter<String> mAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT);
        params.addRule(RelativeLayout.BELOW, R.id.header);
        params.addRule(RelativeLayout.ABOVE, R.id.footer);
        mGrid = new GridView(this) {
            @Override
            protected void onLayout(boolean changed, int l, int t, int r, int b) {
                super.onLayout(changed, l, t, r, b);
                if(!calculated)
                    getDimens();
            }
        };
        mGrid.setVerticalSpacing(0);
        mGrid.setHorizontalSpacing(0);
        mGrid.setStretchMode(GridView.NO_STRETCH);
        mGrid.setBackgroundColor(Color.rgb(100, 10, 10));
        ((RelativeLayout)findViewById(R.id.rootview)).addView(mGrid, params);
    }

    private int mCellWidth;
    private int mCellHeight;
    boolean calculated = false;
    protected void getDimens() {
        calculated = true;
        //here you might have some rounding errors
        //thats why you see some padding around the GridView
        mCellWidth = mGrid.getWidth()/numberOfColumns;
        mCellHeight = mGrid.getHeight()/numberOfRows;
        mGrid.setColumnWidth(mCellWidth);
        mGrid.setNumColumns(numberOfColumns);
        mAdapter = new ArrayAdapter<String>(this, R.layout.item_grid, R.id.text, items) {
            @Override
            public View getView(int position, View convertView, ViewGroup parent) {
                GridView.LayoutParams params = null;
                if(convertView == null) {
                    params = new GridView.LayoutParams(mCellWidth, mCellHeight);
                }
                convertView = super.getView(position, convertView, parent);
                if(params != null) {
                    convertView.setLayoutParams(params);
                }
                return convertView;
            }
        };
        mGrid.setAdapter(mAdapter);
    }
}

COMMENTS: You'd really better find a decent algorithm to choose mCellWidth, mCellHeight, numberOfColumns, and numberOfRows.

like image 74
Sherif elKhatib Avatar answered Oct 27 '22 00:10

Sherif elKhatib


I might be wrong but as far as I know the GridView is an AdapterView, which in your case means that you can't dynamically, through xml, format the height of your items in a way so that they always fill the entire parent. That is not the way grid views (and list views and other adapter views) work.

These kind of "scrollable container views" could be seen as microfilm readers that used to exist in "modern libraries" a very long time ago. One needs to realize that the data has really nothing to do with the actual viewer, you just use your viewer (the GridView in your case) with a fix with and height to pan over the underlaying data items which also have their fix widths and heights.

As I see it you're trying to explicitly target the very corner-case where the data just happens to have the same geometric size as your viewer window.

A few tips, though:

You could instead have a look at GridLayout. The GridLayout is introduced in API level 14 (IceCream Sandwich) so you might have to rethink your version support strategy there (if I'm not completely misstaking it should also be included in the v7 support package for backwards compatibility on older platforms, in that case you could simply add the jar to your app to support older API levels).

Yet another tip would be to use a TableLayout with corresponding table rows and what not. The TableLayout has been around from day one, so there is no backward compataibility issues there, but they do tend to become very layout intensive, though. If you are planning to reload your view a lot or scroll between months smoothly, I'm not sure this is the solution for you (due to the amount of deep layout routes).

A third solution would be that you still use the GridView, but you measure the height of it and dynamically set a fix height to your inflated grid view items from your grid view adapter, based on the measured GridView height (In other words: you make sure you enter the above mentioned corner-case).

If you use the GridView you'd need to get rid of the vertical spacing as well. There is a android:stretchMode attribute on the GridView which you could play around with. You could also try different (negative?) dimensions on the android:verticalSpacing attribute.

Good luck with your custom calendar view!

like image 42
dbm Avatar answered Oct 26 '22 22:10

dbm


If you want to give a height and width to your gridview put a relative layout outside of the gridview and give android:layout_width and android:layout_height to your relative layout. Then give your gridview's width and height to match_parent. After that if you want to give exact height and width to your gridview cell elements at first you have to know the exact width and height of all cells and you should define the columnWidth according to that, for example for this code

 <GridView
android:id="@+id/calendar"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_above="@+id/rl1"
android:layout_below="@+id/ll2"
android:columnWidth="250dp"
android:numColumns="7" >
</GridView>

if you dont have 1000dp layout outside you never get 4 cells in one row in a good view but only gridview will try to determine its own cell width.

for your situation your calendar gridview should be something like this:

<GridView
android:id="@+id/calendar"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_above="@+id/rl1"
android:layout_below="@+id/ll2"
android:columnWidth="50dp"
android:numColumns="7" >
</GridView>
like image 23
wertigom Avatar answered Oct 27 '22 00:10

wertigom


It seems to be a solution for you http://www.anddev.org/how_to_display_gridview_with_gridlines_and_borders-t11099.html

like image 23
janot Avatar answered Oct 26 '22 22:10

janot


Try setting these two values in XML for your GridView:

android:horizontalSpacing="0dp"
android:verticalSpacing="0dp"

You'll probably want to remove the android:columnWidth field.

like image 35
Jason Robinson Avatar answered Oct 26 '22 23:10

Jason Robinson