2016-01-10 15 views
67

Sto cercando di seguire l'esempio di associazione dati da parte di Google doc ufficiale https://developer.android.com/tools/data-binding/guide.htmlCome utilizzare associazione dati con Frammento

solo che sto cercando di applicare i dati-biding ad un frammento, non un'attività.

l'errore Attualmente sto ricevendo durante la compilazione è

Error:(37, 27) No resource type specified (at 'text' with value '@{marsdata.martianSols}.

onCreate per frammento si presenta così:

@Override 
public void onCreate(@Nullable Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    MartianDataBinding binding = MartianDataBinding.inflate(getActivity().getLayoutInflater()); 
    binding.setMarsdata(this); 
} 

onCreateView per frammento si presenta così:

@Nullable 
@Override 
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 
    return inflater.inflate(R.layout.martian_data, container, false); 
} 

e parte s del mio file di layout per il frammento si presenta così:

<?xml version="1.0" encoding="utf-8"?> 

<layout xmlns:android="http://schemas.android.com/apk/res/android"> 
    <data> 
     <variable 
      name="marsdata" 
      type="uk.co.darkruby.app.myapp.MarsDataProvider" /> 
    </data> 
... 

     <TextView 
      android:layout_height="wrap_content" 
      android:layout_width="wrap_content" 
      android:text="@{marsdata.martianSols}" 
     /> 

    </RelativeLayout> 
</layout> 

il mio sospetto è che MartianDataBinding non sa quale file di layout si suppone che fosse legato con - da qui l'errore. Eventuali suggerimenti?

risposta

150

I dati applicazione vincolante deve essere nel metodo onCreateView del frammento, eliminare qualsiasi associazione dati presenti nel metodo OnCreate, tua onCreateView dovrebbe assomigliare a questa:

public View onCreateView(LayoutInflater inflater, 
         @Nullable ViewGroup container, 
         @Nullable Bundle savedInstanceState) { 
    MartianDataBinding binding = DataBindingUtil.inflate(
      inflater, R.layout.martian_data, container, false); 
    View view = binding.getRoot(); 
    //here data must be an instance of the class MarsDataProvider 
    binding.setMarsdata(data); 
    return view; 
} 
+0

questa è esattamente la soluzione che mi è venuta in mente, dopo aver giocato con esso, non ho mai postato la risposta qui, grazie! ottieni il segno di spunta! –

+0

Ho dovuto aggiungere la chiamata a super per generare la mia classe Binding. –

+1

Wow. Ho lottato con la mia testa per due giorni fino a quando ho visto la tua risposta @hdioui abdeljalil. Grazie!! –

5

si può semplicemente recuperare vista degli oggetti come indicato di seguito

public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 

View view = DataBindingUtil.inflate(inflater, R.layout.layout_file, container, false).getRoot(); 

return view; 

} 
1

Prova questo in Android DataBinding

FragmentMainBinding binding; 

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
          Bundle savedInstanceState) { 
     binding = DataBindingUtil.inflate(inflater, R.layout.fragment_main, container, false); 
     View rootView = binding.getRoot(); 
     initInstances(savedInstanceState); 
     return rootView; 
} 
4

funziona nel mio codice.

private FragmentSampleBinding dataBiding; 
private SampleListAdapter mAdapter; 

@Nullable 
@Override 
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 
    super.onCreateView(inflater, container, savedInstanceState); 
    dataBiding = DataBindingUtil.inflate(inflater, R.layout.fragment_sample, null, false); 
    return mView = dataBiding.getRoot(); 
} 
19

Si sono effettivamente incoraggiati a utilizzare il metodo inflate del vostro generato vincolante e non il DataBindingUtil:

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
    MainFragmentBinding binding = MainFragmentBinding.inflate(inflater, container, false); 
    //set variables in Binding 
    return binding.getRoot(); 
} 

Docs for DataBindingUtil.inflate():

utilizzare questa versione solo se layoutId si conosce in anticipo . Altrimenti, utilizzare il metodo di gonfiaggio del Binding generato per garantire un gonfiaggio sicuro per il tipo.

+0

Sfortunatamente mi sta uccidendo con l'errore 'non può essere risolto in un tipo' su build. Non è affidabile secondo me. Se prima vado con 'DataBindingUtil.inflate (inflater, R.layout.fragment_camera, container, false);' e poi lo cambio in 'FragmentCameraBinding.inflate (inflater, container, false);', funziona, ma dopo averlo ricostruito restituisce l'errore –

+0

Funziona alla grande. In realtà non è necessario specificare il res id di layout (cosa che mi stavo chiedendo prima) poiché preleva automaticamente dal file di bind generato. –

1

Kotlin sintassi:

lateinit var binding: MartianDataBinding 
override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? { 
    binding = DataBindingUtil.inflate(inflater, R.layout.martian_data, container, false) 
    return binding.root 
} 
0

Un altro esempio in Kotlin:

override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? { 
    val binding = DataBindingUtil 
      .inflate<MartianDataBinding>(
        inflater, 
        R.layout.bla, 
        container, 
        false 
      ) 

    binding.modelName = // .. 

    return binding.root 
} 

Nota che il nome "MartianDataBinding" dipende dal nome del file di layout. Se il file è denominato "martian_data", il nome corretto sarà MartianDataBinding.

Problemi correlati