I use fragment with view-binding but there is an interesting thing, I can not get the value in the onViewCreated scope, only in the binding button with click event listener scope.
Fragment.java:
public class Fragment extends Fragment {
private FragmentBinding binding;
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment, container, false);
return rootView;
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
binding = FragmentBinding.bind(view);
final String amount1 = binding.formAmountInput.getText().toString();
binding.formSaveButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String amount2 = binding.formAmountInput.getText().toString();
Toast.makeText(mContext, amount1, Toast.LENGTH_SHORT).show(); // gives nothing, why?
Toast.makeText(mContext, amount2, Toast.LENGTH_SHORT).show(); // works, shows input data
}
});
}
xml part:
<com.google.android.material.textfield.TextInputLayout
android:id="#+id/form_amount_layout"
style="#style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:endIconMode="clear_text">
<com.google.android.material.textfield.TextInputEditText
android:id="#+id/form__amount_input"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="number|numberDecimal|numberSigned"
/>
</com.google.android.material.textfield.TextInputLayout>
final String amount1 = binding.formAmountInput.getText().toString();
// gives nothing, why?
Well you are getting the content of the field at that particular point in time. And since you just inflated the view and there is no default text, amount1 is empty.
If you add android:text="default text" to your TextInputEditText, your amount1 will have something to read.
amount1 will not automatically update when you edit the text! Hence it only makes sense to call .getText().toString() in the onClick Listener or in a TextWatcher.
Related
I am using fragment have to Textfield in it. one is for name and other is phone number. Validation for both work just fine. But when I Toast it says null/false.
EditText tPername = (EditText) getView().findViewById(R.id.txtPer);
This is xml
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/txtPer"
android:layout_marginBottom="15dp"
android:background="#drawable/textbox"
android:layout_gravity="center_horizontal"
android:inputType="textPersonName"/>
When I Toast R.id.txtPer it says null.
This is my java code
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_add_customer, container, false);
view.findViewById(R.id.button3).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
doAdd(view);
}
});
return view;
}
public void doAdd(View view) {
String MobilePattern = "[0-9]{10}";
EditText tPername = (EditText) getView().findViewById(R.id.txtPer);
EditText tMobnum = (EditText) getView().findViewById(R.id.txtMob);
if (TextUtils.isEmpty(tPername.getText().toString())) {
tPername.setError("Please fill this field");
return;
} else if (!tMobnum.getText().toString().matches(MobilePattern)) {
tMobnum.setError("Mobile number must be entered 10 digits only");
return;
}
}
type a (EditText tPername = (EditText) getView().findViewById(R.id.txtPer);)
in the onViewCreated
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
EditText tPername = (EditText) getView().findViewById(R.id.txtPer);
}
String name= tPername.getText().toString();
This solved my problem.Thanks
I have a Fragment that has a listview,
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:id="#+id/containerMySubjects"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="15dp">
<ListView
android:id="#+id/lvSubjectLists"
android:layout_width="match_parent"
android:layout_height="match_parent">
</ListView>
</LinearLayout>
</LinearLayout>
I want to transfer the data from the listiview when selected to a new fragment. Here is my code in my onItemClick
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
InstructorFragmentSelectedSubject newFragment = new InstructorFragmentSelectedSubject();
Bundle args = new Bundle();
args.putString("code", code);
args.putString("title", title);
newFragment.setArguments(args);
getFragmentManager().beginTransaction().replace(R.id.containerMySubjects, newFragment).commit();
}
Here is my code in my new fragment, onCreateView
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_instructor_selected_subject, container, false);
tvSelectedCode = (TextView) view.findViewById(R.id.tvSelectedCode);
tvSelectedTitle = (TextView) view.findViewById(R.id.tvSelectedTitle);
String code = getArguments().getString("code");
String title = getArguments().getString("title");
tvSelectedCode.setText(code);
tvSelectedTitle.setText(title);
return view;
}
Try to change LinearLayout to Frame Layout, and see what will happens :)
I think yout code add fragment below your listview, and it has match_parent so it is invisible for user.
Try to avoid making containers for fragment with child view. Better create new fragment with listview and than add to the container. Than replace view by clicking listitem.
//EDITED:
If you change listview to listview fragment you will need communication between fragments. In your listview click listener you should make a callback to the activity, and activity can change fragments using FragmentManager and put some values to the new fragment.
Here you can check how to add callback:
https://developer.android.com/training/basics/fragments/communicating.html
Read Fragment Life Cycle try this code.
private String code = null;
private String title = null;
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_instructor_selected_subject, container, false);
tvSelectedCode = (TextView) view.findViewById(R.id.tvSelectedCode);
tvSelectedTitle = (TextView) view.findViewById(R.id.tvSelectedTitle);
tvSelectedCode.setText(code);
tvSelectedTitle.setText(title);
return view;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
code = getArguments().getString("code");
title = getArguments().getString("title");
}
}
I'm new to fragments and they are a bit confusing to me right now.
I have read alot and actually built a test app using this tutorial
I was able to add more tabs and so on. But I don't want to display static
content (xmls). I want to be able to modify the UI add listviews, load json data with asynctasck and so on but the very first attempt I made has failed.
So on Tab1:
public class Tab1 extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View v =inflater.inflate(R.layout.tab_1,container,false);
return v;
}
}
I tried to declare a textview and edit it's text with settext but
I get a crash and also findviewbyid is not available as a method.
It didn't throw and error when I typed getView().findViewById but
that's not the problem.
Are fragments limited or very different from traditional activities?
Do I need to make never ending customizations
in order to get a listview loading?
Thank you.
You should declare your TextView as a Member variable for your class and get a reference to that view in onCreateView like:
public class Tab1 extends Fragment {
// your TextView member variable
private TextView mTextView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, #Nullable Bundle savedInstanceState) {
View v =inflater.inflate(R.layout.tab_1, container, false);
mTextView = (TextView) v.findViewById(R.id.my_text_view);
return v;
}
// It is safe to access the views here, not in onCreate since it is called before onCreateView
#Override
public void onActivityCreated(Bundle savedInstanceState){
super.onActivityCreated(savedInstanceState);
mTextView.setText("Hello, World!");
}
}
For reference on the Fragment lifecycle
Are fragments limited or very different from traditional activities?
A Fragment has its own lifecycle like that of an Activity but it is dependent upon the lifecycle of its parent Activity, so to answer your question they are not very different, it is just a good practice for modularizing code.
Do I need to make never ending customizations in order to get a listview loading?
A little unclear what you mean by never ending customizations but loading a dynamic ListView is very simple in Android.
For Example:
using fragment_one.xml we have just a FrameLayout
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/fl_list_container"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
And the code:
public class Tab1 extends Fragment {
// your FrameLayout member variable
private FrameLayout mFlParent;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, #Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_one, container, false);
mFlParent = (FrameLayout) v.findViewById(R.id.fl_list_container);
return v;
}
// It is safe to access the views here, not in onCreate since it is called before onCreateView
#Override
public void onActivityCreated(Bundle savedInstanceState){
super.onActivityCreated(savedInstanceState);
// Create a new list, adapter and add a item click listener
ListView myList = new ListView(context); // context needed
myList.setAdapter(new ArrayAdapter<String>(context, android.R.id.simple_list_item_1, new String []{"Item 1", "Item 2", "Item 3", "Item 4"}));
myList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//... handle clicks on list items as usual
}
});
// add the view to the FrameLayout
mFlParent.addView(myList); // may want to call mFlParent.removeAllViews(); before adding just to be safe
}
}
Good luck and happy coding.
Fragment doesn't have an activity methods.
If you want to use findViewById methods, you should use a class field.
public class Tab1 extends Fragment {
private View mView;
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
mView = inflater.inflate(R.layout.tab_1,container,false);
return mView;
}
#Override
public void onCreate() {
// here you can use `findViewById` method via `mView` variable
mView.findViewById(YOUR_VIEW_ID);
}
}
There is basically 2 method to be use in fragment
1. onCreateView
2. onViewCreated
First one is use to inflate layout on your fragment
Second one is use to find all view used in your layout.
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, #Nullable Bundle savedInstanceState) {
View v =inflater.inflate(R.layout.tab_1, container, false);
return v;
}
#Override
public void onViewCreated(View v){
mTextView = (TextView) v.findViewById(R.id.my_text_view);
mTextView.setText("Hello, World!");
}
I'm doing a Navigation Drawer app. I have all the cases working, I mean, when in touch a section the app goes to the right View. But when I want to start coding I don't know how to use methods inside the View. I think my code will explain better than me:
public class News extends android.support.v4.app.Fragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
setText();
return inflater.inflate(R.layout.lay_news, container, false);
}
public void setText(){
TextView texts = (TextView) getView().findViewById(R.id.textView);
texto.setText("hi");
}
}
NullPointerException when I call the method setText. I know that it's the TextView definition, but I don't know how to "find" it in the layout without getView() or getActivty(), both return a NullPointerException when the view loads.
Just do
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v=inflater.inflate(R.layout.lay_news, container, false);
setText(v);
return v;
}
and
public void setText(View v){
TextView texts = (TextView)v.findViewById(R.id.textView);
texto.setText("hi");
}
I need a little bit help, defining my in event_filter.xml declared Views.
It is an child of an AbstractDetailListFragment and implements a DatePicker and a Spinner item.
But I dont know how to acces them in an AbstractDetailFragment.
By defining
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View theView = super.onCreateView(inflater, container, savedInstanceState);
ImageButton searchEnterButton = (ImageButton)getNavigationFragment().getNavigationBar().getRightButton();
View view = getView();
final DatePicker datePicker = (DatePicker) container.findViewById(R.id.datePickerEvent);
Spinner inSpinner = (Spinner) container.findViewById(R.id.category_list);
spinner = inSpinner;
downloadCategories();
the variables view, datePicker, inSpinner always are null!
Any Ideas?
thanks a lot.
That's a thing about fragments. I've been looking for the same error for days, until I read a little bit about fragments (i was lazy and i recommend you not to follow my footsteps ). The way i solved it was by overriding onViewCreated and "catching" views there:
public class MyFragment extends Fragment {
View rootView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.my_fragment, container,
false);
return rootView;
}
//and you use rootView to call findViewById
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
Button myButton = (Button) rootView.findViewById(R.id.mybutton);
sendFeedback.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//do something
}
});
}
}