0

I am trying to make a custom calendar view

When I add TextViews to fill up a GridView they don't expand all the way to the edge of the screen even though everything is set to match parent.

The issue can be seen below on the right side of the emulator screen: enter image description here

The following are the XML layout files I am using:

calendar.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">

    <GridView
        android:id="@+id/calendar_grid"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/dateBorder"
        android:verticalSpacing="1dp"
        android:horizontalSpacing="1dp"
        android:numColumns="7"
        />

</LinearLayout>

calendar_day.xml

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/calendar_day"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="10dp"
    android:gravity="right"
    android:textAppearance="@android:style/TextAppearance.Medium">
</TextView>

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">

    <niddahcalendar.kosherapps.com.testgridview.MyCalendarView
        android:id="@+id/my_calendar_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
    </niddahcalendar.kosherapps.com.testgridview.MyCalendarView>

</LinearLayout>

This is the java code I am using:

MyCalendarView.java

import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.LinearLayout;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.Calendar;

public class MyCalendarView extends LinearLayout{

    GridView grid;

    public MyCalendarView(Context context) {
        super(context);
        init(context);
        updateCalendar();
    }

    public MyCalendarView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
        updateCalendar();
    }

    public MyCalendarView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
        updateCalendar();
    }

    private void init(Context context) {
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        inflater.inflate(R.layout.calendar, this);
        grid = (GridView)findViewById(R.id.calendar_grid);
    }

    public void updateCalendar() {
        final ArrayList<Integer> calendarDays = new ArrayList<>();
        Calendar calendar = Calendar.getInstance();
        int monthBeginningCell = calendar.get(Calendar.DAY_OF_WEEK) - 1;
        calendar.add(Calendar.DAY_OF_MONTH, -monthBeginningCell);
        while (calendarDays.size() < 42) {
            int day = calendar.get(Calendar.DAY_OF_MONTH);
            calendarDays.add(day);
            calendar.add(Calendar.DAY_OF_MONTH, 1);
        }
        CalendarAdapter calendarAdapter = new CalendarAdapter(this.getContext(), calendarDays);
        grid.setAdapter(calendarAdapter);
    }

    class CalendarAdapter extends BaseAdapter {

        private Context context;
        private ArrayList<Integer> calendarDays;

        public CalendarAdapter(Context context, ArrayList<Integer> calendarDays) {
            this.context = context;
            this.calendarDays = calendarDays;
        }

        @Override
        public int getCount() {
            return calendarDays.size();
        }

        @Override
        public Object getItem(int position) {
            return calendarDays.get(position);
        }

        @Override
        public long getItemId(int position) {
            return 0;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

            if (convertView == null) {
                convertView = inflater.inflate(R.layout.calendar_day, parent, false);
            }

            //get view
            TextView textView = (TextView) convertView.findViewById(R.id.calendar_day);

            //set data
            textView.setText(String.format("%d", calendarDays.get(position)));
            textView.setBackgroundColor(getResources().getColor(R.color.dateBackground));

            return convertView;
        }
    }
}

MainActivity.java

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        MyCalendarView myCalendarView = (MyCalendarView) findViewById(R.id.my_calendar_view);
    }

}
yitzih
  • 3,018
  • 3
  • 27
  • 44
  • Weird. Are you sure the grid view itself extends to the edge of the screen? What happens if you add an `android:layout_gravity="right"` attribute to the grid view? Does the gap move to the left? What about if you do the same for the enclosing `LinearLayout`? – Ted Hopp Sep 14 '16 at 02:59
  • @TedHopp yes, that dark grey color is the background color of the `GridView`. Adding the gravity attribute to the `GridView` and/or `LinearLayout` didn't change anything. – yitzih Sep 14 '16 at 03:02
  • I suspect it's a remainder problem: the available width is not exactly divisible by the number of columns. Related question: http://stackoverflow.com/questions/22643726/adapt-a-gridview-cells-height-to-remaining-space – Ted Hopp Sep 14 '16 at 03:02
  • @TedHopp my current guess is that there are left over pixels that can't be evenly divided by the number of columns and they aren't being utilized by the children in the `GridView`. Is this a possibility? – yitzih Sep 14 '16 at 03:16
  • Yes, that's what I meant by a "remainder problem". The solution I proposed in my answer is supposed to address that (but evidently didn't work-- bummer). – Ted Hopp Sep 14 '16 at 03:19

1 Answers1

0

Try adding:

android:stretchMode="columnWidth"

to the GridView attributes.

Ted Hopp
  • 232,168
  • 48
  • 399
  • 521