EditText Values in Android Fragment do not refresh - android

I'm using the Viewpager to switch between 3 fragments, everything is working fine, except the refreshing of the second tab (or fragment). In this tab, I have a picture, some static Textviews, some dynamic TextViews and some EditText fields.
Everytime the second tab is selected, there will be called setText() on all dynamic fields. TextView components and the spinner are refreshing and updating their contents, but EditText elements do not.
I don’t understand why these fields are not updating. After tab change, I call notifiyDataSetChanged() in TabsAdapter. It calls onViewCreated() everytime I change the tab. In onViewCreated() of the second fragment I am changing the contents of the elements.
That’s the code of my fragment:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
hA = (HelloAndroidActivity)this.getSherlockActivity();
appState = ((TestApplication)this.getSherlockActivity().getApplicationContext());
final PersistenceHelper pH = new PersistenceHelper(appState);
m = pH.readMitarbeiter(toDisplay);
// Inflate the layout for this fragment
v = inflater.inflate(R.layout.detailfragment, container, false);
if(m==null) {
//If Mitarbeiter is empty
pH.closeDB();
return v;
}
//Inflating Elements
employeeName = (TextView)v.findViewById(R.id.employee_name);
cDate = (TextView)v.findViewById(R.id.department);
currentPlace = (TextView)v.findViewById(R.id.place_label);
comment_text = (EditText)v.findViewById(R.id.comment_text);
reachable = (EditText)v.findViewById(R.id.reachable_text);
state = (Spinner)v.findViewById(R.id.spinner_state);
durchwahl = (EditText)v.findViewById(R.id.durchwahl);
department = (EditText)v.findViewById(R.id.department_edit);
email = (EditText)v.findViewById(R.id.email_edit);
img = (ImageView)v.findViewById(R.id.userPic);
changeData = (Button)v.findViewById(R.id.changeButton);
//Setting Elements
employeeName.setText(m.getL_name());
currentPlace.setText(m.getStatus());
comment_text.setText(m.getBemerkung());
reachable.setText(m.getErreichbar());
email.setText(m.getS_name()+"");
durchwahl.setText(m.getDurchwahl()+"",TextView.BufferType.EDITABLE);
department.setText(m.getFunktion(),TextView.BufferType.NORMAL);
//Spinner
String[] values = { "Anwesend", "Mittagspause" , "Ausser Haus" , "Dienstreise", "Krankenstand" ,"Zeitausgleich", "Urlaub","Abwesend" };
ArrayAdapter spinnerArrayAdapter = new ArrayAdapter(this.getSherlockActivity(), android.R.layout.simple_spinner_item,values);
state.setAdapter(spinnerArrayAdapter);
state.setSelection(StateMapper.returnState(m.getStatus()));
//Image
//.......
return v;
}
As I mentioned before, my Image, TextView and Spinner Elements are refreshing their content. I also checked the content of all variables, everything seems to be fine, except these EditText elements. If I cast the EditText elements into TextView, the content is changing (in code but not in the GUI). What also makes me desperate is, that the EditText refreshes the first time I set the value.
Has anybody an idea, how I’m able to refresh the content of my EditText fields?

i am not sure but try onResume() and set your text in resume state.
or try
Intent.FLAG_ACTIVITY_CLEAR_TOP on tab change.

You could also try posting a runnable to the message queue so that the EditText's are updated after rendering (in MonoDroid/C#, see How to run a Runnable thread in Android? for java):
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle bundle)
{
EditText et = FindViewById<EditText>(...);
et.Post(() => { et.Text = "content"; });
}
Also, if you have a TextChanged event handler (say for displaying a save icon/button when the text is changed), post it in the runnable as well, and do it after the et.Text assignment. Otherwise, the TextChanged event will fire when the initial et.Text content is assigned, causing the TextChanged event to fire (ie, and the save button showing) when the USER hasn't changed anything:
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle bundle)
{
EditText et = FindViewById<EditText>(...);
et.Post(() =>
{
et.Text = "content";
et.TextChanged += TextChangedHandler;
});
}
private void TextChangedHandler(object o, EventArgs args)
{
ShowSaveButton();
}

I came across this issue in 2021. I just had to call findViewById again right before setting the text.
myEditText = (EditText)view.findViewById(R.id.myEditText);
myEditText.setText(String.valueOf(newValue));

Related

Give a certain EditText focus

I'm using 2 EditText next to each other, the left one gains focus on the fragment startup, I want to give the right one focus I've tried to call requestFocus() on the right EditText but it's not working
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.sandwich_fragment,container, false);
sandwichNameEditText = view.findViewById(R.id.sandwich_name_edit_text);
sandwichPriceEditText = view.findViewById(R.id.sandwich_price_edit_text);
insertSandwichImageView = view.findViewById(R.id.insert_sandwich_btn);
sandwichListView = view.findViewById(R.id.sandwich_list);
dbHandler = new DBHandler(getContext(),null);
sandwichArrayList = dbHandler.getSandwiches();
final SandwichListAdapter adpater = new SandwichListAdapter(getContext(),
R.layout.sandwich_item, sandwichArrayList);
sandwichListView.setAdapter(adpater);
insertSandwichImageView.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
if(sandwichNameEditText.getText().toString().equals("") || sandwichPriceEditText.getText().toString().equals("")){
Toast.makeText(getContext(),"No empty strings.", Toast.LENGTH_SHORT).show();
return;
}
Sandwich sandwich = new Sandwich(sandwichNameEditText.getText().toString(),
Double.parseDouble(sandwichPriceEditText.getText().toString()));
dbHandler.addSandwich(sandwich);
adpater.add(sandwich);
sandwichNameEditText.setText("");
sandwichPriceEditText.setText("");
sandwichNameEditText.requestFocus(); // working here
}
});
sandwichNameEditText.requestFocus(); // not working here
return view;
Try to call requestFocus in the onViewCreated method.
The request for focus is something you should do once your View is created.
You can find some insights about the difference between onCreateView and onViewCreated methods for a Fragment here.
That said, you should move your view elements initialisations in the onViewCreated as well, since they're something you want to do after the view is created and not while it's being created. Just leave the inflate logic there, and do the other logic once the View is there.

Xamarin FindViewById NullReference Exception

I have a problem, whenever i try to add an eventhandler to a button i get a null reference exception, i am trying to create a popup window with a DialogFragment, where inside it im calling the view PopUpWindow wich will show up on screen, but when i try to access the buttons by id and to assign them eventhandlers for example:
Button btnCopyText = dp.view.FindViewById<Button>(Resource.Id.btnCopyText);
btnCopyText.Click += BtnCopyText_Click;
then i get a null reference exception, can anyone help me, below is the necessary code.
class dialog_Popup:DialogFragment
{
public View view;
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
base.OnCreateView(inflater, container, savedInstanceState);
view = inflater.Inflate(Resource.Layout.PopupWindow, container, false);
return view;
}
public override void OnActivityCreated(Bundle savedInstanceState)
{
Dialog.Window.RequestFeature(WindowFeatures.NoTitle);
base.OnActivityCreated(savedInstanceState);
}
public class MainActivity : Activity
{
protected override void OnCreate(Bundle bundle)
{
//some code
}
public string itemclicked;
dialog_Popup dp;
private void Lv_ItemLongClick(object sender, AdapterView.ItemLongClickEventArgs e)
{
//View popUpView = LayoutInflater.Inflate(Resource.Layout.PopupWindow,
//null); // inflating popup layout
Button height = FindViewById<Button>(Resource.Id.btnCopyText);
//Then: change the width of the button
FragmentTransaction transaction = FragmentManager.BeginTransaction();
dp = new dialog_Popup();
dp.Show(transaction,"Popup");
itemclicked = lv.GetItemAtPosition(e.Position).ToString();
Button btnCopyText = dp.view.FindViewById<Button>(Resource.Id.btnCopyText);
btnCopyText.Click += BtnCopyText_Click;
Button btnSaveCurrentAya = dp.view.FindViewById<Button>(Resource.Id.btnSaveCurrentAya);
btnSaveCurrentAya.Click += BtnSaveCurrentAya_Click;
Button btnsavingsAya = dp.view.FindViewById<Button>(Resource.Id.savingsAya);
btnsavingsAya.Click += BtnsavingsAya_Click;*
Button btnShareFB = dp.view.FindViewById<Button>(Resource.Id.fbShare);
btnShareFB.Click += BtnShareFB_Click;
}
}
There are several reasons why a NullReferenceException can occur with FindViewById:
The layout does not contain the id -> check that the correct layout and id is inflated/ referenced
The type like Button is incorrect
In your case, check that dp and dp.view is not null.
One thing to mention here is, that it is not the best implementation to reference the control of a fragment in you main view. A fragment is something that should be able to life on her own. So I see two ways of implementing your desired behavior:
1) The fragment gets an event and you listen to that. This means your main view will contain the logic to save something.
2) The logic moves into the fragment.

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.

TextView forgets its value after tab switching

I've setup a tabhHost in my program with 3 tabs each with a fragment in its content that contains a textView. I've set a button in app that is supposed to update the content of every tab. However the problem i am now facing is that if i change a tab its content gets forgotten and new tab has no value aswell unless i click the button again. Each tab content has a different class but in each of them the class just returns the view with textview in it. I assumed that the values reset on each view inflate however i cannot find a reasonable way to make it work as i intend to it.
Here is the part of the code with the method ran by my button:
public void getNum(View view) {
proteinNeeded = weightNum.getValue() * FirstActivity.weightMultiplier;
carbohydrateNeeded = weightNum.getValue() * 5;
switch (weightMultiplier) {
case 2: {
resultTxt = String.format("Zapotrzebowanie:%nBiałko - %dg.%nWęglowodany - %dg.%n",
FirstActivity.proteinNeeded, FirstActivity.carbohydrateNeeded);
FragmentTab.tv.setText(resultTxt);
FragmentTab2.dietTxt = String.format("text1");
FragmentTab2.tv.setText(FragmentTab2.dietTxt);
FragmentTab3.foodTxt = String.format("text2");
FragmentTab3.tv.setText(FragmentTab3.foodTxt);....
And here is the code from FragmentTab.java, each tab has more or less same code so i'll post only this one for now:
public class FragmentTab extends Fragment {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
public static View v;
public static TextView tv;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
v = inflater.inflate(R.layout.fragment_layout, container, false);
tv = (TextView) v.findViewById(R.id.textResult);
if (tv != null) {
tv.setText("nothing has been input yet");
}
return v;
}
}
TL;DR - How do I save my values in textView in such a way that if my text gets updated it won't revert to default values after the view gets refreshed?
An option to solve your problem is to use SQLite Database to save your data, and fetch it from database whenever you return to that tab.
You can refer to this link. Saving Data in SQL Databases.
For other android storage options, refer to this series of videos. Android Data Storage Options.

Change a TextView Visibility in Fragment

I have a some fragment in my PageViewer.
In the main fragment, I would like to show a component ( TextView or imageView) if there is no connection.
In the code below, I can reach my textview, but I cannot get them disapperead.
public class MainFragment extends Fragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View layout = inflater.inflate(R.layout.main, container, false);
// RelativeLayout mainLayout = (RelativeLayout)findViewById(R.layout.main);
TextView TxtIsNotConnected = (TextView) layout.findViewById(R.id.isNotConnected);
TextView TxtIsConnected = (TextView) layout.findViewById(R.id.isConnected);
// String text = TxtIsNotConnected.getText().toString(); // This is a test which works, return the text o my textview.
boolean isConnected = ConnectivityUtils.isConnected(getActivity()); // This Works fine
if (!isConnected) TxtIsNotConnected.setVisibility(View.VISIBLE); // NOT WORKING
else TxtIsConnected.setVisibility(View.VISIBLE); // NOT WORKING
return inflater.inflate(R.layout.main, container, false);
}
How should I do???
To make your TextView visible
yourTextView.setVisibility(View.VISIBLE);
To make Invisible
yourTextView.setVisibility(View.GONE);
From your code it seems that you have to keep one view visible and another invisible. So, please try this
if (!isConnected) {
TxtIsNotConnected.setVisibility(View.VISIBLE);
TxtIsConnected.setVisibility(View.GONE);
} else {
TxtIsConnected.setVisibility(View.VISIBLE);
TxtIsNotConnected.setVisibility(View.GONE);
}
Hope it helps...
Edit :
Well, your code is correct about visibility but you have made a silly mistake that's why it seems that your code is not working. Look at the first line and last line of your onCreateView method. You have inflated your R.layout.main in View object called "layout". You have set your actions within that layout. Finally you have returned a new instance of that view. So, your previous codes became useless. So, your return statement will be...
return layout ;
It should fix the problem.

Categories

Resources