0

i have made a simple timetable with GridLayout and it looks like this enter image description here

Now the idea is to insert required subject into specific row and column. In order to achieve that i have created a class that extends CardView in which i need to insert TextView. code: TimeTable.xml

<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"

    android:columnCount="8"
    android:columnOrderPreserved="true"
    android:rowCount="6"
    tools:context="com.digiart.schoolapp.fragments.TimetableFragment">


    <android.support.v7.widget.CardView
        android:id="@+id/timetable_card_space"

        android:layout_column="0"
        android:layout_columnSpan="1"
        android:layout_columnWeight="1"
        android:layout_row="0"
        app:cardElevation="2dp"
        app:contentPadding="5dp">

        <TextView
            android:id="@+id/timetable_dummy"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="time"
            android:textAppearance="@style/TextAppearance.AppCompat.Body1"
            android:visibility="invisible" />
    </android.support.v7.widget.CardView>

    <android.support.v7.widget.CardView
        android:id="@+id/timetable_day1_card"
        android:layout_column="1"
        android:layout_columnWeight="1"
        android:layout_row="0"
        app:cardElevation="2dp"
        app:contentPadding="5dp">

        <TextView
            android:id="@+id/timetable_day1_label"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Monday"
            android:textAppearance="@style/TextAppearance.AppCompat.Body2" />
    </android.support.v7.widget.CardView>

    .....
    ........
    <android.support.v7.widget.CardView
        android:id="@+id/timetable_time1_card"
        android:layout_column="0"
        android:layout_columnWeight="1"
        android:layout_row="1"
        app:cardElevation="2dp"
        app:contentPadding="5dp">

        <TextView
            android:id="@+id/timetable_time1_label"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="09.00"
            android:textAppearance="@style/TextAppearance.AppCompat.Body2" />
    </android.support.v7.widget.CardView>
    ..... 
    ......
   </GridLayout>

TimetableSubject:

public class TimetableSubject extends CardView {

    TextView subjectText;

    public TimetableSubject(Context context,int column,int row,int columnSpan,String subjectName) {
        super(context);

        GridLayout.LayoutParams subjectParam =new GridLayout.LayoutParams();
        subjectParam.columnSpec = GridLayout.spec(column,columnSpan);
        subjectParam.rowSpec = GridLayout.spec(row);

        subjectText = new TextView(context);
        CardView.LayoutParams textParams = new CardView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.MATCH_PARENT);
        subjectText.setText(subjectName);
        subjectText.setLayoutParams(textParams);

        setLayoutParams(subjectParam);
    }


}

Now i get what i need to do, i need to pass row and column to the custom view, and set those as layout params. the issue i think is with the Layout parameters code, i must be messing something up there. Could anyone explain how to set layout params for this situation properly? Thanks.

vibetribe93
  • 257
  • 8
  • 23

3 Answers3

1

This is an age old ticket and I know this is marked as solved, but I'll just leave my experience here. I faced a somewhat similar issue: I was using custom views - extended RelativeLayout - inside GridLayout, I wanted to create a Grid with two columns and N rows (rows don't matter in my case). My custom views did not want to stretch horizontally, to take up the space they have. I have tried the support library, the Android X version of the library, weights, gravity - none of these worked.

It turns out that the GridLayout's parameters were set ok. My custom view was the problem. In my case there was no need to subclass a RelativeLayout, simply subclass a LinearLayout and you can still have whatever layout built inside.

Solution:

 <androidx.gridlayout.widget.GridLayout
                    android:id="@+id/grid"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginStart="@dimen/activity_margin"
                    android:layout_marginEnd="@dimen/activity_margin"
                    app:columnCount="2">
    
                    <custom.MenuButtonGrid
                        android:id="@+id/item1"
                        app:abg_title="Title1"
                        app:layout_columnWeight="1"
                        app:layout_gravity="fill" />
    
                    <custom.MenuButtonGrid
                        android:id="@+id/item2"
                        app:abg_title="Title2"
                        app:layout_columnWeight="1"
                        app:layout_gravity="fill" />
    
                    <custom.MenuButtonGrid
                        android:id="@+id/item3"
                        app:abg_title="Title3"
                        app:layout_columnWeight="1"
                        app:layout_gravity="fill" />
    </androidx.gridlayout.widget.GridLayout>

The implementation of MenuButtonGrid:

/**
 * A component that creates a card view with an icon and texts.
 * They are designed to use as buttons.
 */
class MenuButtonGrid @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : LinearLayout(context, attrs, defStyleAttr) {

    private var binding =
        LayoutButtonGridViewBinding.inflate(LayoutInflater.from(context), this, true)

    init {
      // do whaterver you want in here
    }

}

The inside of layout_button_grid_view.xml:

<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:cardUseCompatPadding="true">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="100dp">

        // Content doesn't matter here

    </RelativeLayout>

</com.google.android.material.card.MaterialCardView>
Marton
  • 121
  • 6
0

You should go with TableLayout. In TableLayout you can create any number of rows and column. Go through the TableLayout documentation and read the concepts of rows and column. Here is a very nice tutorial for table layout.

This tutorial is also very helpful for you.

phatnhse
  • 3,870
  • 2
  • 20
  • 29
  • Started with tableLayout, but as far as i've been reading it has poor performance over GridLayout. Is that true? – vibetribe93 Jul 03 '17 at 18:44
  • @vibetribe93 Depends on your application type. But in most situation, GridLayout will fit your requirement. You should concern about performance only when you have enough data to verify your viewpoint. – hqt Jul 05 '17 at 17:12
  • Ok, thanks on the info. I want to stick with grid layout. Do you know what is wrong when i try to insert my custom view in it? – vibetribe93 Jul 05 '17 at 19:34
0

There was an issue with GridLayout weight parameter in Spec. Managed to solve the problem by inserting weight as a float parameter in Spec Code:

public class TimetableSubjectView extends CardView {

    TextView subjectText;

    public TimetableSubjectView(Context context, int column, int row, float columnWeight, String subjectName, int color) {
        super(context);

        GridLayout.Spec rowI = GridLayout.spec(row,1,columnWeight);
        GridLayout.Spec colI = GridLayout.spec(column,1,columnWeight);

        GridLayout.LayoutParams subjectParam =new GridLayout.LayoutParams(rowI,colI);
        subjectParam.setMargins(5,5,5,5);

        setBackgroundColor(color);
        subjectText = new TextView(context);
        CardView.LayoutParams textParams = new CardView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.MATCH_PARENT);
        subjectText.setText(subjectName);
        subjectText.setGravity(Gravity.CENTER);
        subjectText.setLayoutParams(textParams);
        this.addView(subjectText);
        setLayoutParams(subjectParam);
    }


}
vibetribe93
  • 257
  • 8
  • 23