I have been through a lot of posts here about starting an activity from a fragment, although none of them seem to be solving my problem. As i say, i am trying to start an activity from a class that extends a fragment. At the minute, when i remove the "android:onClick" from the xml, the button simply becomes dead and it does not let me click it. However when i put in the OnClick method to the xml i receive the following error:
java.lang.IllegalStateException: Could not find method onClick(View) in a parent or ancestor Context for android:onClick attribute defined on view class android.support.v7.widget.AppCompatButton with id 'buttonViewDetails'
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.resolveMethod(AppCompatViewInflater.java:327)
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:284)
at android.view.View.performClick(View.java:5653)
at android.view.View$PerformClick.run(View.java:22509)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6144)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
I am not quite sure what this means. Here is the code that i have tried:
Button XML inside the class extending fragment:
<Button
android:id="#+id/buttonViewDetails"
android:layout_width="60dp"
android:layout_height="60dp"
android:background="#mipmap/info"
android:layout_marginLeft="250dp"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"
android:layout_marginEnd="14dp"
android:layout_marginBottom="14dp" />
Java Code for the class that extends fragment:
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View myInflatedView = inflater.inflate(R.layout.line_details, container, false);
Bundle extras = getArguments();
if (extras != null) {
String linetype = extras.getString("LineType");
TextView LT = (TextView) getActivity().findViewById(R.id.textViewLineType);
LT.setText(linetype);
Button InfoButton = (Button) getActivity().findViewById(R.id.buttonViewDetails);
InfoButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(getActivity(), VerifyLine.class);
startActivity(intent);
}
});
}
return myInflatedView;
}
Would anyone be able to help me out?
Thanks!
You are inflating a view myInflatedView and doing findViewById of that view using activity reference.So ust change that getActivity and use myInflatedView to find the Views.Also remove onClick for the button from xml.
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View myInflatedView = inflater.inflate(R.layout.line_details, container, false);
TextView LT = (TextView) myInflatedView.findViewById(R.id.textViewLineType);
Button InfoButton = (Button) myInflatedView.findViewById(R.id.buttonViewDetails);
InfoButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(getActivity(), VerifyLine.class);
startActivity(intent);
}
});
Bundle extras = getArguments();
if (extras != null) {
String linetype = extras.getString("LineType");
LT.setText(linetype);
}
return myInflatedView;
}
Related
I have "home_fragment.java" class file in my project
which i need to be launched when the app starts.
but i am only able to add 'activities' as launch default,not fragments.
please help me to add a 'fragment' as a launch activity.
i am new to android ,thank you.
this is my home_fragment.java
public class home_fragment extends Fragment {
View myView;
Button more;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
View myview = inflater.inflate(R.layout.home_layout,container, false);
Button button = (Button) myview.findViewById(R.id.button5);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// do something
}
});
return myview;
}
}
you have to add the fragment into the activity and launch this activity.
it is not possible for fragment to be launched independently.
in empty activity add this xml
<fragment android:name="com.company.appName.fragments.FirstFragment"
android:id="#+id/fragment_place"
android:layout_width="match_parent"
android:layout_height="match_parent" />
and in activity onCreate method do this
Fragment fr = new FirstFragment();
fr.setArguments(args);
FragmentManager fm = getFragmentManager();
FragmentTransaction fragmentTransaction = fm.beginTransaction();
fragmentTransaction.replace(R.id.fragment_place, fr);
fragmentTransaction.commit();
hope this will help you.
Fragment must be launched from Activity.
You can do it by launching your fragment from your activity onCreate() method like this:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getFragmentManager().beginTransaction().replace(android.R.id.content, new MyFragment()).commit();
}
Obviously, I am new to Android - XML programming... So I have a navigation drawer, and once item is selected from the drawer, a corresponding fragment on the right side will display. Inside that fragment, I have linear layouts. I'd like to get redirected to another activity once that linear layout has been tapped. I was able to make it work on activities, by using android:onClick on XML file, but can't make it work on fragment. Somebody help me please.
App interface, refer to this image:
http://i.stack.imgur.com/u6dHi.jpg
Code:
fragment_smart.xml - the display once item's selected. I am trying to use the onClick on xml.
<LinearLayout
android:id="#+id/linearLayoutsmart1"
android:layout_width="match_parent"
android:layout_height="30dp"
android:layout_below="#+id/smart_title"
android:layout_marginLeft="15dp"
android:layout_marginTop="15dp"
android:orientation="horizontal"
android:weightSum="1"
android:onClick="smart_recommended_link">
Here's my Java code:
public class FragmentSmart extends Fragment {
public static final String TAG = "stats";
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View myfragment = inflater.inflate(R.layout.fragment_smart, container, false);
return myfragment;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
public void smart_recommended_link(View view) {
Intent smartRecommendedIntent = new Intent(this, SmartRecommended.class);
startActivity(smartRecommendedIntent);
}
}
The app is crashing when I clicked on the linearlayout using this code. What's the best thing to do here? Thank you!
For fragments you need to add the listener programmatically:
public class MyFragment extends Fragment implements View.OnClickListener {
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
view.findViewById(R.id.my_layout).setOnClickListener(this);
}
#Override
public void onClick(View v) {
// Handle click based on v.getId()
}
}
First of all, linear layouts cant trigger onClick events by default.
Check this answer for more information: LinearLayout onClick.
You can get the LinearLayout from the view in your onCreateView() like this:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View myfragment = inflater.inflate(R.layout.fragment_smart, container, false);
LinearLayout layout = (LinearLayout)myFragment.findViewById(R.id.linearLayoutsmart1);
// here you can set a listener of any type you want to the layout
return myfragment;
}
In fragments, you must use getActivity() method instead of this to reference the activity that the fragment is attached to.
public void smart_recommended_link(View view) {
Intent smartRecommendedIntent = new Intent(getActivity(), SmartRecommended.class);
startActivity(smartRecommendedIntent);
}
I have the following Activity:
public class MainActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new StartFragment())
.commit();
}
Button login = (Button) findViewById(R.id.loginButton);
login.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
Intent intent = new Intent(MainActivity.this,LoginActivity.class);
startActivity(intent);
}
});
}
I get a NPE when I try to invoke findViewByID for R.id.loginButton, and I'm guessing this is because loginButton is within a separate Fragment, which I have as:
public static class StartFragment extends Fragment {
public StartFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_main, container, false);
}
}
However, I am unsure of how to fix this so that I can find the loginButton ID. I haven't worked with fragments before, so I realize I may be using them/implementing them incorrectly. fragment_main contains a few buttons in a LinearLayout, and activity_main has nothing but a single FrameLayout.
Try to implement your onCreateView(...) in Fragment like
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container,
false);
View something = rootView.findViewById(R.id.something);
something.setOnClickListener(new View.OnClickListener() { ... });
return rootView;
}
The Button is in the fragment layout (fragment_main.xml) and not in the activity layout (activity_main.xml). onCreate() is too early in the lifecycle to find it in the activity view hierarchy, and a null is returned. Invoking a method on null causes the NPE.
Write code to initialize button from fragment becuase your button is into fragment layout not into activity's layout.
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container,
false);
Button login = (Button) rootView.findViewById(R.id.loginButton);
login.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
Intent intent = new Intent(MainActivity.this,
LoginActivity.class);
startActivity(intent);
}
});
return rootView;
}
And remove the login button related code from onCreate of Activity.
findViewById() works with reference to a root view.
Without having a view in the first place will throw a null pointer exception
In any activity you set a view by calling setContentView(someView);.
Thus when you call findViewById() , its with reference to the someView.
Also findViewById() finds the id only if its in that someView. So in you case null pointer exception
For fragments, adapters, activity, .... any view's findViewById() will only find if the id exixts in the view
Alternately if you are inflating a view, then you can also use inflatedView.findViewById() to get a view from that inflatedView
In short make sure you have the id in your layout you are referring to or make findViewById() call in appropriate place(Ex. adapters getView(), activity's onCreate() or onResume() or onPause() , fragments onCreateView(), ....)
Also have an idea about UI & background thread's as you cannot efficiently update UI in bg-threads
I am trying to add left side slide menu inside my application but i am facing little trouble getting the slide menu to the following child activities of the fragment.
So far i have tried using this sliding menu example and when i got this image now inside the "Find People" fragment class i have static data.
Find People (Parent Activity) on Button Click go to ---> Friends (Child Activity of Find People) on Button Click go to ----> Names (Child Activity of Friends)
I am trying to get the same sliding menu with the Child Activities also that i failed to achieve so far please can any one help me out
public class FindPeopleFragment extends Fragment {
public FindPeopleFragment(){}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_find_people, container, false);
Button btn = (Button) rootView.findViewById(R.id.butto);
btn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(getActivity(), Friends.class);
startActivity(intent);
}
});
return rootView;
}
}
Friends (Child Activity)
public class Friends extends Activity {
Button btnNext;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.friends_xml);
btnNext = (Button)findViewById(R.id.btnNexts);
btnNext.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
// Go to Names Child Activity
}
});
}
}
And Similarly Names (Child Activity)
How do i get the same slide menu in both the child activities (Friends & Names). Any idea ??
Plz help me out in this.
Code Snippet will be much helpful.
Thanks
As #Piyush Gupta said you need to call new Fragment instead of calling activities,
In Place of activity you need to use Fragment and move from one Fragment to next used this code
Instead of using Fragment element use Framelayout id of the fragment Xml
Replace ur code with this
public class FindPeopleFragment extends Fragment {
public FindPeopleFragment(){}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_find_people, container, false);
Button btn = (Button) rootView.findViewById(R.id.butto);
btn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
FragementDemo fd = new FragementDemo();
android.support.v4.app.FragmentTransaction ft =
getFragmentManager().beginTransaction();
ft.replace(R.id.content_frame, fd); // content_frame is your FrameLayout container
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
ft.addToBackStack(null);
ft.commit();
}
});
return rootView;
}
}
And your next child activity will extend Fragment not Activity like this :
public class Friends extends SherlockFragment{
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragementdemo, container, false);
// use button click code as used in FindPeopleFragment
return rootView;
}
}
Hope it works fine now for you!!
Okay so I've tried two types of code to get this to work and it keeps giving me force closes when I press the button to go into another Activity. I'm using a Fragment and there's a button in that Fragments code but I can't seem to get it to work. I'm not an experienced Android developer but I'm trying my best to learn.
Here's the Java code:
1st Method
public class About extends Fragment {
Intent intent;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.about, container, false);
intent = new Intent(getActivity(), Contact_Developer.class);
final Button button = (Button) rootView.findViewById(R.id.btnContactDev);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
startActivity(intent);
}
});
return rootView;
}
}
2nd Method
public class About extends Fragment {
public void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.about, container, false);
Button button = (Button) rootView.findViewById(R.id.btnContactDev);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
Intent intent = new Intent(getActivity(), Contact_Developer.class);
getActivity().startActivity(intent);
}
});
return rootView;
}
}
I really don't know what's going on and why I'm getting force closes but if anyone could help me and explain a little what I did wrong that'd be more than enough
Do not handle the onClick for the fragment button in the Fragment. Let it go it's parent activity. And start the activity from the parent activity.
To make sure that the button onClick event is sent to the parent activity, make sure, in your about.xml, for the button with id btnContactDev, you have the following parameter:
<Button android:id="#+id/btnContactDev"
android:onClick="buttonClick"
...
/>
and in your parent activity (parent of About fragment), you have:
public void buttonClick(View v) {
switch(v.getId()) {
case R.id.btnContactDev:
Intent myIntent = new Intent();
myIntent.setClassName(your_package_name_string, your_activity_name_string);
// for ex: your package name can be "com.example"
// your activity name will be "com.example.Contact_Developer"
startActivity(myIntent);
break;
}
}
HTH.
PS: This solution is very specific for what your requirement. In general, it's best to handle the onClick events related to the fragment inside the fragment class.
PS: Yes, as the other solution says, make sure you have registered the Contact_Developer Activity in your Manifest file.
Have you declared the proper activity in the AndroidManifest.xml? Each activity other then the first should be declared inside the application tag, like this:
<activity
android:name=".Contact_Developer"
android:label="#string/app_name" >
</activity>
If it's not found, it will give force close.
I think the issue here is that the activity is not ready.
I would not recommend you following harikris's solution even though it works. It's usually bad practice to put code (onClick() which handles the click event) in your XML file. For example, it will be very difficult to hunt that piece of code down to review/ change it in the future yourself, not to mention another developer in your team.
I'd suggest to listen to the event the activity is ready i.e. onActivityCreated() within your Fragment class. Override the implementation of the same method and call something in your activity e.g. onFragmentReady() like in the example below.
Fragment class:
public class About extends Fragment {
Intent intent;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.about, container, false);
intent = new Intent(getActivity(), Contact_Developer.class);
final Button button = (Button) rootView.findViewById(R.id.btnContactDev);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
startActivity(intent);
}
});
return rootView;
}
#Override
public void onActivityCreated (Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
((MyActivity) this.getActivity()).onFragmentReady();
}
}
Activity class:
public class MyActivity extends FragmentActivity {
private void onFragmentReady() {
Log.i(TAG, "testing");
intent = new Intent(getActivity(), Contact_Developer.class);
final Button button = (Button) rootView.findViewById(R.id.btnContactDev);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
startActivity(intent);
}
});
}
public class About extends Fragment {
...
}
}
I think you should use getContext() or getApplicationContext() instead of getActivity()
so code will be
Intent intent =new Intent(getContext(),Contact_Developer.class);
startActivity(intent);