I am doing an android project which uses a Tabhost to link to 3 fragments and need some communication between them. Each tab will include another xml file. I linked different element in different sml file to the .java file. But it doesn't seem to work. Here is the code:
In Main.xml
<TabHost>
<LinearLayout>
<include
android:id="#+id/fragmentreview"
layout="#layout/fragentreview"/>
</LinearLayout>`
In fragentreview.xml
<LinearLayout>
<TextView
android:id="#+id/textViewinfragR"
android:text="Text in new xml reviews" />
</LinearLayout>`
In fragment.class
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragentreview, container, false);
txtMsgR = (TextView)rootView.findViewById(R.id.textViewinfragR);
txtMsgR.setText("Main Car integer = ");
return rootView;
}
When I launch the app textViewinfragR it should show Main Car integer = but it is still showing Text in new xml reviews. Is there a problem in my code?
You are setting the text in the wrong place. Try setting it in onActivityCreated
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
txtMsgR = (TextView) view.findViewById(R.id.textViewinfragR);
txtMsgR.setText("Main Car integer = ");
}
This should work. The onViewCreated method is called after the inflation is completed.
onCreateView -> onViewCreated -> onActivityCreated
Related
am trying to make the text under my login button "no account yet? signup now" when clicked to send me to my RegisterFragment.so i added an OnClickListener for it like this in my LoginFragment.
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
TextView signup = (TextView) getView().findViewById(R.id.signup);
signup.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
LoginFragment.this.startActivity(new Intent(getActivity(), RegisterFragment.class));
}
});
but when i run the code the app crashes on this line
TextView signup = (TextView) getView().findViewById(R.id.signup);
this is my fragment_login.xml file
<TextView android:id="#+id/signup"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="24dp"
android:text="No Account Yet? Signup_now"
android:gravity="center"
android:textSize="16dp"
android:clickable="true"/>
please guys i really need your help.
onCreateView() method is responsible for creating view, so you should first create it.
You can't directly use getView() inside onCreateView().
You need to inflate it first like
View view = inflater.inflate(R.layout.my_layout, container, false);
Then use
TextView signup = (TextView) view.findViewById(R.id.signup);
So full code should look like this
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.my_layout, container, false);
TextView signup = (TextView) view.findViewById(R.id.signup);
signup.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
return view;
}
On side note, setting up click listener initializing TextView's etc should be done inside onViewCreated(). onCreateView() should just create & return the view.
like
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
TextView signup = (TextView) view.findViewById(R.id.signup);
// and so on...
}
I would recommend not setting a click listener into something you want to type into
You can't call getView before onCreateView has actually returned a proper View
findViewById in Fragment
RegisterFragment.class is not an Activity, you cannot startActivity for it.
Use the FragmentManager
getSupportFragmentManager().beginTransaction()
.replace(R.id.<someContainer>, RegisterFragment.class)
.commit();
Or you can see the documentation on Communication between Fragments to see how you might implement on onLogin() or onRegistrationSelected() action to swap out to the registration fragment or "post-login" main fragment.
I want to set text of a TextView that is inside a layout file,
I tried setContentView() but it isnt working since i am using fragments.
I tried using getResources().getLayout(R.layout.abc);
It returns null
I tried setContentView() but it isnt working since i am using
fragments
That's wrong. You have to override onCreateView and inflate and return the layout you want to show, and you can use onCreateView, and use its first parameter, View view, to call findViewById and access the widgets in your layout. You can read more here and here
inside fragment you can set view inside function onCreateView(), use below code
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle b) {
View view = (LinearLayout) inflater.inflate(R.layout.my_layout, container, false);
return view;
}
here my_layout should be the name of layout file,
now you can get view of it inside function onviewcreated()
public void onViewCreated(View view, Bundle savedInstanceState){
// here you can get your textview and set its value
}
thumbs up, if you find my answer correct
You can inflate your layout like this:
ViewGroup group = LayouInflate.from(context).inflate(R.layout.abc,null);
TextView tv = group.findViewById(R.id.xxx);
you have to inflate the layout through the onCreateView method and then return the View.
#Override
public View onCreateView(LayoutInflater inflater,ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.your_layout, container, false);
TextView yourTextView = (TextView)rootView.findViewById(R.id.yourTextViewId);
return rootView;
}
I have a simple fragment with 2 TextView objects. The fragment has the corresponding Java class. How do I pass values from the activity layout XML to the fragment? I want to instantiate the same fragment multiple times with the TextView objects having different values.
So, the activity XML would be something like:
*
Thank you.
Everybody seems to ignore it but you can actually pass static arguments like a label through XML.
It's a bit complicated. First you need to declare the custom attributes you want to use in a file like attrs.xml, then you need to override Fragment.onInflate() to retrieve the value of these attributes.
The official Android documentation provides a simple example on how to retrieve a label from the XML layout to use it in a Fragment.
I guess that you are expecting some way of data binding in xml (for example like in wpf).
There is no data binding like that in android (at least not without third party libraries).
What you do have is your onCreateView () method of fragment.
There you catch reference to those TextView objects, like this:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment, container,
false);
TextView myTextView1 = (TextView)view.findViewById ("textView1");
TextView myTextView2 = (TextView)view.findViewById ("textView2");
return view;
}
There you can also set value of those textViews, or you can set it latter in code like this:
myTextView1.setText ("this is my textview1 test");
So, to conclude - there is no typical inside xml data binding in android, you have to find those views in fragment code and then manipulate with them.
EDIT:
if you have data somewhere in activity, and you want to pass it to your fragment when you create it, you can use fragment setArgument() function (and corresponding getArguments() ).
You have example here: Setting Fragment arguments from Activity - in the accepted answer.
EDIT 2:
According to new Data Binding Library it's possible to do binding like this:
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable name="user" type="com.example.User"/>
</data>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#{user.firstName}"/>
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#{user.lastName}"/>
</LinearLayout>
</layout>
link: https://developer.android.com/tools/data-binding/guide.html
But note that it's still beta release.
It seems like you are going about using fragment wrong.
But nonetheless you can just use textview.setText in each fragments java class...
you want to pass data to the fragment and let the fragment use it. The following article describes the whole 9 yard:
http://developer.android.com/training/basics/fragments/communicating.html
In short:
sender to setArguments:
Bundle args = new Bundle();
args.putString("myText", aText);
f.setArguments(args);
the receiving Fragment to retrieve argument:
String text = getArguments().getInt("myText"); // myTextView.setText(...)
The following is an example of a Fragment. Notice the way you interact with the TextView. You just have to create as many fragments as you want and put them into an ArrayList so that you will be able to get information from all fragments.
public class Yourfragment extends Fragment {
private TextView mTextView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.your_fragment, container, false);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
View _view = getView();
if(_view != null){
mTextView = (EditText) _view.findViewById(R.id.your_textView);
}
}
}
To answer your question,
you need to have a mainclass extending Activity class from which you will instantiate the fragmnet. And you need a fragment class with those two TextView objects ad the class variables with a parameterized constructor . So you need to maintain a Map which has key as the name of your fragment and textviewvalue1"+"textviewvalue2. So now while creating an instance of a fragment, you can send the value yiu have in the map as parameters to that fragment constructor.
Like this:
public class Yourfragment extends Fragment {
private TextView mTextView1;
private TextView mTextView2;
public Yourfragment(String txt1,String txt2){
super();
this.mTextView1.setText(txt1);
this.mTextView2.setText(txt2);
}
#Override public View
onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
//ur logic
}
#Override public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
//ur logic
}
} }
And in the place where you instantiate, use map.get( fragmentname).split("+")[0] and map.get( fragmentname).split("+")[1] as parameters to conatructor and set the title of fragment to fragmentname
I am new in Android programming.
I created the main Activity of my app style google shop ussing ActionBarSherlock and a NavigationTabs, with fragments, each referencing another activity (Fragment 1 Fragment 2, etc) and each fragment inflating a layout.
However, I'm used to create layouts in xml and then customize them in java. To put a different text depending on the time of day, or according to some data in a database, giving function to buttons, etc.. But in a Fragment Class, I can not even use setContentView to work with each text or button, and set the context for using my database is giving me problems.
How I can customize a xml layout in a fragment?
Or what would be the right thing to do?
Here my Fragment:
public class Fragment1 extends SherlockFragment{
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
return inflater.inflate(R.layout.menu, container, false);
}
This is more simple then you think. onCreateView instanciate au returns the view for your Fragment. As you said, in a simple Activity you set (and instanciate) the view with setContentView() and then you get your Views with findViewById().
findViewById() asks for the view to return the view item that you want, you can call it from your view before returning it. Like this:
public class Fragment1 extends SherlockFragment{
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
View v = inflater.inflate(R.layout.menu, container, false);
// For example, getting a TextView
TextView tv = (TextView) v.findViewById(R.id.myTextView);
// do your job
return v;
}
so far so good, you just need to use the view you are inflating to get everything.
here is an example
View v = inflater.inflate(R.layout.menu, container, false);
Button b = (Button)v.findViewById(r.id.button1);
return v;
inside onActivityCreated you could use:
View mView = getView();
TextView textView = (TextView) view.findViewById(R.id.theIdOfTextView);
where theIdOfTextView is declared inside R.layout.menu.
getView() returns the View you inflated inside onCreateView. You use it only after onCreateView has been executed
I am working through the Big Nerd Ranch guide for android programming, and I am at the challenge for Chapter 16. The challenge is to make an EmptyView for a ListView, and then make a button on the EmptyView that adds stuff. I got the EmptyView to work but I can't figure out where I should make my button. Here is my code.
public View onCreateView(LayoutInflater inflater, ViewGroup parent,
Bundle savedInstanceState) {
View v= super.onCreateView(inflater, parent, savedInstanceState);
inflater.inflate(R.layout.list_frame_layout, parent);
return v;
}
and here is my XML.
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ListView
android:id="#android:id/list"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
</ListView>
<LinearLayout android:id="#android:id/empty"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="24dp"
android:text="#string/empty_no_crime" />
<Button
android:id="#+id/empty_new_crime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/empty_new_crime">
</Button>
</LinearLayout>
</FrameLayout>
The book is telling us to use fragments, hence the inflate. I figure the code should be
mNewCrime=(Button)getView().findViewById(R.id.empty_new_crime)
but that isn't working. Any ideas?
Edit*: Hmmm, apparently this also really isn't working that well. When I do add stuff, the EmptyView does not go away, it just gets pushed down while items are listed. Any ideas on how to make the EmptyView go away as soon as I add things?
I had trouble with this challenge at first as well. I over thought it! You have probably solved this issue by now but I thought it would be useful to post an answer for others. The following worked for me:
Create a new XML file specifying the "empty" and "list" views as you have done already.
Modify your existing onCreateView method to inflate the new modified layout which contains the "empty" and "list" views you have defined in your XML.
Create a new button and setup the onClickListener for the button.
Here is the code:
#TargetApi(11)
#Override
// We override the onCreateView to set the subtitle by default if we are rocking >3.0
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState)
{
super.onCreateView(inflater, parent, savedInstanceState);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB){
if(mSubtitleVisible){
getActivity().getActionBar().setSubtitle(R.string.subtitle);
}// End inner if
}// End if
View v = inflater.inflate(R.layout.empty_layout, parent, false);
mNewCrimeButton = (Button)v.findViewById(R.id.add_crime);
//Define an click event listener for the button and launch the new crime fragment when clicked
mNewCrimeButton.setOnClickListener(new View.OnClickListener(){
public void onClick(View v){
Crime crime = new Crime();
//Get the crimelab from the activity and add the crime
CrimeLab.get(getActivity()).addCrime(crime); //getActivity returns the activity this fragment is attached to
Intent i = new Intent(getActivity(), CrimePagerActivity.class);
startActivityForResult(i,0);
}//End onClick
});
return v;
}// End onCreateView
This should work with your existing xml layout. I hope this helps.
I too struggled initially with this, essentially solving it the same way the above poster did. However my problem was a bit different. I was getting bombed out of the application on startup, because my code that set up the onClick listener looked like this:
Button mCrimeButton = (Button)v.findViewById(R.id.crime_button);
mCrimeButton.setOnClickListener(new View.OnClickListener(){
public void onClick(View v) {
initiateCrimeRecord();
}
});
It wasn't until I moved the declaration of mCrimeButton up to the class level making it an instance variable of the class that I was able to successfully execute the app:
public class CrimeListFragment extends ListFragment {
private static final String TAG = "CrimeListFragment";
private ArrayList<Crime> mCrimes;
private boolean mSubtitleVisible;
private Button mCrimeButton;
*
*
*
#TargetApi(11)
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_empty_crime_list, parent, false);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
if ( mSubtitleVisible) {
getActivity().getActionBar().setSubtitle(R.string.subtitle);
} else {
getActivity().getActionBar().setSubtitle(null);
}
}
// Set the button up on the empty view
mCrimeButton = (Button)v.findViewById(R.id.crime_button);
mCrimeButton.setOnClickListener(new View.OnClickListener(){
public void onClick(View v) {
initiateCrimeRecord();
}
});
return v;
}
I then went back and noticed that in all the other examples in the book, the widgets that get manipulated are declared as private instances of the class. Why is this? Android doesn't allow you to just get a local instance to attach the listener?