Autore Topic: [medio] Introduzione ai Fragment  (Letto 31821 volte)

Offline bradipao

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 4043
  • keep it simple
  • Respect: +567
    • Github
    • Google+
    • bradipao
    • Mostra profilo
  • Dispositivo Android:
    Nexus 5
  • Play Store ID:
    Bradipao
  • Sistema operativo:
    W7
[medio] Introduzione ai Fragment
« il: 25 Febbraio 2012, 10:01:11 CET »
+14
Livello di difficoltà : medio
Target SDK : 11+
Min SDK : 4
Sorgente : ZIP allegato e http://code.google.com/p/it-anddev-bradipao-janus/


NOTA : Scopo di questo tutorial non è fornire un esempio immediatamente utilizzabile di applicazione con Fragment, ma introdurre il concetto di Fragment e come cambia il modo di concepire le applicazioni che ne fanno uso.


Cosa sono i Fragment?

Prima di HoneyComb (la prima versione Android per tablet), nella programmazione dell'interfaccia grafica si parlava esclusivamente di Activity e View. Activity intesa come schermata in cui piazzare le varie View (EditView, TextView, etc). Con l'avvento dei tablet l'area disponibile sullo schermo è cresciuta significativamente, al punto da sentire l'esigenza di metterci quello che prima stava in due o più Activity.

La definizione ufficiale di Fragment è la seguente: Un Fragment rappresenta una funzione o una parte di interfaccia utente di una Activity. E' possibile combinare più Fragment in una singola Activity così da realizzare una interfaccia utente multi-pannello e poter riutilizzare un Fragment in più Activity. Pensate al Fragment come ad una parte modulare di una Activity, ha il proprio ciclo di vita, riceve eventi in input e può essere aggiunto o rimossa mentre l'Activity è visibile.

A livello pratico è importante sottolineare che il Fragment non sostituisce l'Activity, anzi ha senso solo all'interno di una Activity, proprio come qualsiasi altra View. Avremo quindi che una Activity potrà essere composta da un paio di Fragment e qualche View sparsa, e a sua volta ciascun Fragment conterrà un po' di View.

Facciamo un esempio pratico: nelle interfacce per smartphone siamo abituati da tempo ad avere una schermata per il menu a lista (esempio la lista contatti) ed una schermata separata per vederne i dettagli (esempio i dati del contatto). Passando al tablet, viene naturale avere tutto nella stessa schermata (lista contatti in pannello laterale e dettagli contatto cliccato al centro). E' chiaro che l'interfaccia per tablet può essere dichiarata tutta in un unico layout, però è naturale considerare i due oggetti (la lista contatti e il pannello dettagli) come ben distinti. Entrambi sono candidati ideali ad essere trasformati in Fragment.


IceCreamSandwich è uscito da poco, tablet con almeno HoneyComb non ce ne sono molti e comunque le app fatte per smartphone girano anche sui tablet, quindi perchè usare i Fragments da subito?


Domanda lecita, ed aggiungo anche che usare i Fragment non semplifica il codice delle applicazioni, anzi aggiunge un ulteriore grado di complessità (a parità di risultato finale). La risposta sintetica è che si tratta di un investimento per il futuro. Come mostrato più avanti in questo tutorial, nella realizzazione delle interfacce per tablet risulterà molto comodo fare uso dei Fragment e quindi sarà naturale riutilizzare quanto prodotto anche per l'interfaccia smartphone piuttosto che farne una separata.

I Fragment sono supportati solo a partire da Honeycomb (Android 3.0), per cui in teoria sarebbe necessario sviluppare due applicazioni distinte per i device pre e post HoneyComb. Per risolvere questo pesante vincolo, ci è stata messa a disposizione una Compatibility Library ufficiale, che consente di usarli (con qualche limitazione) anche a partire dalla versione 4 delle API (Android 1.6). In questo modo risulta molto più semplice sviluppare un'unica applicazione che abbracci tutte le versioni di Android in circolazione e che faccia uso dei Fragment.


Ok, ma quali sono i casi in cui i Fragment sono indispensabili?

L'esempio più semplice è l'interfaccia descritta sopra con lista contatti laterale e pannello centrale per i dettagli del contatto. Una volta realizzata questa interfaccia per tablet, è abbastanza banale riutilizzare i due Fragment già scritti all'interno di Activity distinte per l'interfaccia smartphone.

Una variante che si tende spesso a sottovalutare è quella del diverso layout per orientazioni diverse. Infatti orientando il tablet in verticale (portrait) potremmo decidere di non volere più entrambi i Fragment nella stessa schermata, ma passare all'approccio smartphone con schermate distinte. Di nuovo tutto abbastanza banale potendo riutilizzare i Fragment già scritti.

C'è poi il caso di interfacce molto complesse (non trattato in questo esempio), tipicamente quelle in cui all'interno della schermata del tablet sono presenti dei menu ed un'area generica in cui vengono visualizzate diverse tipologie di contenuti. In questi casi risulta comodissima la possibilità di mettere nell'area generica Fragment di tipologie diverse. Il framework consente facilmente di cambiare il Fragment correntemente assegnato all'area, gestisce transizioni animate e persino la cronologia di navigazione è integrata.


PREDISPORSI ALL'USO DEL SUPPORT PACKAGE (COMPATIBILITY LIBRARY)

Per poter usare i Fragment su Android pre-3.0 occorre includere nel progetto il Support Package ( Support Package | Android Developers ) e fare uso delle classi da esso fornite al posto di quelle native presenti solo da HoneyComb in poi.

  • Copiare il file android-support-v4.jar da %ANDROID-SDK%\extras\android\compatibility\v4 in un nuovo folder /libs sotto la root dell'applicazione
  • Cliccarci sopra col tasto destro, e selezionare add to build path per includerlo nella compilazione
  • Estendere le activity da FragmentActivity e non da Activity ( public class JanusActivity extends FragmentActivity )
  • Importare la classe Fragment dal support package e non quello nativo ( import android.support.v4.app.Fragment )


COME USARE I FRAGMENT NEL LAYOUT

Supponiamo di voler gestire due casistiche:
1) Orientazione Landscape : singola activity con due fragment



2) Orientazione Portrait : due activity, ciascuna con un fragment



In generale questo metodo di gestione può essere usato anche per avere layout distinti su smartphone e tablet.

Creiamo per ciascuna activity un file di layout, in cui ciascun Fragment sarà inserito proprio come se fosse una View. Per gestire le due casistiche metteremo in res/layout il layout per il caso landscape e in res/layout-port i due layout per le activity separate dell'orientazione vertical.

LAYOUT LANDSCAPE ac_main.xml

Codice (XML): [Seleziona]
<?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="horizontal" >

    <fragment
       android:id="@+id/menuFragment"
       android:layout_width="150dip"
       android:layout_height="match_parent"
       class="it.anddev.bradipao.janus.MenuFragment" >
    </fragment>

    <fragment
       android:id="@+id/bodyFragment"
       android:layout_width="match_parent"
       android:layout_height="match_parent"
       class="it.anddev.bradipao.janus.BodyFragment" >
    </fragment>

</LinearLayout>

LAYOUT PORTRAIT MENU ac_main.xml

Codice (XML): [Seleziona]
<?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="horizontal" >

    <fragment
       android:id="@+id/menuFragment"
       android:layout_width="match_parent"
       android:layout_height="match_parent"
       class="it.anddev.bradipao.janus.MenuFragment" />

</LinearLayout>

LAYOUT PORTRAIT BODY ac_body.xml

Codice (XML): [Seleziona]
<?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:orientation="vertical" >

    <fragment
       android:id="@+id/bodyFragment"
       android:layout_width="match_parent"
       android:layout_height="match_parent"
       class="it.anddev.bradipao.janus.BodyFragment" />

</LinearLayout>

A sua volta ciascun fragment avrà un suo file di layout, questa volta indipendente da qualsiasi orientazione:

LAYOUT MENUFRAGMENT fr_menu.xml

Codice (XML): [Seleziona]
<?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" >

    <Button
       android:id="@+id/btn1"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_gravity="center_horizontal"
       android:text="Send Text to Fragment" />

    <Button
       android:id="@+id/btn2"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_gravity="center_horizontal"
       android:text="Send Text to Activity" />

</LinearLayout>

LAYOUT BODYFRAGMENT fr_body.xml

Codice (XML): [Seleziona]
<?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:orientation="vertical" >

    <TextView
       android:id="@+id/detailsText"
       android:layout_width="wrap_content"
       android:layout_height="match_parent"
       android:layout_gravity="center_horizontal|center_vertical"
       android:layout_marginTop="20dip"
       android:text="...just.created..."
       android:textAppearance="?android:attr/textAppearanceLarge"
       android:textSize="30dip" />

</LinearLayout>

E' facile notare che sostituendo all'oggetto fragment i layout dei fragment stessi, si torna ai layout convenzionali a cui siamo abituati.


COME GESTIRE IL CODICE DEI FRAGMENT E DELLE ACTIVITY

A livello di codice java, avremo due file per le activity (uno per l'activity principale, sia essa a singolo o doppio fragment, e uno per l'activity secondaria nel caso di singolo fragment), e un file per ciascun Fragment.

Se nel contesto del layout i Fragment assomigliavano molto alle View, nel contesto del codice Java hanno molto in comune con le Activity, perchè devono in qualche modo condividerne il ciclo di vita. La restante parte di codice non è altro che codice Java necessario a gestire le View contenute nel Fragment.

In particolare nel codice dei Fragment per ora si noti come l'override dei metodi onAttach(), onCreate(), onActivityCreated() e onCreateView() sia molto simile ai corrispondenti dell'activity: in tali metodi deve essere messo il codice che prima veniva eseguito nel corrispondente metodo dell'activity. Per esempio in onCreateView() andremo a dichiarare i listener dei Button.

CODICE MENUFRAGMENT MenuFragment.java

Codice (Java): [Seleziona]
package it.anddev.bradipao.janus;

import android.app.Activity;
import android.support.v4.app.Fragment;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;

// extended from compatibility Fragment for pre-HC fragment support
public class MenuFragment extends Fragment {
   
   // views
   Button btn1,btn2;
   
   // activity listener
   private OnMenufragListener menufragListener;

   // interface for communication with activity
   public interface OnMenufragListener {
      public void onMenufrag(String s);
   }
   
   // onAttach
   @Override
   public void onAttach(Activity activity) {
      super.onAttach(activity);
      try {
         menufragListener = (OnMenufragListener) activity;
      } catch (ClassCastException e) {
         throw new ClassCastException(activity.toString()+" must implement OnMenufragListener");
      }
   }
   
   // onCreate
   @Override
   public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
   }

   // onActivityCreated
   @Override
   public void onActivityCreated(Bundle savedInstanceState) {
      super.onActivityCreated(savedInstanceState);
   }
   
   // onCreateView
   @Override
   public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState) {
      View view = inflater.inflate(R.layout.fr_menu,container,false);
     
      // get button BTN1
      btn1 = (Button)view.findViewById(R.id.btn1);
      // button listener
      btn1.setOnClickListener(new View.OnClickListener() {
         @Override
         public void onClick(View v) {
            sendBodyTextToFragment("Text From Fragment");
         }
      });
     
      // get button BTN2
      btn2 = (Button)view.findViewById(R.id.btn2);
      // button listener
      btn2.setOnClickListener(new View.OnClickListener() {
         @Override
         public void onClick(View v) {
            sendBodyTextToActivity("Text From Activity");
         }
      });
     
      return view;
   }
   
   // (recommended) method to send command to activity
   private void sendBodyTextToActivity(String s) {
      menufragListener.onMenufrag(s);
   }
   
   // alternate (not recommended) method with direct access to fragment
   private void sendBodyTextToFragment(String s) {
     
      // get body fragment (native method is getFragmentManager)
      BodyFragment fragment = (BodyFragment) getActivity().getSupportFragmentManager().findFragmentById(R.id.bodyFragment);
     
      // if fragment is not null and in layout, set text, else launch BodyActivity
      if ((fragment!=null)&&fragment.isInLayout()) {
         fragment.setText(s);
      } else {
         Intent intent = new Intent(getActivity().getApplicationContext(),BodyActivity.class);
         intent.putExtra("value",s);
         startActivity(intent);
      }
     
   }
   
}

CODICE BODYFRAGMENT BodyFragment.java

Codice (Java): [Seleziona]
package it.anddev.bradipao.janus;

import android.support.v4.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

//extended from compatibility Fragment for pre-HC fragment support
public class BodyFragment extends Fragment {

   // onCreate
   @Override
   public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
   }

   // onActivityCreated
   @Override
   public void onActivityCreated(Bundle savedInstanceState) {
      super.onActivityCreated(savedInstanceState);
   }
   
   // onCreateView
   @Override
   public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState) {
      View view = inflater.inflate(R.layout.fr_body,container,false);
      return view;
   }
   
   // set text
   public void setText(String item) {
      TextView view = (TextView) getView().findViewById(R.id.detailsText);
      view.setText(item);
   }
   
}

 
Usando i Fragment il codice utente si sposta per lo più all'interno dei Fragment stessi e ben poco rimane nel file delle activity (vedi codice sotto riportato), dove metteremo il codice che gestisce le transizioni tra layout ed il codice che permette ai fragment di comunicare.

Se non fosse per il listener (che spiegheremo dopo), nell'activity primaria non rimarremo altro che l'inflate del layout.

ACTIVITY PRIMARIA JanusActivity.java
 
Codice (Java): [Seleziona]
package it.anddev.bradipao.janus;

import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;

// main activity (FragmentActivity provides fragment compatibility pre-HC)
public class JanusActivity extends FragmentActivity implements MenuFragment.OnMenufragListener {
   
   // called when the activity is first created
   @Override
   public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.ac_main);
   }
   
   // MenuFragment listener
   @Override
   public void onMenufrag(String s) {
     
      // get body fragment (native method is getFragmentManager)
      BodyFragment fragment = (BodyFragment) getSupportFragmentManager().findFragmentById(R.id.bodyFragment);
     
      // if fragment is not null and in layout, set text, else launch BodyActivity
      if ((fragment!=null)&&fragment.isInLayout()) {
         fragment.setText(s);
      } else {
         Intent intent = new Intent(this,BodyActivity.class);
         intent.putExtra("value",s);
         startActivity(intent);
      }
     
   }
   
}

L'activity secondaria è quella visibile solo in portrait per mostrare il contenuto del secondo fragment. Contiene quindi un controllo sull'orientazione per tornare all'activity primaria nel caso in cui il terminale torni in landscape. In più contiene la lettura dell'extra, necessario per ricevere il testo da visualizzare nel secondo fragment.

ACTIVITY SECONDARIA BodyActivity.java

Codice (Java): [Seleziona]
package it.anddev.bradipao.janus;

import android.content.res.Configuration;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;

//created only when in portrait mode (FragmentActivity provides fragment compatibility pre-HC)
public class BodyActivity extends FragmentActivity {

   @Override
   protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
     
      // check orientation to avoid crash (this activity is not necessary in landscape)
      if (getResources().getConfiguration().orientation==Configuration.ORIENTATION_LANDSCAPE) {
         finish();
         return;
      } else setContentView(R.layout.ac_body);
     
      // show body content as requested in Intent extra
      Bundle extras = getIntent().getExtras();
      if (extras != null) {
         // get data from Intent extra
         String s = extras.getString("value");
         // get body fragment
         BodyFragment fragment = (BodyFragment) getSupportFragmentManager().findFragmentById(R.id.bodyFragment);
         // if fragment is not null and in layout set text
         if ((fragment!=null)&&fragment.isInLayout()) {
            fragment.setText(s);
         }
      }

   }
   
}

COMUNICARE TRA FRAGMENT

Abbiamo detto che all'interno del MenuFragment è presente un Button, alla cui pressione vogliamo aggiornare il testo presente nella TextView dell'altro Fragment.

Prima di dedicarci al Button, dotiamo il BodyFragment di una funzione che prende come parametro il testo da aggiornare e che si occupa di scriverlo nella giusta TextView. La funzione è banale, ma sarà utilissima perchè potrà essere chiamata dall'esterno del Fragment senza sapere niente di come è strutturato il Fragment stesso.

Codice (Java): [Seleziona]
   public void setText(String item) {
      TextView view = (TextView) getView().findViewById(R.id.detailsText);
      view.setText(item);
   }

Per gestire l'evento di pressione del Button, il modo più immediato (ma meno corretto) di farlo è gestire il tutto dall'interno del MenuFragment. Si controlla se l'altro Fragment è presente nell'activity (per capire in quale delle due casistiche ci troviamo), in caso negativo si lancia l'activity secondaria allegando negli Extra il testo da aggiornare. Altrimenti reperiamo il riferimento all'altro Fragment e richiamiamo la funzione che avevamo predisposto per aggiornare il testo.

Questa è la funzione richiamata alla pressione del relativo Button. Grazie alla getSupportFragmentManager() si può accedere al gestore dei Fragment che a sua volta di fornisce il riferimento al BodyFragment, quello che voglio aggiornare. A questo punto se mi trovo nel layout landscape tale riferimento sarà valido e potrò richiamare la sua setText sopra definita. Se invece mi trovo in portrait, richiamerò l'activity secondaria passando il testo da aggiornare negli extra.

Codice (Java): [Seleziona]
   // alternate (not recommended) method with direct access to fragment
   private void sendBodyTextToFragment(String s) {
     
      // get body fragment (native method is getFragmentManager)
      BodyFragment fragment = (BodyFragment) getActivity().getSupportFragmentManager().findFragmentById(R.id.bodyFragment);
     
      // if fragment is not null and in layout, set text, else launch BodyActivity
      if ((fragment!=null)&&fragment.isInLayout()) {
         fragment.setText(s);
      } else {
         Intent intent = new Intent(getActivity().getApplicationContext(),BodyActivity.class);
         intent.putExtra("value",s);
         startActivity(intent);
      }
     
   }

Il suddetto metodo funziona, però compromette uno dei vantaggi dell'uso dei Fragment: il fatto che il Fragment non dovrebbe essere consapevole del layout in cui si trova. In altre parole, il codice che abbiamo scritto sopra funziona solo se il layout rimane tale e quale, perchè se cambia anche solo il nome della classe dell'altro fragment, anche questo deve essere cambiato.

L'approccio corretto è usare l'activity per comunicare tra i Fragment. L'evento pressione del Button avviene nel MenuFragment, occorre quindi trasferirlo all'activity tramite un listener.

Nel MenuFragment dichiariamo l'interfaccia che sarà implementata nell'activity:

Codice (Java): [Seleziona]
   // activity listener
   private OnMenufragListener menufragListener;

   // interface for communication with activity
   public interface OnMenufragListener {
      public void onMenufrag(String s);
   }

Alla pressione del Button nel MenuFragment, viene inviato l'evento al listener dell'activity.

Codice (Java): [Seleziona]
      // get button BTN2
      btn2 = (Button)view.findViewById(R.id.btn2);
      // button listener
      btn2.setOnClickListener(new View.OnClickListener() {
         @Override
         public void onClick(View v) {
            sendBodyTextToActivity("Text From Activity");
         }
      });

   
   // (recommended) method to send command to activity
   private void sendBodyTextToActivity(String s) {
      menufragListener.onMenufrag(s);
   }

L'activity principale era stata dichiarata in modo da implementare il nostro listener.

public class JanusActivity extends FragmentActivity implements MenuFragment.OnMenufragListener
   
Il codice del listener è quasi uguale al precedente nel contenuto, la differenza concettuale è che in questo modo potete tranquillamente rimpiazzare un Fragment con un altro, preoccupandovi solo della sua interfaccia verso l'activity.

Codice (Java): [Seleziona]
   // MenuFragment listener
   @Override
   public void onMenufrag(String s) {
     
      // get body fragment (native method is getFragmentManager)
      BodyFragment fragment = (BodyFragment) getSupportFragmentManager().findFragmentById(R.id.bodyFragment);
     
      // if fragment is not null and in layout, set text, else launch BodyActivity
      if ((fragment!=null)&&fragment.isInLayout()) {
         fragment.setText(s);
      } else {
         Intent intent = new Intent(this,BodyActivity.class);
         intent.putExtra("value",s);
         startActivity(intent);
      }
     
   }
NON rispondo a domande nei messaggi privati
Bradipao @ Play Store

Offline xWOLKx

  • Utente junior
  • **
  • Post: 72
  • Adoro quella citazione western!
  • Respect: +7
    • xWOLKx
    • Wolkrasgt
    • Mostra profilo
    • ZondeIT
  • Dispositivo Android:
    Samsung Galaxy Ace
  • Sistema operativo:
    Windows7
Re:[medio] Introduzione ai Fragment
« Risposta #1 il: 25 Febbraio 2012, 13:42:04 CET »
0
Interessante, lo proverò sicuramente :D

Offline gsources75

  • Utente normale
  • ***
  • Post: 327
  • Respect: +9
    • Google+
    • pepigno75
    • devandroid_it
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy Nexus S - Vodafone Smart -BB Bold- Iphone 4-
  • Play Store ID:
    Giuseppe+Sorce
  • Sistema operativo:
    Ubuntu-Windows Seven- Mac Lion
Re:[medio] Introduzione ai Fragment
« Risposta #2 il: 12 Marzo 2012, 08:28:11 CET »
0
Li sto studiando in questi giorni.
Ottimo articolo :)
La domanda stupida è quella che non si fa

Offline eagledeveloper

  • Translate Team
  • Utente senior
  • ****
  • Post: 516
  • Respect: +37
    • Google+
    • 347516210
    • dark_pinz
    • @WandDStudios
    • Mostra profilo
    • W&D Studios
  • Dispositivo Android:
    HTC One X e HTC One
  • Play Store ID:
    W%26D+Studios
  • Sistema operativo:
    Ubuntu / Windows 7
Re:[medio] Introduzione ai Fragment
« Risposta #3 il: 28 Marzo 2012, 10:42:00 CEST »
0
Bel tutorial, molto utile per iniziare  :-)
I numeri contano molto di più del seme.

Offline Giovanni D'Addabbo

  • Utente normale
  • ***
  • Post: 163
  • Respect: +8
    • Google+
    • giovannid
    • giovanni.daddabbo
    • magoscuro
    • Mostra profilo
    • Rhubbit.it - Sviluppo app Android/iOs
  • Dispositivo Android:
    Nexus 5
  • Play Store ID:
    Rhubbit srl
  • Sistema operativo:
    Windows/Mac/Linux
Re:[medio] Introduzione ai Fragment
« Risposta #4 il: 28 Marzo 2012, 15:38:42 CEST »
0
ottimo tutorial....poi il problema che avevo sai a cosa era dovuto? :)
non avevo esteso la classe giusta :D :D succede a lavorare di notte :D :D

Offline jocker99

  • Nuovo arrivato
  • *
  • Post: 39
  • Respect: +2
    • Mostra profilo
  • Dispositivo Android:
    samsung galaxy mini 2
  • Sistema operativo:
    debian 6 - 64 bit
Re:[medio] Introduzione ai Fragment
« Risposta #5 il: 15 Agosto 2012, 16:55:49 CEST »
0
Salve,  scusa ma ti pongo questa domanda e questo dubbio,  ma perche' ci sono due file per la gestione dell'activity?, citandoti " (uno per l'activity principale, sia essa a singolo o doppio fragment, e uno per l'activity secondaria nel caso di singolo fragment)" non ne capisco il motivo  :-(
nel codice dice che la seconda serve solo per la visualizzazione verticale come mai questa scelta?

grazie mille

Offline bradipao

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 4043
  • keep it simple
  • Respect: +567
    • Github
    • Google+
    • bradipao
    • Mostra profilo
  • Dispositivo Android:
    Nexus 5
  • Play Store ID:
    Bradipao
  • Sistema operativo:
    W7
Re:[medio] Introduzione ai Fragment
« Risposta #6 il: 16 Agosto 2012, 16:55:41 CEST »
+1
Salve,  scusa ma ti pongo questa domanda e questo dubbio,  ma perche' ci sono due file per la gestione dell'activity?, citandoti " (uno per l'activity principale, sia essa a singolo o doppio fragment, e uno per l'activity secondaria nel caso di singolo fragment)" non ne capisco il motivo  :-(
nel codice dice che la seconda serve solo per la visualizzazione verticale come mai questa scelta?

grazie mille

In caso di orientazione portrait, cioé quando i due fragment staranno in due schermate diverse, serve appunto una activity per la seconda schermata. Questo ovviamente perché é stato scelto un approccio convenzionale, cioé di avere una activity distinta per ciascuna schermata.
NON rispondo a domande nei messaggi privati
Bradipao @ Play Store

Offline skizzato

  • Nuovo arrivato
  • *
  • Post: 1
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    HTC Wildfire
  • Sistema operativo:
    OS X
Re:[medio] Introduzione ai Fragment
« Risposta #7 il: 30 Agosto 2012, 16:39:21 CEST »
0
Ciao,
innanzitutto grazie mille per l'ottimo tutorial.
Volevo chiedere : come fare invece per determinare il layout anche in base al device (phone o tablet) ?
La casistica è : doppio fragment per tablet in landscape 3.0+, singolo fragment per tablet in portrait, entrambi gli orientamenti del device (sia 2.3 che successivi) e per tablet in landscape ma 3.0- .

Grazie mille

Offline bradipao

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 4043
  • keep it simple
  • Respect: +567
    • Github
    • Google+
    • bradipao
    • Mostra profilo
  • Dispositivo Android:
    Nexus 5
  • Play Store ID:
    Bradipao
  • Sistema operativo:
    W7
Re:[medio] Introduzione ai Fragment
« Risposta #8 il: 30 Agosto 2012, 16:45:41 CEST »
0
Volevo chiedere : come fare invece per determinare il layout anche in base al device (phone o tablet) ?

Da una ricerca lampo ho ritrovato questo codice, ma non ricordo se aveva delle controindicazioni. Se puoi provarlo e magari tornare a confermarlo, sarebbe perfetto.

Codice (Java): [Seleziona]
public static boolean isTablet(Context context) {
    return (context.getResources().getConfiguration().screenLayout
            & Configuration.SCREENLAYOUT_SIZE_MASK)
            >= Configuration.SCREENLAYOUT_SIZE_LARGE;
}
NON rispondo a domande nei messaggi privati
Bradipao @ Play Store

Offline MarcoDuff

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 1073
  • Respect: +202
    • Google+
    • marcoduff
    • Mostra profilo
    • MarcoDuff's Blog
  • Dispositivo Android:
    Samsung Galaxy Nexus
  • Play Store ID:
    MarcoDuff
  • Sistema operativo:
    Windows 7
Re:[medio] Introduzione ai Fragment
« Risposta #9 il: 30 Agosto 2012, 18:09:56 CEST »
0
Da una ricerca lampo ho ritrovato questo codice, ma non ricordo se aveva delle controindicazioni. Se puoi provarlo e magari tornare a confermarlo, sarebbe perfetto.

Codice (Java): [Seleziona]
public static boolean isTablet(Context context) {
    return (context.getResources().getConfiguration().screenLayout
            & Configuration.SCREENLAYOUT_SIZE_MASK)
            >= Configuration.SCREENLAYOUT_SIZE_LARGE;
}

Il problema di questo codice (già da me usato in una app) è il Galaxy Note! Sinceramente, nemmeno io so come considerlo... è un tablet o uno smartphone?

Offline Nicola_D

  • Utente storico
  • *****
  • Post: 2479
  • SBAGLIATO!
  • Respect: +323
    • Github
    • Google+
    • nicoladorigatti
    • Mostra profilo
  • Dispositivo Android:
    Nexus 6p, Nexus 4, Nexus S, Nexus 7(2012)
  • Sistema operativo:
    Windows 7
Re:[medio] Introduzione ai Fragment
« Risposta #10 il: 30 Agosto 2012, 19:38:22 CEST »
0
Il problema di questo codice (già da me usato in una app) è il Galaxy Note! Sinceramente, nemmeno io so come considerlo... è un tablet o uno smartphone?
smartphone mi pare, dalla risoluzione è un xhdpi o sbaglio?
« Ultima modifica: 30 Agosto 2012, 19:40:48 CEST da Nicola_D »
IMPORTANTE:NON RISPONDO A PROBLEMI VIA MESSAGGIO PRIVATO
LOGCAT: Non sai cos'è? -> Android Debug Bridge | Android Developers
               Dov'è in Eclipse? -> Window -> Open Prospective -> DDMS e guarda in basso!
[Obbligatorio] Logcat, questo sconosciuto! (Gruppo AndDev.it LOGTFO) - Android Developers Italia

Offline matleyit

  • Nuovo arrivato
  • *
  • Post: 6
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    HTC Desire
Re:[medio] Introduzione ai Fragment
« Risposta #11 il: 05 Settembre 2012, 09:28:14 CEST »
0
Io avrei una domanda più generale: per usare Fragment e quant'altro relativi ad Android v3.0 o superiore dobbiamo usare le support library v4 per la compatibilità all'indietro.
Quindi i nostri Fragment provengono da android.support.v4.app, package che inseriamo nel progetto Android.
Ma quando l'app gira su Android v3.0 o superiore, prenderà sempre il Fragment da quel package giusto ?
Quindi le support ci servono per un periodo "transazionale" che decide lo sviluppatore immagino; quando lo sviluppatore deciderà di non supportare più android < 3 dovrà rimuovere il package e cambiare tutti gli import.....
In sostanza, non c'è un modo furbo che capisce quando parte l'app che versione di Android ho e se è < 3 prende i Fragment dalla support invece se è >= 3 li prende dal package android.app ... se no bisognerebbe farlo a mano con le reflection ma sarebbe un bel bordello di codice da scrivere :), giusto ?
Grazie.
« Ultima modifica: 05 Settembre 2012, 09:29:54 CEST da matleyit »

Offline bradipao

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 4043
  • keep it simple
  • Respect: +567
    • Github
    • Google+
    • bradipao
    • Mostra profilo
  • Dispositivo Android:
    Nexus 5
  • Play Store ID:
    Bradipao
  • Sistema operativo:
    W7
Re:[medio] Introduzione ai Fragment
« Risposta #12 il: 05 Settembre 2012, 09:40:21 CEST »
0
Io avrei una domanda più generale: per usare Fragment e quant'altro relativi ad Android v3.0 o superiore dobbiamo usare le support library v4 per la compatibilità all'indietro.
Quindi i nostri Fragment provengono da android.support.v4.app, package che inseriamo nel progetto Android.
Ma quando l'app gira su Android v3.0 o superiore, prenderà sempre il Fragment da quel package giusto ?
Quindi le support ci servono per un periodo "transazionale" che decide lo sviluppatore immagino; quando lo sviluppatore deciderà di non supportare più android < 3 dovrà rimuovere il package e cambiare tutti gli import.....
In sostanza, non c'è un modo furbo che capisce quando parte l'app che versione di Android ho e se è < 3 prende i Fragment dalla support invece se è >= 3 li prende dal package android.app ... se no bisognerebbe farlo a mano con le reflection ma sarebbe un bel bordello di codice da scrivere :), giusto ?
Grazie.

Sono abbastana sicuro che la compatibility library implementi proprio questo modo furbo, cioè quando rileva Android >=3 allora usa i Fragment "ufficiali".
NON rispondo a domande nei messaggi privati
Bradipao @ Play Store

Offline Nicola_D

  • Utente storico
  • *****
  • Post: 2479
  • SBAGLIATO!
  • Respect: +323
    • Github
    • Google+
    • nicoladorigatti
    • Mostra profilo
  • Dispositivo Android:
    Nexus 6p, Nexus 4, Nexus S, Nexus 7(2012)
  • Sistema operativo:
    Windows 7
Re:[medio] Introduzione ai Fragment
« Risposta #13 il: 05 Settembre 2012, 09:58:49 CEST »
0
Sono abbastana sicuro che la compatibility library implementi proprio questo modo furbo, cioè quando rileva Android >=3 allora usa i Fragment "ufficiali".
credo anche io, dovrei verificare i sorgenti (che sicuramente sono open), ma mi pare di averne sentito parlare... se mi ricordo stasera googlo un po a riguardo
IMPORTANTE:NON RISPONDO A PROBLEMI VIA MESSAGGIO PRIVATO
LOGCAT: Non sai cos'è? -> Android Debug Bridge | Android Developers
               Dov'è in Eclipse? -> Window -> Open Prospective -> DDMS e guarda in basso!
[Obbligatorio] Logcat, questo sconosciuto! (Gruppo AndDev.it LOGTFO) - Android Developers Italia

Offline matleyit

  • Nuovo arrivato
  • *
  • Post: 6
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    HTC Desire
Re:[medio] Introduzione ai Fragment
« Risposta #14 il: 05 Settembre 2012, 10:20:55 CEST »
0
credo anche io, dovrei verificare i sorgenti (che sicuramente sono open), ma mi pare di averne sentito parlare... se mi ricordo stasera googlo un po a riguardo

Allora così sarebbe fico ;). Grazie mille