declaration of Widgets. In or outside of onCreateView? - android

whats the diffrence between this two codes:
EditText mTitleField;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_crime, parent, false);
mTitleField = (EditText)v.findViewById(R.id.crime_title);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_crime, parent, false);
EditText mTitleField = (EditText)v.findViewById(R.id.crime_title);
}
The first one has Edittext variable declared outside the onCreateView, the second one has its declaration inside onCreateView.
Does it matter where do I declare it?

Yes it does matter.
For the first scenario, you can use mTitleField with other methods also (though you will have to instatiate it separately for other methods).
For the second scenario, you have bot declared and instantiated mTitleField inside onCreateView(), so it is accessible only inside that method.
This is a basic concept of Global and Local variables in Java.

Off course it does matter, I assume for first case mTitleField is declared globally in class level. In this case you can access mTitleField as EditText in any other method in that particular class.
Ex: Suppose on click of any button you need the text enter in that EditText then you can simply do like this
String someString = mTitleField.getText().toString();
In second case mTitleField is declared locally. In this case outside onCreateView(...) you can not access mTitleField. Scope of mTitleField is in onCreateView(...).
Ex: Suppose on click of any button you need the text enter in that EditText then you have to declare that EditText again inside onClick method like this
EditText mTitleField = (EditText)v.findViewById(R.id.crime_title);
String someString = mTitleField.getText().toString();

The Difference is that In First Method it declared globally so the advantage of that is you can use global variable anywhere in whole activity While for Second method it is used as a local variable that you can use for Particular place in an activity.
A local variable is defined within the scope of a block.
A global variable is a variable that can be accessed in multiple scopes.

Related

How do we initialize views created at runtime inside a LinearLayout from a Fragment?

I have a fragment with an empty LinearLayout. At some point a user will click an "Add" button that will trigger the appearance of another LinearLayout inside the first one:
// inside the onClick method...
case R.id.addPlayerButton: addItemsToLinearLayout(mContext, 1);
I have the inner LinearLayout on a different xml file and it contains several views. One of these views is a delete icon whose function is to delete the row, that is, delete the inner LinearLayout.
My problem is that I get a NullPointerException when I try to initialize the delete icon, which is an ImageView in the following way from the onCreateView of the fragment:
//class field private ImageView deleteRowIcon;
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_choose_players, container, false);
deleteRowIcon = view.findViewById(R.id.deleteRowIcon);
return view;
}
I've read the documentation on findViewById of the class View and it says that it returns null if it doesn't find any view with that id, but then, why am I able to even write view.findViewById(R.id.deleteRowIcon) without getting a warning telling me this is not possible? IntelliJ even gives it to me as an option to choose from!

How to prevent editText from auto filling text when fragment is restored from saved instance?

I have an activity which holds and shows multiple fragments.
When i re-enter the fragment it auto fills text in all the editTexts. The same text for all fields as well.
Example:
Open fragment and fill in text in the two editTexts:
CustomEditText1: [______]
CustomEditText2: [_acb__]
CustomEditText3: [_qwe__]
Click back button and re-enter the fragment
CustomEditText1: [_qwe__]
CustomEditText2: [_qwe__]
CustomEditText3: [_qwe__]
This is my overwritten methods in the fragment:
public AddBookingFragment() {
// Required empty public constructor
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
tabsActivity = (TabsActivity) getActivity();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_add_booking, container, false);
lastNameEditText = (NASEditText) view.findViewById(R.id.nas_add_booking_last_name);
pnrEditText = (NASEditText) view.findViewById(R.id.nas_add_booking_pnr);
addButton = (NASButton) view.findViewById(R.id.nas_add_booking_add_button);
scanButton = (NASButton) view.findViewById(R.id.nas_add_booking_scan_button);
confirmationBox = (LinearLayout) view.findViewById(R.id.nas_add_booking_confirmation_box);
confirmationText = (NASHeaderAndSubtext) view.findViewById(R.id.nas_add_booking_confirmation_text);
confirmationBox.setVisibility(View.GONE);
bindButtons();
FontHelper.setFont(container, tabsActivity);
return view;
}
By debugging I can see that the editText is setting the text by breakpointing inside the overrided OnTextChanged.
This is the stacktrace from that breakpoint:
(NASEditText is my custom view)
Two problems / questions:
How can I prevent the activity/fragment/editText from filling in the text in the fields when fragment is restored?
Why is it filling in the same text for all fields?
Found the problem with help from a friend!
SaveEnabled is default true on editTexts in Android.
The solution is simply to set:
setSaveEnabled(false);
on your editText.
Turns out Android isn't very smart in how it restores state for views with identical IDs in the same hierarchy (even in parent views with different IDs). I just turned this off because I save my state in a ViewModel object and restore it from my fragment's onCreateView().
This is not the answer, but it fixes the problem:
As commented by #Slugge:
Override the onSaveInstanceState method in your custom editText and clear the text / do what you want from there.

Android: preserving activity/fragment state

If I want to keep track of an int value in an activity/fragment, is this approach incorrect:
In layout XML, have:
<TextView
android:id="#+id/int_id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone" />
On fragment's onCreateView or activity's onCreate, have the following code:
TextView intId = (TextView)getView().findViewById(R.id.int_id);
intId.setText(String.valueOf(<integer_value_to_keep_track_of>));
Then, whenever I need to use the int value later in the code, access it by doing the following:
int accessId = Integer.valueOf(((TextView)getView().findViewById(R.id.detail_column_id)).getText().toString());
Something tells me this is not the best way to preserve state. Would declaring a class member (e.g. private int accessId) and assigning that be better? Thanks!
Usually, if you are inside onCreateView() you get a reference of the Views that are part of the Fragment's View hierarchy only once when you inflate the layout. When you call infalter.inflate() a View instance is returned; the parent of the hierarchy. You can use that View's findViewById() to get a reference of the TextView.
For example:
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle SavedInstanceState) { // TODO Auto-generated method stub
View view = (View) inflater.inflate(R.layout.me_layout, container,false);
TextView intId = (TextView)view.findViewById(R.id.int_id);
return view;
}
Then once you get the TextView reference you can simply do
String text = intId.getText().toString();
inside onCreateView();

why we access like that getActivity().findViewById()

When a layout , which is defined for a Fragment and used inside setContentView() method and it has no relation with Activity .
then why we need Activity Reference to access it .
so I want to create a ListView , inside a Fragment . than i have to create it inside Activity layout or inside Fragment layout .
Hey Neil , i have a question because every time I have made a mistake because , i am performing this
TextView txt = ( TextView ) getActivity().findViewById(R.id.txt);
txt.setText("nayak nahi , khalnayak hun mein");
inside oncreateView() so it is creating problem but when ever i am implementing this inside
onActivityCreated() , it is working , so can you please tell me Why this is happening .
if you want to find the view by getActivity(), you should do that after onCreateView is called, because till onCreateView is called the view of fragment is null. So you can do:
#Override
public void onResume() {
super.onResume();
TextView txt = ( TextView ) getActivity().findViewById(R.id.txt);
txt.setText("nayak nahi , khalnayak hun mein");
}
You can define a ListView in a layout for your Fragment. Try something like this in your fragment to define a alternative layout
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
_baseView = inflater.inflate(R.layout.yourlayout, null); //where base view is your upper most parent in your layout
return _baseView;
}
Then in your onActivityCreated you can use _baseView.findViewById('yourListView') to set your ListView. I don't know if this is best practice but it works perfectly for me.
In Fragment you should use its View but getActivity:
public View onCreateView(…){
View rootView = inflater.inflate(R.layout.listview_xml_file, container, false);
ListView ListNewsBelarus = (ListView) rootView.findViewById(R.id.listViewId);
return rootView;
}

Android: How to get a view given an activity inside a normal class?

I have a normal class (not an activity). Inside that class, I have a reference to an activity.
Now I want to access a view (to add a child) contained in the layout xml of that activity.
I don't know the name of the layout file of that activity. I only know the ID of the view, which I want to access (for example: R.id.my_view).
How can I do that?
Regarding the NullPointerException (which you should add to the question), always make sure you've called setContentView() in your Activity before trying to access a View defined in XML. Example usage:
public class MainActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
...
}
...
}
Then, somewhere,
ViewGroup group = (ViewGroup) context.findViewById(R.id.group); // In your example, R.id.my_view
The reason you need to have called setContentView() is that before it's called, your View(Group) doesn't exist. Because findViewById() is unable to find something that doesn't exist, it returns null.
As simple as that!
View view = activity.findViewById(R.id.my_view);
In case of the Layout:
LinearLayout layout = (LinearLayout) activity.findViewById(R.id.my_layoutId);
And to add the Views:
layout.addView(view);
You could make your method accept an Activity parameter and then use it to find the view by id.
Ex:
public class MyClass{
public void doSomething(Activity context){
TextView text=(TextView)context.findViewById(R.id.my_textview);
}
}
Then in your activity:
obj.doSomething(YourActivity.this);

Categories

Resources