GridView with different column sizes
Asked Answered
B

2

7

Trying to make a highscore list, which is scrollable, and looks like this:

foo         1000
bar         876
foobar      500
foobarfoo   1

I am currently doing it with a GridView. I would like to set the name column width to 60% of the screen and the score column width to 40%. Is it possible?

Currently I am trying via a costum adapter. Here is the getview funcion for it:

public View getView(int position, View convertView, ViewGroup parent) {
    TextView tv;
    if (convertView == null) {
        tv = new TextView(context);
        tv.setTextSize(25);
        tv.setTextColor(Color.WHITE);              

        if (position % 2 == 0)
        {
            tv.setLayoutParams(new GridView.LayoutParams((width/10)*6, 50));
        }
        else
        {
            tv.setLayoutParams(new GridView.LayoutParams((width/10)*4, 50));
        }
    }
    else {
        tv = (TextView) convertView;
    }

    tv.setText(texts[position]);
    return tv;
}

The layout is built by the gridview and a button at the bottom. The XML file is:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent" android:orientation="vertical" android:id="@+id/top">
    <GridView android:layout_width="fill_parent"
              android:layout_height="wrap_content"
              android:layout_weight="2"
              android:id="@+id/grid"
              android:numColumns="2"
              android:columnWidth="0dp"
              >
    </GridView>
    <Button android:layout_width="fill_parent" android:layout_height="wrap_content" android:id="@+id/backbutton" android:text="@string/backstr"></Button>

</LinearLayout>

So the question again: Is it possible to set the GridView to let adding different sized columns? If yes, then my approach is good? (Probably not, since it is not working :)) Did I just miss something?

Thank you in advance!

Bream answered 11/7, 2011 at 13:55 Comment(6)
can you try setting column width to wrap_content instead of 0dp and then see if it works?Pox
That's sadly not a valid value for the columnwidth. But thanks for the comment!Bream
In that case you could use a ListView instead of GridView, and for each row, use a layout with two text views (LinearLayout preferably) which you populate in the getView method of your adapter.Pox
And with this method is the list scrollable?Bream
Yes, ListViews are scrollable :)Pox
Thank you very much! It is working like a charm! I will post my solution after this 8 hour block :)Bream
B
1

Working like a charm! Big thanks to Abhinav, who made a good advise. Here is the code for everyone who has the same problem:

public View getView(int position, View convertView, ViewGroup parent) {
    TextView tv1;
    TextView tv2;
    LinearLayout ll;
    if (convertView == null) {
        tv1 = new TextView(context);
        tv1.setTextSize(25);
        tv1.setTextColor(Color.WHITE);
        tv1.setGravity(Gravity.LEFT);
        tv1.setPadding(5, 5, 5, 5);
        tv1.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT,
                                                          LinearLayout.LayoutParams.FILL_PARENT,
                                                          (float) 3.0));

        tv2 = new TextView(context);
        tv2.setTextSize(25);
        tv2.setTextColor(Color.WHITE);  
        tv2.setGravity(Gravity.RIGHT);
        tv2.setPadding(5, 5, 5, 5);
        tv2.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT,
                                                              LinearLayout.LayoutParams.FILL_PARENT,
                                                              (float) 4.0));

        ll = new LinearLayout(context);
        ll.setOrientation(0);
        ll.setPadding(5, 5, 5, 10);

        tv1.setText(names[position]);
        tv2.setText(scores[position]);

        ll.addView(tv1);
        ll.addView(tv2);
    }
    else {
        ll = (LinearLayout) convertView;
        tv1 = (TextView) ll.getChildAt(0);
        tv2 = (TextView) ll.getChildAt(1);

        tv1.setText(names[position]);
        tv2.setText(scores[position]);
    }

    return ll;
}

And the XML file:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent" android:orientation="vertical" android:id="@+id/top">
    <ListView android:layout_width="fill_parent"
              android:layout_height="wrap_content"
              android:layout_weight="2"
              android:numColumns="2"
              android:columnWidth="0dp"
              android:id="@+id/list">
    </ListView>
    <Button android:layout_width="fill_parent" android:layout_height="wrap_content" android:id="@+id/backbutton" android:text="@string/back"></Button>

</LinearLayout>

If you think you can improve this code (since I am a newbie in this field) don't hesitate, to reply! Thanks in advance!

Bream answered 11/7, 2011 at 22:21 Comment(1)
Nice explanation but if i have 3 coloumns then how to achieve this??Suppress
S
5

We had to do this for a project, and didn't want to use anything other than a GridView because the functionality was repeated, but on one GridView we needed a slightly different view configuration (but still using an adapter and all that other good stuff). We found that you CAN do this if you override GridView's layoutChildren function, although it's pretty poorly documented.

Our implementation has a check for a special view and for if the new layout has already been implemented:

@Override
protected void layoutChildren(){
    super.layoutChildren();
    if(!isSpecial || layoutAlreadySet) return;
    layoutAlreadySet = true;
    //Implement special layout....
}
Sipper answered 21/9, 2012 at 2:26 Comment(2)
Hey Steve. I came across this thread as I was looking for a solution for my problem. I try to display two different types of a custom View in my GridView. Type A has a width of 150dp and Type B has a width of 310dp. I always want the cell to wrap its content. Is that possible with your solution?Sundog
This solution is just for making the GridView do something different than it might normally do, but still feeding it with info from an Adapter. It might be easier to do what you're trying to do with a different layout object, like a LinearLayout. That said, we did use this code to implement a custom-sized cell within a GridView, so if that's the type of thing you need to do, this is a route you can take.Sipper
B
1

Working like a charm! Big thanks to Abhinav, who made a good advise. Here is the code for everyone who has the same problem:

public View getView(int position, View convertView, ViewGroup parent) {
    TextView tv1;
    TextView tv2;
    LinearLayout ll;
    if (convertView == null) {
        tv1 = new TextView(context);
        tv1.setTextSize(25);
        tv1.setTextColor(Color.WHITE);
        tv1.setGravity(Gravity.LEFT);
        tv1.setPadding(5, 5, 5, 5);
        tv1.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT,
                                                          LinearLayout.LayoutParams.FILL_PARENT,
                                                          (float) 3.0));

        tv2 = new TextView(context);
        tv2.setTextSize(25);
        tv2.setTextColor(Color.WHITE);  
        tv2.setGravity(Gravity.RIGHT);
        tv2.setPadding(5, 5, 5, 5);
        tv2.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT,
                                                              LinearLayout.LayoutParams.FILL_PARENT,
                                                              (float) 4.0));

        ll = new LinearLayout(context);
        ll.setOrientation(0);
        ll.setPadding(5, 5, 5, 10);

        tv1.setText(names[position]);
        tv2.setText(scores[position]);

        ll.addView(tv1);
        ll.addView(tv2);
    }
    else {
        ll = (LinearLayout) convertView;
        tv1 = (TextView) ll.getChildAt(0);
        tv2 = (TextView) ll.getChildAt(1);

        tv1.setText(names[position]);
        tv2.setText(scores[position]);
    }

    return ll;
}

And the XML file:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent" android:orientation="vertical" android:id="@+id/top">
    <ListView android:layout_width="fill_parent"
              android:layout_height="wrap_content"
              android:layout_weight="2"
              android:numColumns="2"
              android:columnWidth="0dp"
              android:id="@+id/list">
    </ListView>
    <Button android:layout_width="fill_parent" android:layout_height="wrap_content" android:id="@+id/backbutton" android:text="@string/back"></Button>

</LinearLayout>

If you think you can improve this code (since I am a newbie in this field) don't hesitate, to reply! Thanks in advance!

Bream answered 11/7, 2011 at 22:21 Comment(1)
Nice explanation but if i have 3 coloumns then how to achieve this??Suppress

© 2022 - 2024 — McMap. All rights reserved.