Semmai vi capiterà di realizzare un’App Android che necessiti del widget calendario, non dovrete più cercar di venire a capo ad uno dei problemi più frequenti, che insorge quando si cerca di inserirlo all’interno di una ScrollView.

Immaginiamo di voler implementare all’interno della nostra App un form da far compilare all’utente, con l’ausilio del calendario per poter far selezionare una data specifica.
Se il form contiene parecchi campi, sarà necessario inserire una ScrollView che permetta lo scorrimento della pagina. La ScrollView di fatti permette questo.
Mentre la CalendarView permette di scorrere i mesi e selezionare una data specifica. Qui casca l’asino.

Per selezionare un mese nel Calendario, diverso da quello che ci viene proposto quando avviamo l’app, dobbiamo fare lo scrolling verticale sulla CalendarView. Se questo è presente all’interno di una ScrollView, subentra il conflitto.

L’unico modo per far coesistere CalendarView e ScrollView è quello di estendere il widget calendario come viene mostrato qui sotto:

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.ViewParent;
import android.widget.CalendarView;
 
public class CalendarViewScrollable extends CalendarView {
 
    public CalendarViewScrollable(Context context) {
        super(context);
    }
 
    public CalendarViewScrollable(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
 
    public CalendarViewScrollable(Context context, AttributeSet attrs,
            int defStyle) {
        super(context, attrs, defStyle);
    }
 
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev)
    {
        if (ev.getActionMasked() == MotionEvent.ACTION_DOWN)
        {
            ViewParent p = getParent();
            if (p != null)
                p.requestDisallowInterceptTouchEvent(true);
        }
 
        return false;
    }
 
}

Il layout del nostro widget è così definito:

        <apps.package.form.CalendarViewScrollable
            android:id="@+id/calendarView1"
            android:layout_width="match_parent"
            android:layout_height="357dp"
            android:background="@color/options"
            android:dateTextAppearance="?android:attr/textAppearanceMedium"
            android:firstDayOfWeek="2"
            android:focusedMonthDateColor="@color/testi"
            android:showWeekNumber="false" />

Per lavorare con il calendario esteso sarà sufficiente dichiararlo laddove si necessita, in modo simile:

public class Form extends Fragment {
 
static CalendarViewScrollable calView;
 
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
		super.onCreate(savedInstanceState);
 
		rootView = inflater.inflate(R.layout.fragment_form, container, false);
		calView = (CalendarViewScrollable)rootView.findViewById(R.id.calendarView1);
 
		// etc ...
 
		}
 
// ...
 
}