15

Sto lavorando su un'applicazione Android (v3.0), che ha un requisito di imitando il layout del calendario settimanale trovato su Google Calendar:Come posso creare una vista calendario settimanale per un'applicazione Android Honeycomb?

Google Calendar Weekly Layout

Gli eventi saranno basati su richieste esterne attraverso il calendario di Google API (ho già questa parte funzionante). Utilizzando l'API, posso ottenere un elenco di eventi per la settimana, con ogni evento che ha un data/ora di inizio e fine. Vorrei utilizzare questi dati per mostrare gli eventi programmati agli utenti dell'applicazione in una vista simile a quella precedente.

Ecco quello che ho finora:

My Prototype Calendar View

L'XML appare sotto:

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

    <TextView 
     android:id="@+id/textView1" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="Calendar Title" 
     android:textAppearance="?android:attr/textAppearanceLarge" /> 

    <RelativeLayout 
     android:id="@+id/relativeLayout1" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" > 

     <LinearLayout 
      android:id="@+id/linearLayout1" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_alignParentLeft="true" 
      android:layout_alignParentRight="true" 
      android:layout_alignParentTop="true" > 

      <TextView 
       android:id="@+id/textView2" 
       android:layout_width="0dp" 
       android:layout_height="wrap_content" 
       android:layout_weight="1" 
       android:text="" /> 

      <TextView 
       android:id="@+id/textView3" 
       android:layout_width="0dp" 
       android:layout_height="wrap_content" 
       android:layout_weight="2" 
       android:gravity="center" 
       android:text="Sunday" /> 

      <TextView 
       android:id="@+id/textView4" 
       android:layout_width="0dp" 
       android:layout_height="wrap_content" 
       android:layout_weight="2" 
       android:gravity="center" 
       android:text="Monday" /> 

      <TextView 
       android:id="@+id/textView5" 
       android:layout_width="0dp" 
       android:layout_height="wrap_content" 
       android:layout_weight="2" 
       android:gravity="center" 
       android:text="Tuesday" /> 

      <TextView 
       android:id="@+id/textView6" 
       android:layout_width="0dp" 
       android:layout_height="wrap_content" 
       android:layout_weight="2" 
       android:gravity="center" 
       android:text="Wednesday" /> 

      <TextView 
       android:id="@+id/textView7" 
       android:layout_width="0dp" 
       android:layout_height="wrap_content" 
       android:layout_weight="2" 
       android:gravity="center" 
       android:text="Thursday" /> 

      <TextView 
       android:id="@+id/textView8" 
       android:layout_width="0dp" 
       android:layout_height="wrap_content" 
       android:layout_weight="2" 
       android:gravity="center" 
       android:text="Friday" /> 

      <TextView 
       android:id="@+id/textView9" 
       android:layout_width="0dp" 
       android:layout_height="wrap_content" 
       android:layout_weight="2" 
       android:gravity="center" 
       android:text="Saturday" /> 
     </LinearLayout> 
    </RelativeLayout> 

    <ScrollView 
     android:id="@+id/scrollView1" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:padding="0dp" 
     android:scrollbars="none" >" 

     <RelativeLayout 
      android:id="@+id/relativeLayout242" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:padding="0dp" > 


      <View android:background="#aaa" android:layout_width = "fill_parent" android:layout_height="1dp" android:layout_marginTop="0dp"/> 
      <View android:background="#aaa" android:layout_width = "fill_parent" android:layout_height="1dp" android:layout_marginTop="40dp"/> 
      <View android:background="#aaa" android:layout_width = "fill_parent" android:layout_height="1dp" android:layout_marginTop="80dp"/> 
      <View android:background="#aaa" android:layout_width = "fill_parent" android:layout_height="1dp" android:layout_marginTop="120dp"/> 
      <View android:background="#aaa" android:layout_width = "fill_parent" android:layout_height="1dp" android:layout_marginTop="160dp"/> 
      <View android:background="#aaa" android:layout_width = "fill_parent" android:layout_height="1dp" android:layout_marginTop="200dp"/> 
      <View android:background="#aaa" android:layout_width = "fill_parent" android:layout_height="1dp" android:layout_marginTop="240dp"/> 
      <View android:background="#aaa" android:layout_width = "fill_parent" android:layout_height="1dp" android:layout_marginTop="280dp"/> 
      <View android:background="#aaa" android:layout_width = "fill_parent" android:layout_height="1dp" android:layout_marginTop="320dp"/> 
      <View android:background="#aaa" android:layout_width = "fill_parent" android:layout_height="1dp" android:layout_marginTop="360dp"/> 
      <View android:background="#aaa" android:layout_width = "fill_parent" android:layout_height="1dp" android:layout_marginTop="400dp"/> 
      <View android:background="#aaa" android:layout_width = "fill_parent" android:layout_height="1dp" android:layout_marginTop="440dp"/> 
      <View android:background="#aaa" android:layout_width = "fill_parent" android:layout_height="1dp" android:layout_marginTop="480dp"/> 
      <View android:background="#aaa" android:layout_width = "fill_parent" android:layout_height="1dp" android:layout_marginTop="520dp"/> 
      <View android:background="#aaa" android:layout_width = "fill_parent" android:layout_height="1dp" android:layout_marginTop="560dp"/> 
      <View android:background="#aaa" android:layout_width = "fill_parent" android:layout_height="1dp" android:layout_marginTop="600dp"/> 
      <View android:background="#aaa" android:layout_width = "fill_parent" android:layout_height="1dp" android:layout_marginTop="640dp"/> 
      <View android:background="#aaa" android:layout_width = "fill_parent" android:layout_height="1dp" android:layout_marginTop="680dp"/> 
      <View android:background="#aaa" android:layout_width = "fill_parent" android:layout_height="1dp" android:layout_marginTop="720dp"/> 
      <View android:background="#aaa" android:layout_width = "fill_parent" android:layout_height="1dp" android:layout_marginTop="760dp"/> 
      <View android:background="#aaa" android:layout_width = "fill_parent" android:layout_height="1dp" android:layout_marginTop="800dp"/> 
      <View android:background="#aaa" android:layout_width = "fill_parent" android:layout_height="1dp" android:layout_marginTop="840dp"/> 
      <View android:background="#aaa" android:layout_width = "fill_parent" android:layout_height="1dp" android:layout_marginTop="880dp"/> 
      <View android:background="#aaa" android:layout_width = "fill_parent" android:layout_height="1dp" android:layout_marginTop="920dp"/> 

      <View android:background="#777" android:layout_width = "fill_parent" android:layout_height="1dp" android:layout_marginTop="20dp"/> 
      <View android:background="#777" android:layout_width = "fill_parent" android:layout_height="1dp" android:layout_marginTop="60dp"/> 
      <View android:background="#777" android:layout_width = "fill_parent" android:layout_height="1dp" android:layout_marginTop="100dp"/> 
      <View android:background="#777" android:layout_width = "fill_parent" android:layout_height="1dp" android:layout_marginTop="140dp"/> 
      <View android:background="#777" android:layout_width = "fill_parent" android:layout_height="1dp" android:layout_marginTop="180dp"/> 
      <View android:background="#777" android:layout_width = "fill_parent" android:layout_height="1dp" android:layout_marginTop="220dp"/> 
      <View android:background="#777" android:layout_width = "fill_parent" android:layout_height="1dp" android:layout_marginTop="260dp"/> 
      <View android:background="#777" android:layout_width = "fill_parent" android:layout_height="1dp" android:layout_marginTop="300dp"/> 
      <View android:background="#777" android:layout_width = "fill_parent" android:layout_height="1dp" android:layout_marginTop="340dp"/> 
      <View android:background="#777" android:layout_width = "fill_parent" android:layout_height="1dp" android:layout_marginTop="380dp"/> 
      <View android:background="#777" android:layout_width = "fill_parent" android:layout_height="1dp" android:layout_marginTop="420dp"/> 
      <View android:background="#777" android:layout_width = "fill_parent" android:layout_height="1dp" android:layout_marginTop="460dp"/> 
      <View android:background="#777" android:layout_width = "fill_parent" android:layout_height="1dp" android:layout_marginTop="500dp"/> 
      <View android:background="#777" android:layout_width = "fill_parent" android:layout_height="1dp" android:layout_marginTop="540dp"/> 
      <View android:background="#777" android:layout_width = "fill_parent" android:layout_height="1dp" android:layout_marginTop="580dp"/> 
      <View android:background="#777" android:layout_width = "fill_parent" android:layout_height="1dp" android:layout_marginTop="620dp"/> 
      <View android:background="#777" android:layout_width = "fill_parent" android:layout_height="1dp" android:layout_marginTop="660dp"/> 
      <View android:background="#777" android:layout_width = "fill_parent" android:layout_height="1dp" android:layout_marginTop="700dp"/> 
      <View android:background="#777" android:layout_width = "fill_parent" android:layout_height="1dp" android:layout_marginTop="740dp"/> 
      <View android:background="#777" android:layout_width = "fill_parent" android:layout_height="1dp" android:layout_marginTop="780dp"/> 
      <View android:background="#777" android:layout_width = "fill_parent" android:layout_height="1dp" android:layout_marginTop="820dp"/> 
      <View android:background="#777" android:layout_width = "fill_parent" android:layout_height="1dp" android:layout_marginTop="860dp"/> 
      <View android:background="#777" android:layout_width = "fill_parent" android:layout_height="1dp" android:layout_marginTop="900dp"/> 
      <View android:background="#777" android:layout_width = "fill_parent" android:layout_height="1dp" android:layout_marginTop="940dp"/> 

      <LinearLayout 
       android:id="@+id/linearLayout2" 
       android:layout_width="match_parent" 
       android:layout_height="wrap_content" 
       android:padding="0dp" > 

       <RelativeLayout 
        android:id="@+id/relativeLayout2" 
        android:layout_width="0dp" 
        android:layout_height="match_parent" 
        android:layout_weight="1" 
        android:padding="0dp" > 

        <View android:background="#aaa" android:layout_width = "1dp" android:layout_height="fill_parent" android:layout_alignParentRight="true"/> 

        <TextView 
         android:id="@+id/textView10" 
         android:layout_width="match_parent" 
         android:layout_height="wrap_content" 
         android:layout_marginTop="0dp" 
         android:gravity="center" 
         android:text="12am" /> 

        <TextView 
         android:id="@+id/textView10" 
         android:layout_width="match_parent" 
         android:layout_height="wrap_content" 
         android:layout_marginTop="40dp" 
         android:gravity="center" 
         android:text="1am" /> 

        <TextView 
         android:id="@+id/textView10" 
         android:layout_width="match_parent" 
         android:layout_height="wrap_content" 
         android:layout_marginTop="80dp" 
         android:gravity="center" 
         android:text="2am" /> 

        <TextView 
         android:id="@+id/textView10" 
         android:layout_width="match_parent" 
         android:layout_height="wrap_content" 
         android:layout_marginTop="120dp" 
         android:gravity="center" 
         android:text="3am" /> 

        <TextView 
         android:id="@+id/textView10" 
         android:layout_width="match_parent" 
         android:layout_height="wrap_content" 
         android:layout_marginTop="160dp" 
         android:gravity="center" 
         android:text="4am" /> 

        <TextView 
         android:id="@+id/textView10" 
         android:layout_width="match_parent" 
         android:layout_height="wrap_content" 
         android:layout_marginTop="200dp" 
         android:gravity="center" 
         android:text="5am" /> 

        <TextView 
         android:id="@+id/textView10" 
         android:layout_width="match_parent" 
         android:layout_height="wrap_content" 
         android:layout_marginTop="240dp" 
         android:gravity="center" 
         android:text="6am" /> 

        <TextView 
         android:id="@+id/textView10" 
         android:layout_width="match_parent" 
         android:layout_height="wrap_content" 
         android:layout_marginTop="280dp" 
         android:gravity="center" 
         android:text="7am" /> 

        <TextView 
         android:id="@+id/textView10" 
         android:layout_width="match_parent" 
         android:layout_height="wrap_content" 
         android:layout_marginTop="320dp" 
         android:gravity="center" 
         android:text="8am" /> 

        <TextView 
         android:id="@+id/textView10" 
         android:layout_width="match_parent" 
         android:layout_height="wrap_content" 
         android:layout_marginTop="360dp" 
         android:gravity="center" 
         android:text="9am" /> 

        <TextView 
         android:id="@+id/textView10" 
         android:layout_width="match_parent" 
         android:layout_height="wrap_content" 
         android:layout_marginTop="400dp" 
         android:gravity="center" 
         android:text="10am" /> 

        <TextView 
         android:id="@+id/textView10" 
         android:layout_width="match_parent" 
         android:layout_height="wrap_content" 
         android:layout_marginTop="440dp" 
         android:gravity="center" 
         android:text="11am" /> 

        <TextView 
         android:id="@+id/textView10" 
         android:layout_width="match_parent" 
         android:layout_height="wrap_content" 
         android:layout_marginTop="480dp" 
         android:gravity="center" 
         android:text="12pm" /> 

        <TextView 
         android:id="@+id/textView10" 
         android:layout_width="match_parent" 
         android:layout_height="wrap_content" 
         android:layout_marginTop="520dp" 
         android:gravity="center" 
         android:text="1pm" /> 

        <TextView 
         android:id="@+id/textView10" 
         android:layout_width="match_parent" 
         android:layout_height="wrap_content" 
         android:layout_marginTop="560dp" 
         android:gravity="center" 
         android:text="2pm" /> 

        <TextView 
         android:id="@+id/textView10" 
         android:layout_width="match_parent" 
         android:layout_height="wrap_content" 
         android:layout_marginTop="600dp" 
         android:gravity="center" 
         android:text="3pm" /> 

        <TextView 
         android:id="@+id/textView10" 
         android:layout_width="match_parent" 
         android:layout_height="wrap_content" 
         android:layout_marginTop="640dp" 
         android:gravity="center" 
         android:text="4pm" /> 

        <TextView 
         android:id="@+id/textView10" 
         android:layout_width="match_parent" 
         android:layout_height="wrap_content" 
         android:layout_marginTop="680dp" 
         android:gravity="center" 
         android:text="5pm" /> 

        <TextView 
         android:id="@+id/textView10" 
         android:layout_width="match_parent" 
         android:layout_height="wrap_content" 
         android:layout_marginTop="720dp" 
         android:gravity="center" 
         android:text="6pm" /> 

        <TextView 
         android:id="@+id/textView10" 
         android:layout_width="match_parent" 
         android:layout_height="wrap_content" 
         android:layout_marginTop="760dp" 
         android:gravity="center" 
         android:text="7pm" /> 

        <TextView 
         android:id="@+id/textView10" 
         android:layout_width="match_parent" 
         android:layout_height="wrap_content" 
         android:layout_marginTop="800dp" 
         android:gravity="center" 
         android:text="8pm" /> 

        <TextView 
         android:id="@+id/textView10" 
         android:layout_width="match_parent" 
         android:layout_height="wrap_content" 
         android:layout_marginTop="840dp" 
         android:gravity="center" 
         android:text="9pm" /> 

        <TextView 
         android:id="@+id/textView10" 
         android:layout_width="match_parent" 
         android:layout_height="wrap_content" 
         android:layout_marginTop="880dp" 
         android:gravity="center" 
         android:text="10pm" /> 

        <TextView 
         android:id="@+id/textView10" 
         android:layout_width="match_parent" 
         android:layout_height="40dp" 
         android:layout_marginTop="920dp" 
         android:gravity="center|top" 
         android:text="11pm" /> 
       </RelativeLayout> 

       <RelativeLayout 
        android:id="@+id/relativeLayout3" 
        android:layout_width="0dp" 
        android:layout_height="match_parent" 
        android:layout_weight="14" 
        android:padding="0dp" > 

        <LinearLayout 
         android:id="@+id/linearLayout3" 
         android:layout_width="match_parent" 
         android:layout_height="wrap_content" 
         android:layout_alignParentLeft="true" 
         android:layout_alignParentRight="true" 
         android:layout_alignParentTop="true" 
         android:padding="0dp" > 

         <RelativeLayout 
          android:id="@+id/relativeLayout4" 
          android:layout_width="0dp" 
          android:layout_height="match_parent" 
          android:layout_weight="1" > 

          <View android:background="#00f" android:layout_width = "fill_parent" android:layout_height="180dp" android:layout_marginTop="180dp"/> 

          <Button 
           android:id="@+id/button1" 
           android:layout_width="fill_parent" 
           android:layout_height="180dp" 
           android:layout_marginTop="180dp" 
           android:text="Some Event" /> 

         </RelativeLayout> 

         <RelativeLayout 
          android:id="@+id/relativeLayout5" 
          android:layout_width="0dp" 
          android:layout_height="match_parent" 
          android:layout_weight="1" > 

          <View android:background="#00f" android:layout_width = "fill_parent" android:layout_height="180dp" android:layout_marginTop="280dp"/> 

          <Button 
           android:id="@+id/button1" 
           android:layout_width="fill_parent" 
           android:layout_height="180dp" 
           android:layout_marginTop="280dp" 
           android:text="Some Event" /> 

         </RelativeLayout> 

         <RelativeLayout 
          android:id="@+id/relativeLayout6" 
          android:layout_width="0dp" 
          android:layout_height="match_parent" 
          android:layout_weight="1" > 

          <View android:background="#00f" android:layout_width = "fill_parent" android:layout_height="60dp" android:layout_marginTop="40dp"/> 

          <Button 
           android:id="@+id/button1" 
           android:layout_width="fill_parent" 
           android:layout_height="60dp" 
           android:layout_marginTop="40dp" 
           android:text="Some Event" /> 

         </RelativeLayout> 

         <RelativeLayout 
          android:id="@+id/relativeLayout7" 
          android:layout_width="0dp" 
          android:layout_height="match_parent" 
          android:layout_weight="1" > 

          <View android:background="#00f" android:layout_width = "fill_parent" android:layout_height="90dp" android:layout_marginTop="60dp"/> 

          <Button 
           android:id="@+id/button1" 
           android:layout_width="fill_parent" 
           android:layout_height="90dp" 
           android:layout_marginTop="60dp" 
           android:text="Some Event" /> 

          <View android:background="#00f" android:layout_width = "fill_parent" android:layout_height="120dp" android:layout_marginTop="340dp"/> 

          <Button 
           android:id="@+id/button1" 
           android:layout_width="fill_parent" 
           android:layout_height="120dp" 
           android:layout_marginTop="340dp" 
           android:text="Some Event" /> 

         </RelativeLayout> 

         <RelativeLayout 
          android:id="@+id/relativeLayout8" 
          android:layout_width="0dp" 
          android:layout_height="match_parent" 
          android:layout_weight="1" > 

          <View android:background="#00f" android:layout_width = "fill_parent" android:layout_height="180dp" android:layout_marginTop="380dp"/> 

          <Button 
           android:id="@+id/button1" 
           android:layout_width="fill_parent" 
           android:layout_height="180dp" 
           android:layout_marginTop="380dp" 
           android:text="Some Event" /> 

         </RelativeLayout> 

         <RelativeLayout 
          android:id="@+id/relativeLayout9" 
          android:layout_width="0dp" 
          android:layout_height="match_parent" 
          android:layout_weight="1" > 

          <View android:background="#00f" android:layout_width = "fill_parent" android:layout_height="180dp" android:layout_marginTop="480dp"/> 

          <Button 
           android:id="@+id/button1" 
           android:layout_width="fill_parent" 
           android:layout_height="180dp" 
           android:layout_marginTop="480dp" 
           android:text="Some Event" /> 

         </RelativeLayout> 

         <RelativeLayout 
          android:id="@+id/relativeLayout10" 
          android:layout_width="0dp" 
          android:layout_height="match_parent" 
          android:layout_weight="1" > 

          <View android:background="#00f" android:layout_width = "fill_parent" android:layout_height="180dp" android:layout_marginTop="340dp"/> 

          <Button 
           android:id="@+id/button1" 
           android:layout_width="fill_parent" 
           android:layout_height="180dp" 
           android:layout_marginTop="340dp" 
           android:text="Some Event" /> 

         </RelativeLayout>   

        </LinearLayout> 
       </RelativeLayout> 
      </LinearLayout> 
     </RelativeLayout> 
    </ScrollView> 

</LinearLayout> 

Il mio approccio è stato quello di rendere 40dp pari ad 1 ora di tempo. Pertanto, ogni volta che desidero aggiungere un evento della durata di 1,5 ore, creerò un pulsante di 60 dpi che inserirò nella posizione esatta in cui inizia l'ora (12am = 0dp dall'alto, 1pm = 40dp dall'alto , 2pm = 80d dall'alto, ecc.).

Le mie domande sono:

  1. Esiste un modo migliore di fare questo?
  2. Come posso convertire il mio XML in vista standalone che può essere aggiunto a qualsiasi progetto Android? (Ho in programma forse di fare un post sul blog sul prodotto finale)

Grazie!

+0

hey BVB come r u ??? ho bisogno dello stesso calendario come da te dato. Ho fatto il codice per quella vista? Non riesco a capire zappa per fare questo così se tu codice hv puoi darmi?/ – Google

+0

Cosa intendi? Quale vista? Il primo è uno screenshot di Google Calendar (l'applicazione web), mentre il secondo è uno screenshot del risultato dell'XML pubblicato. – BVB

+0

hey bvb voglio usare il primo e non riesco a farlo usando google api.if il codice hv per quello quindi mandami così posso vedere come funziona questo ?? – Google

risposta

18

Ho finito per seguire un approccio simile al mio post originale. Ho creato una vista di scorrimento con un layout lineare al suo interno. Ho quindi aggiunto sette layout relativi al layout lineare. Ciascuno dei layout relativi è un giorno. Mi sono assicurato che l'altezza di questi layout fosse pari al numero di minuti in un giorno. Ciò renderebbe 1 ora = 60 minuti = 60 dp, il che rende più facile la misurazione delle altezze degli eventi. Per gli eventi, ho creato una visualizzazione personalizzata in grado di visualizzare l'ora di inizio e di fine dell'evento, nonché il titolo dell'evento. Gli eventi sono stati aggiunti ai relativi layout con una proprietà layout_marginTop, il cui valore è uguale all'ora di inizio dell'evento in minuti dall'inizio del giorno. Questo sembrava funzionare bene.

Ecco un'anteprima di quello che ha finito per assomigliare:

Calendar preview

Ecco il layout XML: http://pastebin.com/jT4wQxeb

Il codice è troppo lungo per adattarsi al risposta.

Nota: calendar_zebra è semplicemente un layout di 60 * 24 = 1440 dpi con 1 dp di altezza orizzontale View s con uno sfondo grigio uniforme posizionato ogni 60 dpi. Ognuno rappresenta un marker per un'ora di tempo.

+0

Devo creare una vista del calendario uguale a quella che hai creato. Ho seguito i link che hai fornito ma non sono in grado di capire come creare una vista settimanale. Per favore mi aiuti su questo ... – Narendra

+0

Ho pubblicato il codice. Si prega di guardare i commenti qui: http://aleakymemory.blogspot.com/2012/09/android-room-manager.html – BVB

+0

pls pls inviare l'Xml –

3

1. Ecco quello che ho capire dalla fonte di Calendar

Si crea una visualizzazione personalizzata (DayView per l'agenda in un giorno) per l'intero layout nel xml.

Quindi si disegna la tela utilizzando il rettangolo e il testo come quello che è possibile vedere nell'app quando viene chiamato lo onDraw().

The View implementa OnClickListener e OnLongClickListener per l'evento. Quando fai clic sull'area di disegno, trasferisce la posizione del clic all'Evento con Data e ora corrispondenti (quindi ha calcolato un sacco di dimensioni correlate per evento, margine, evento dell'intero giorno quando viene chiamato l'override onSizeChanged()), quindi avvia l'attività se tale evento esiste, altrimenti crea un nuovo evento.

2.You necessario creare una classe estende View, dicono DayView, allora si dovrebbe aggiungere questo in attrs.xml

<resources> 
    <declare-styleable name="DayView"> 
    </declare-styleable> 
</resources> 

Quindi è possibile utilizzarlo come un tag XML nel layout con il nome del pacchetto. come qui:

<xxxxxxx.DayView 
     android:layout_height="wrap_content" 
     android:layout_width="match_parent" 
     android:id="@id/ui_schedule_dayview"> 

Here è possibile trovare il campione di farlo