NullPointerException when calling setText on a TextView outside activity_main.xml - android

I am making an app using two tabs with different layouts, which means I have three total layouts at the moment:
activity_main,
fragment_receive,
fragment_send
In my onCreate method in my main activity, the following line sets my content view to activity_main. (If anyone could explain why this layout appears to be blank and yet my app still shows both tabs, that would be great.)
setContentView(R.layout.activity_main);
Then I use the findViewById method to set a TextView to a view that appears in both fragment_receive.xml and fragment_send.xml.
currentExchangeRate = (TextView) findViewById(R.id.exchangeRateView);
Then I attempt to use the setText method on this TextView.
currentExchangeRate.setText(Double.toString(lastPrice));
This line gives me the NullPointerException.
Can anyone explain this to me?

findViewById() called from the Activity, looks for the id in the hierarchy of views of the Activity.
if you want to perform that on the Fragment hierarchy, you have to call it from the Fragment view, for example view.findByById() from the Fragment onCreateView, after you inflated the layout.

When you call:
currentExchangeRate = (TextView) findViewById(R.id.exchangeRateView);
The compiler finds that the static int ID does exist within your R.id because you declared them in your fragments, and therefore doesn't throw a compiler error. But at runtime, the current view layout (the one you set with setContentView(R.layout.activity_main);) doesn't hold that ID and therefore returns null.
To access your textview that exists within your Fragment from the Controlling Activity, you use the Fragment Manager (add an id property to your fragments in activity xml, or set tags when you declare your Fragments in your code):
ReceiveFragment receiveFragment = (ReceiveFragment) getSupportFragmentManager().findFragmentById(R.id.receive_fragment);
TextView tv = (TextView) receiveFragment.getView().findViewById(R.id.exchangeRateView);
tv.setText(Double.toString(lastPrice));

findViewById retrieves the view with the requested id from your activity's layout
To get your fragment's textview, make the view that your fragments onCreateView is returning a static variable and initialize it in the onCreateView.
Then you can retrieve the textview like this:
TextView textview = (TextView) YourFragmentTitle.yourFragmentViewTitle.findViewById(R.id.yourId);

Related

findViewById from specific layout seems not linked

Good evening
I am trying to make users can change font in other layout called row.XML from the main activity class everything seems okay but there's no change of the font or color it seems like look not linking
Any idea guys
Edit:
I used include method row.XML in main XML but all in vain
LayoutInflater inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view;
/* We inflate the xml which gives us a view */
view = inflater.inflate(R.layout.row, null);
/* Get the widget with id name which is defined in the xml of the row */
textfont = (TextView) view.findViewById(R.id.textItemmain);
(https://i.stack.imgur.com/GN6UQ.png)
That is not how views work, views are not explicitly bound to an activity so all you are doing by inflating that view is inflating a view that isn't associated to anything.
To send data back to an activity you need to use startActivityForResult then listen for data coming back to it when the activity is resumed
First of all you need to know that you can't change the views properties of another layout activity directly from your current activity it is not possible, what you can do is that before going to the next activity you can pass an intent with a Boolean flag that will be check in the targeted activity to see if a boolean condition is true or false if it is true change the font of textview in target activity if it is false dont do anything, This is the only way to achieve what you are trying to do. If you can't create an intent and pass boolean extra in it post in comments I'll update the answer.

TextViews not saving values when changing fragments

I have an activity with a number of fragments. In all fragments, I get the views in onViewCreated, like this:
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
tv1 = (TextView)view.findViewById(R.id.tv1);
tv2 = (TextView)view.findViewById(R.id.tv2);
tv3 = (TextView)view.findViewById(R.id.tv3);
}
I'm not storing the textview's text in the state. One fragment extends ListFragment and I change the adapter's items and refresh the listview.
When I go back to previous fragments (I use popBackStack() because I need to use a Back button (app runs in kiosk mode), text in some fragments is lost while in others (and the listview) the changes done stay there.
I'm using replace to replace the current fragment in the frame.
EDIT
The values that are being lost are of TextViews and ImageButtons (image resource). The text in EditText views are not lost.
Why is this happening in just some fragments and how can I solve this data loss?
You have to use
android:freezesText="true"
In your layout textviews whose text you want to be preserved.
I hope it helps.
Let me see if I understand your situation:
You are showing an instance of Fragment1 which contains your TextView.
You replace your instance of Fragment1 on the screen with an instance of Fragment2.
You return to Fragment1, but when you do, the text in the TextView has been lost.
I have seen situations where this occurs because the instance of Fragment1 that contained the original TextView is not the same instance of Fragment1 that is shown the second time. If you are showing two different instances of Fragment1, the second instance will not display the text that the first instance contained in its own text view.
So take a look at the code that is managing your fragment transactions. Are you creating new instances of your fragments before showing them? If so, you'll have to keep references to the fragments that you want to retain instead of recreating them every time.
Another thing to look at would be how the TextView is being populated. Maybe the actual data is being lost somewhere.
Use Instance variables to store data inside each Fragment, if you are using replace E.g.:
String value = "";
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
tv1 = (TextView)view.findViewById(R.id.tv1);
tv1.setText(value);
}
Note: Update value variable as well whenever textview data is being updated.

How the view are refereed under MainActivity In android

Here is the XML code for a simple TextView:
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/hello"
android:id="#+id/test"/>
Then, in MainActivity, it is used like this:
TextView test = (TextView) findViewById(R.id.test);
test.setText("test");
I want to know how the view is accessed in Main class, which is defined in xml layout.
Can anyone explain how it happens?
how the view accessed in Main class
To be honest, i dont know the process in detail. Let me help you on what i know :
The Activity will search the layout XML in setContentView method.
After the layout has been found, we can use findViewById to link the instance (test - in your case) we created to the layout XML.
If the ID is found, the instance (Java) and XML will be linked.
Of course, you can do something like :
TextView test2 = new TextView(this);
Which means the instance is not must exist in XML.
Sorry English is not my native language.
On your Activity, you have:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
//...
}
According to Android documentation, setContentView is responsible for linking your XML layout to your Activity:
Set the activity content to an explicit view. This view is placed
directly into the activity's view hierarchy. It can itself be a
complex view hierarchy.
After the Activity's content view is set, you can use findViewById in order to access the views of the XML linked to your Activity:
Finds a view that was identified by the id attribute from the XML that
was processed in onCreate(Bundle).
Hope it helps you to understand this process! :)
I think this is the method
1.when you create or declare a text view or something like that a reference is generated in your R file(JAVA file).
2.which is what you access through
R.id.test
this is how your linking works

How to access the ids of Different layout associated with different activity from another Activity and how to perfoem a onClick on it

i have different fragments in my application and they have different layout ,so i want to access the layout ids from a different activity for ex button,textview .
i have a fragment called MyFragment and it has a layout file frag.xml and a MainActivity with layout main.xml.in frag.xml i have
<Button
android:id="#+id/myButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
i want to access the id of Button of farg.xml in MainActivity
like Button button=(Button)findViewById(R.id.myButton);so how can i access it if i will acess like this it will throw a NullPointerException.also i want to perform the onClick() event for that button in MainActivity.
R.id.myButton is how you refer to the id of the button. However, the button is only available in the view hierarchy of frag.xml. So, findViewById(R.id.myButton) should return null if the button does not exist in the view hierarchy of the context under which you called findViewById(R.id.myButton).
To access the button in the fragment from your main activity, you must write a method that the main activity can call on the fragment and then have the fragment do the work of accessing/modifying the button and returning whatever information you need to the main activity.
you can find the id of the button by
buttonid = getResources().getIdentifier(myButton , "Button", getPackageName());
The first parameter is the name from the XML after the #+id, the second is the type, the third is your package name.
Find main Layout of each fragment and store them in static array in a class.You can find your view in each fragment and store it in static field of a class(perhaps another class):
class Store{
public static view;
}
In fragment:
Stroe.view = (Button)findViewById(R.id.myButton);
In Activity:
Button btn = Store.view;

Setting global Button and EditText objects

I'm getting null pointer exceptions when I try to initialize Button and EditText objects in global scope, can't figure it out. I've commented out everything but the bare minimum for the app to display my layout, but this still causes a crash:
private EditText addmoney = (EditText)findViewById(R.id.addmoney);
R.id.addmoney definitely, definitely exists. So what the heck? Is it impossible to declare EditText in global scope? I need to be able to call it from both onCreate and onPause in a class extending Activity, is there maybe another way I should be doing this?
EDIT:
I tried using shade's method of inflating the layout first but it causes errors, apparently your not allowed to use system services before onCreate() has been called and inflating a view requires one.
You have to execute findViewById only after you have set the content for your current activity.
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.home);
addmoney = (EditText)findViewById(R.id.addmoney);//it knows in which file to search for the id
}
Alternatively, you could do something like this:
private View dummy = (View) View.inflate(this, R.layout.dummy, null);
private EditText addmoney = (EditText) dummy.findViewById(R.id.addmoney);
... and in the onCreate (or wherever else):
setContentView (dummy);
Since you already have the parent of the EditText view instantiated, you can reference it without having a NPE.
NOTE: The first parameter of inflate is a Context. Therefore, you need a Context that is alive for this to work.
Ooops, wrong class :D

Categories

Resources