I am trying to do a simple test example with Android Data Binding. I only want to show in my fragment the text "test" in the EditText named "title", but this text is not shown. Here is my code:
TestVM.java
public class TestVM extends BaseObservable {
public TestVM() {}
#Bindable
public String getText() {
return "test";
}
}
fr_login.xml
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="test"
type="de.theappguys.templateandroid.viewmodel.TestVM"/>
</data>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/transparent"
>
<TextView
android:id="#+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_marginTop="20dp"
android:text="#{test.text}"
android:textSize="22sp"
android:textStyle="bold"
android:textColor="#android:color/black"
/>
</RelativeLayout>
</layout>
FrLogin.java
#EFragment
public class FrLogin extends Fragment {
...
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
FrLoginBinding binding = DataBindingUtil.inflate(inflater, R.layout.fr_login, container, false);
return binding.getRoot();
}
...
build.gradle
android {
.....
dataBinding {
enabled = true
}
....
}
you need to set value to your binding
FrLoginBinding binding = DataBindingUtil.inflate(inflater, R.layout.fr_login, container, false);
binding.setTest(new TestVM());
Problem with your code is that there is no connection between your model and Fragment.
you have to bind your ViewModel as well. E.g
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
FrLoginBinding binding = DataBindingUtil.inflate(inflater, R.layout.fr_login, container, false);
binding.setTest(new TestVM());
return binding.getRoot();
}
You should add this line in build.gradle (:app):
buildFeatures {
viewBinding true
}
private Context mContent;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
FragmentBrandBinding binding = FragmentBrandBinding.inflate(inflater, container, false);
View view = binding.getRoot();
mContent = view.getContext();
return view;
}
Related
I'm learning RecyclerView and having trouble with my recycler:
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/bootik_recycler"
/>
And the class:
public class BotikFragment extends Fragment {
private RecyclerView recyclerView;
private View view;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view=inflater.inflate(R.layout.recycler_botik,container);
return view;
recyclerView=(RecyclerView)view.findViewById(R.id.bootik_recycler);
I'm getting an Unreachable Statement error.
Just put the last two statements in different order:
recyclerView=(RecyclerView)view.findViewById(R.id.bootik_recycler);
return view;
In my Android app I have an Activity with RecyclerView and when the user clicks on an item I call another Activity that has a TabLayout with 2 fragments, each tab for a set of fields to be filled by the user.
When I do not use data binding, all is fine, but when I change the code to use data binding this error message appears:
FragmentManager: No view found for id 0x7f0c0072
(mypackage:id/container) for fragment
ContatosFormFragment2 [...]
FragmentManager: Activity state:
AndroidRuntime: FATAL EXCEPTION: main
java.lang.IllegalArgumentException: No view found for id 0x7f0c0072 (mypackage:id/container) for fragment ContatosFormFragment2 [...] '.
The strange thing is that if I don’t include the ContatosFormFragment1 (so I have only one tab), the ContatosFormFragment2 works...
Also, if I change the tabs order, including ContatosFormFragment2 first an then ContatosFormFragment1, the error message is 'No view found [...] for fragment ContatosFormFragment1'
Note: I'll really aprecciate if you can focus on the main problem, I mean, don't worry about variable names, encapsulation, code style, etc ... This is an initial code that will be improved when working.
Below the code with and without data binding:
My Activity, no changes for data binding
public class ContatosFormActivity extends AppCompatActivity {
public User contato;
private SectionsPagerAdapter mSectionsPagerAdapter;
private ViewPager mViewPager;
TextView tNome, tTipo;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_contatos_form);
Utils.initToolbar(this,false);
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
mViewPager = (ViewPager) findViewById(R.id.container);
setupViewPager(mViewPager);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(mViewPager);
Cursor cursor = (new DbController(getBaseContext())).carregaContatoById(getIntent().getIntExtra("contatoId", -1));
contato = new User(cursor.getString(cursor.getColumnIndexOrThrow(DbHelper.NOME)));
contato.setTipoPessoa(cursor.getString(cursor.getColumnIndexOrThrow(DbHelper.TIPO_PESSOA)));
}
private void setupViewPager(ViewPager viewPager) {
SectionsPagerAdapter adapter = new SectionsPagerAdapter(getSupportFragmentManager());
adapter.addFragment(new ContatosFormFragment1(), "Principal");
adapter.addFragment(new ContatosFormFragment2(), "Histórico");
viewPager.setAdapter(adapter);
}
public class SectionsPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public void addFragment(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
/* constructor + getItem + getCount + getPageTitle ...*/
}}
Code without data binding
public class ContatosFormFragment1 extends Fragment{
private EditText inputName;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_contatos_tab1,container,false);
inputName = (EditText) view.findViewById(R.id.editText);
ContatosFormActivity contatosFormActivity = (ContatosFormActivity)getActivity();
inputName.setText(contatosFormActivity.contato.getNome());
return view;
}
}
public class ContatosFormFragment2 extends Fragment{
private EditText inputName;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_contatos_tab2,container,false);
inputTipoPessoa = (EditText) view.findViewById(R.id.tipo_pessoa);
ContatosFormActivity contatosFormActivity = (ContatosFormActivity)getActivity();
inputTipoPessoa.setText(contatosFormActivity.contato.getTipoPessoa());
return view;
}
}
fragment_contatos_tab1.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"
android:weightSum="1">
<android.support.design.widget.TextInputLayout
android:id="#+id/input_layout_name"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/editText"
android:layout_gravity="center_horizontal"
android:elegantTextHeight="false"
android:hint="Nome"/>
</android.support.design.widget.TextInputLayout>
</LinearLayout>
fragment_contatos_tab2.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"
android:weightSum="1">
<android.support.design.widget.TextInputLayout
android:id="#+id/input_layout_tipoPessoa"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/tipo_pessoa"
android:layout_gravity="center_horizontal"
android:elegantTextHeight="false"
android:hint="Tipo de Pessoa"/>
</android.support.design.widget.TextInputLayout>
</LinearLayout>
Code with data binding
public class ContatosFormFragment1 extends Fragment{
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_contatos_tab1,container,false);
ContatosFormActivity contatosFormActivity = (ContatosFormActivity)getActivity();
FragmentContatosTab1Binding binding = DataBindingUtil.setContentView(getActivity(), R.layout.fragment_contatos_tab1);
binding.setContato(contatosFormActivity.contato);
return view;
}
}
public class ContatosFormFragment2 extends Fragment{
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_contatos_tab2,container,false);
ContatosFormActivity contatosFormActivity = (ContatosFormActivity)getActivity();
FragmentContatosTab2Binding binding = DataBindingUtil.setContentView(getActivity(), R.layout.fragment_contatos_tab2);
binding.setContato(contatosFormActivity.contato);
return view;
}
}
fragment_contatos_tab1.xml
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable name="contato" type="net.simplifiedcoding.retrofitexample.models.User"/>
</data>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.TextInputLayout
android:id="#+id/input_layout_name"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/editText"
android:layout_gravity="center_horizontal"
android:text="#{contato.nome}"
android:elegantTextHeight="false"
android:hint="Nome"/>
</android.support.design.widget.TextInputLayout>
</LinearLayout>
</layout>
fragment_contatos_tab2.xml
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable name="contato" type="net.simplifiedcoding.retrofitexample.models.User"/>
</data>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.TextInputLayout
android:id="#+id/input_layout_tipoPessoa"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/tipo_pessoa"
android:layout_gravity="center_horizontal"
android:text="#{contato.tipoPessoa}"
android:elegantTextHeight="false"
android:hint="Tipo de Pessoa"/>
</android.support.design.widget.TextInputLayout>
</LinearLayout>
</layout>
I solved changing to this:
public class ContatosFormFragment1 extends Fragment{
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
ContatosFormActivity contatosFormActivity = (ContatosFormActivity)getActivity();
FragmentContatosTab1Binding binding = DataBindingUtil.inflate(
inflater, R.layout.fragment_contatos_tab1, container, false);
View view = binding.getRoot();
binding.setContato(contatosFormActivity.contato);
return view;
}
}
public class ContatosFormFragment2 extends Fragment{
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
ContatosFormActivity contatosFormActivity = (ContatosFormActivity)getActivity();
FragmentContatosTab2Binding binding = DataBindingUtil.inflate(
inflater, R.layout.fragment_contatos_tab2, container, false);
View view = binding.getRoot();
binding.setContato(contatosFormActivity.contato);
return view;
}
}
I have an xml file as shown below:
One.xml
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:background="#drawable/additemsbackground"
android:orientation="horizontal"
android:layout_marginRight="20dp"
android:layout_marginLeft="20dp">
<ImageView
android:id="#+id/btnaddtxt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right|center_vertical"
android:layout_marginRight="10dp"
android:adjustViewBounds="true"
android:src="#drawable/add" />
</LinearLayout>
This is my MainFragment:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LayoutInflater layoutInflater = LayoutInflater.from(MainActivity.this);
View myView = layoutInflater.inflate(R.layout.One,
null);
ImageView btnadd=(ImageView)myView.findViewById(R.id.btnaddtxt);
btnadd.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View arg0) {
Toast.makeText(getApplicationContext(),
"Clicked Add Text Button" , Toast.LENGTH_LONG)
.show();
}
});
}
When I'm trying to get the ImageView as shown in my MainFragment it always returns null.
Can anyone say me what's the correct way of doing this ?
Initialize your views in onCreateView(...) and not in onCreate(...) when using Fragments. Something like this
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.delivery_boys, container,
false);
ImageView btnadd=(ImageView)rootView .findViewById(R.id.btnaddtxt);
return rootView;
}
you are suppose to inflate view in onCreateView in your fragment class
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view= inflater.inflate(R.layout.delivery_boys, container,
false);
ImageView img=(ImageView)view.findViewById(R.id.your_img_view);
return view;
}
onCreateView function you get attached to the activity and you get you get view inflation opportunity in onCreate Method Fragment is initialized and not yet attached to activity.
#Override
public View setContentView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if (mChangeVehiclesView == null) {
mChangeVehiclesView = inflater.inflate(
R.layout.frag_vehicles_registered, null);
} else {
((ViewGroup) mChangeVehiclesView.getParent())
.removeView(mChangeVehiclesView);
}
mvehicleListView = (ListView) mChangeVehiclesView
.findViewById(R.id.frag_vehicle_registeres_list);
return mChangeVehiclesView;
}
I have been extending from the fragment, but getting a Undefined Error For FindViewByID. Here is the Code
public class hashingfragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_hashing, container, false);
return rootView;
}
public void Hash(View view){
EditText edit_text = (EditText)
getView().findViewById(R.id.editText1);
}
And here is the xml
<EditText
android:id="#+id/editText1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="#+id/textView1"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_marginTop="17dp"
android:ems="20"
android:inputType="textMultiLine"
android:hint="Enter the Text" >
<requestFocus />
</EditText>
What people are suggesting at in the comments above is:
public class hashingfragment extends Fragment {
// hold on to your EditText
private EditText editText;
#Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_hashing, container, false);
// get your EditText here from the inflated View
editText = (EditText) rootView.findViewById(R.id.editText1);
return rootView;
}
public void Hash(View view){
// now you can use 'editText' however you wish here
}
}
I'm attempting to customize the fragment layout by returning my own view hierarchy from onCreateView(LayoutInflater, ViewGroup, Bundle). This inflates my custom view, but seems to stack the views instead of inflating within, I see everything at once. Any help is appreciated.
MyActivity.java:
public class MyActivity extends FragmentActivity{
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getSupportFragmentManager().findFragmentById(android.R.id.content) == null) {
ArrayListFragment list = new ArrayListFragment();
getSupportFragmentManager().beginTransaction().add(android.R.id.content, list).commit();
}
}
public static class ArrayListFragment extends ListFragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
inflater.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.main, container);
return super.onCreateView(inflater, container, savedInstanceState);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
String List[] = {"Larry", "Moe", "Curly"};
setListAdapter(new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, List));
}
}
}
main.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"
android:paddingLeft="8dp"
android:paddingRight="8dp">
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="THIS IS A BUTTON" />
<ListView
android:id="#android:id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#00FF00"
android:layout_weight="1"
android:drawSelectorOnTop="false" />
<TextView
android:id="#android:id/empty"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FF0000"
android:text="No data" />
</LinearLayout>
I wasn't returning the new view within the onCreateView method of the ListFragment class. For instance:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.main, null);
return view;
}
All works well now in the land of Android!
I think you'd better
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.main, container, false);
return root;
}
optimized way and shot code
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.list_alphabet, container, false);
}
getSupportFragmentManager().beginTransaction().add(android.R.id.content, list).commit();
List is not accepted, it's looking for a fragment.
use this pattern, works perfectly!
inflater.inflate(R.layout.list_layout, container, false);
public View inflate (XmlPullParser parser, ViewGroup root, boolean attachToRoot)
attachToRoot Whether the inflated hierarchy should be attached to the root parameter? If false, root is only used to create the correct subclass of LayoutParams for the root view in the XML.