TextView.setText() location confusion: onCreate() vs userMethod() - android

I'm curious about where setText() actually works. Here is a sample code for my question. I skipped irrelevant code with "..." ellipse.
// fragment_main.xml
<RelativeLayout ... >
<TextView
android:id="#+id/hello_world"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/hello_world" />
<Button
android:id="#+id/button_send"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/button_send"
android:onClick="userMethod" />
</RelativeLayout>
and
// ActivityMain.java
public class MainActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView textView = (TextView) findViewById(R.id.hello_world);
textView.setText("This cause runtime error!!");
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new PlaceholderFragment()).commit();
} // if
} // onCreate
/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends Fragment {
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// gives a compile error about non-static finViewById here
// TextView textView = (TextView) findViewById(R.id.hello_world);
// textView.setText("Compiling Error!!");
View rootView = inflater.inflate(R.layout.fragment_main, container,
false);
return rootView;
} // onCreateView
} // PlaceholderFragment
// user defined method
public void userMethod(View view) {
TextView textView = (TextView) findViewById(R.id.hello_world);
textView.setText("This run successful");
} // userMethod
} // class MainActivity
Here is what I don't understand:
textView.setText("string") fail when in protected void onCreate(...)
but
textView.setText("string") run when in public void userMethod(...)
yet
both these methods are in public class MainActivity extends ActionBarActivity
What is the difference??

TextView apparently is in fragment layout. You are trying to reach the textview before you inflate the fragment that's why you get null pointer exception.
Try to settext inside fragment onCreateView() method or after fragment inflate.
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// we inflate the fragment here.
View rootView = inflater.inflate(R.layout.fragment_main, container,
false);
// get the textview from inflated layout.
TextView textView = (TextView) rootView.findViewById(R.id.hello_world);
textView.setText("Should work");
return rootView;
}

Actually TextView is in your fragment_main.xml and You are calling setText before adding the fragment to the mainActivity and it will make a NullpointerException because of there is no textview in your activity_main.xml.

Related

How to Set Text to the text view in Fragment Activity programmatically?

I have a Fragment Activity i need to set Text to the text view in that Activity,when i am using following code getting null pointer exception.
can any other approach is there to set data for text view .
public class Introduction extends Fragment {
TextView txt;
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v= inflater.inflate(R.layout.activity_introduction, container, false);
txt=(TextView) v.findViewById(R.id.officeheader);
return v;
}
public void setText(String text){
txt.setText(text);
}
}
and in My Fragment Activity class :
frgManager=getSupportFragmentManager();
frgManager.beginTransaction()
. replace(R.id.fragmentoffice, introduction,"introduction")
.commit();
introduction.setText(" Office Coffee that will \n have everyone talking ");
set string in bundle
Bundle bundl = new Bundle();
bundl.putString("Text", text);
introduction.setArguments(bundl)
frgManager=getSupportFragmentManager();
frgManager.beginTransaction()
. replace(R.id.fragmentoffice, introduction,"introduction")
.commit();
get text from bundle
public class Introduction extends Fragment {
TextView txt;
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
String str = getArguments().getString("Text");
View v= inflater.inflate(R.layout.activity_introduction, container, false);
txt=(TextView) v.findViewById(R.id.officeheader);
setText(str);
return v;
}
public void setText(String text){
txt.setText(text);
}
}
you can write introduction constructor ,which contain a parameter Type String ,
and on the onCreateView ,you can initialize the textivew and settext

NullPointerException when calling findViewById in onCreate

Whenever I use findViewById in my Activity's onCreate I get a NullPointerException. For example:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new PlaceholderFragment()).commit();
}
TextView mTextView = (TextView) findViewById(R.id.textview);
}
I have read that the problem might by that the views may not be fully loaded when I try to find them and that is why I get a null pointer. If I call for findViewById in onCreateView of my Activity's fragment, everything works fine:
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container,
false);
TextView mTextView = (TextView) rootView.findViewById(R.id.textview);
}
However, I need to use mTextView outside this fragment class. I have seen many examples in Android's official documentation where findViewById is used in the Activity's onCreate. What am I doing wrong?
From the layout xmls, place your textview in the layout xml- activity_main so the activity's setContentView can find it there.
Currently the textview is in the layout xml fragment_main
fyi: fragment_main and activity_main are two different layouts. If your app structure doesn't demand the fragment then you don't need it at all.
you can try something like this -
class MainActivity extends Activity{
public TextView tv;
protected void onCreate(Bundle savedInstance){
......
}
public void doActionOnTextView()
{
//at this point you have the textview in tv
// do what you want to do with it
}
}
class MyFragment extends Fragment{
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container,
false);
TextView mTextView = (TextView) rootView.findViewById(R.id.textview);
mTextView.postRunnable(new Runnable(){
((MainActivity)getActivity()).tv=mTextView;
((MainActivity)getActivity()).doActionOnTextView();
}
}
Its not the best solution, but would work for you now.

Dynamically add elements to fragment

Hi I'm new to android and was trying to dynamically add content to a Fragment.
I've two Fragments inside an Activity. The first point to the second like this:
public static class PlaceholderFragment extends Fragment {
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_welcome,
container, false);
Button searchActivityBtn = (Button) rootView.findViewById(R.id.SearchActivityBtn);
searchActivityBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d("##SecondActivity", "search btn click");
getFragmentManager().beginTransaction()
.replace(R.id.welcome_fragment, new searchAnnouncementsFragment()).addToBackStack(null).commit();
}
});
return rootView;
}
}
the second Fragment class is
public static class searchAnnouncementsFragment extends Fragment {
public searchAnnouncementsFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_search,
container, false);
return rootView;
}
//public void onStart(){
// super.onStart();
// RelativeLayout root = (RelativeLayout) getActivity().findViewById(R.id.annunciContainer);
// Log.d("##onstart", "root:" + (root == null));
//}
}
As you can see i tried to do something in onStart method but I've always a bunch of errors, the R.id.annunciContainer is the id of the fragment_search.xml layout
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id ="#+id/annunciContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/white" >
What I'm trying to achieve is to dynamically add elements like other FrameLayout to my Fragment ( represented by the above RelativeLayout ).
Any thought?
You didn't mention the name of the activity, lets say the name as Activity1,
First create a linear layout or frame layout in the Activity1
Second add the following lines of code to your Activity1 for inflating PlaceholderFragment into your layout in Activity1
PlaceholderFragment pf = new PlaceholderFragment();
FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.annunciContainer, pf,"place_holder");
ft.commit();
For inflating searchAnnouncementsFragment replace PlaceholderFragment with searchAnnouncementsFragment.
What I was searching for are ListView

Access to view elements in fragments

I have an activity which receive data from other activity. This data has to be showed in a TextView in a fragment inflated in the activity. So, the code is:
public class DetailActivity extends Activity {
private int idEstablecimiento;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_detail);
if (savedInstanceState == null) {
getFragmentManager().beginTransaction()
.add(R.id.container, new PlaceholderFragment()).commit(); //Here the fragment is added to the activity
}
Bundle extras = getIntent().getExtras();
if (extras != null) {
idEstablecimiento = extras.getInt("idEstablecimiento");
}
TextView textView = (TextView) this.findViewById(R.id.nombreView); //Declared in fragmentDetail, which has been already inflated at this point, but still null
textView.setText(this.idEstablecimiento);
}
//...
//Non related stuff...
//...
public static class PlaceholderFragment extends Fragment {
private int idEstablecimiento;
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_detail,
container, false);
return rootView;
}
}
The problem is that the textView in the onCreate() method is null, why is this happening if the fragment has been already inflated? Shouldn't I be able to access to the IU elements once the fragment has been inflated in the onCreate() method? Or if not, what is the rigth way to do access to it?
You have to find the TextView in the Fragment.
public static class PlaceholderFragment extends Fragment {
private int idEstablecimiento;
public PlaceholderFragment() {
}
public PlaceholderFragment(int idEstablecimiento) {
this.idEstablecimiento = idEstablecimiento;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_detail,
container, false);
TextView text = rootView.findViewById(R.id.nombreView);
text.setText(idEstablecimiento);
return rootView;
}
And then you can get the text and commit it.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_detail);
Bundle extras = getIntent().getExtras();
if (extras != null) {
idEstablecimiento = extras.getInt("idEstablecimiento");
}
if (savedInstanceState == null) {
getFragmentManager().beginTransaction()
.add(R.id.container, new PlaceholderFragment(idEstablecimiento)).commit();
}
}
Regards
Nils
If you want to get the View from a fragment layout you should use the view inside the oncreateView of the fragment and then get the textView inside the oncreate view..
example:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_detail,
container, false);
TextView textView = (TextView) rootView.this.findViewById(R.id.nombreView); //Declared in fragmentDetail, which has been already inflated at this point, but still null
textView.setText("I am here");
return rootView;
}

Before onCreateView starts

In PageFragment; I inflate a layout in onCreateView. But I want to inflate this layout before onCreateView loads. It could be inflated one time / or for every fragment; not important.
How can I achieve it ?
public class PageFragment extends Fragment {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.page_quiz, container, false);
tv = (TextView) view.findViewById(R.id.Text);
LinearLayout ll = (LinearLayout) view.findViewById(R.id.questionList);
return view;
}
}
You just have to provide a layout as the return parameter in onCreateView(), that does not means you have to inflate it there. Layout can come from anywhere. You can Inflate the layout in onAttach() or in onCreate().
use getActivity() to get a LayoutInflater instance:
View layout = LayoutInflater.from(getActivity()).inflate(........);

Categories

Resources