I'm working on dynamically setting a text of TextView in a fragment called 'ChallengeFragment' by creating a method that sets the text. Then, I call the method in FragmentActivity class to update the TextView. However, I am getting error that TextView object is null when the method is called. I am not sure why TextView is null.
Here's the logcat message:
16:36:02.437 4072-4072/eie.android.crunch E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: eie.android.crunch, PID: 4072
java.lang.RuntimeException: Unable to start activity ComponentInfo{eie.android.crunch/eie.android.crunch.ChallengePage}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2325)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2390)
at android.app.ActivityThread.access$800(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5257)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
at eie.android.crunch.ChallengeFragment.setNameText(ChallengeFragment.java:76)
at eie.android.crunch.ChallengePage.onCreate(ChallengePage.java:50)
at android.app.Activity.performCreate(Activity.java:5990)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2278)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2390)
at android.app.ActivityThread.access$800(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5257)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
Here is the Fragment class (ChallengeFragment.java):
public class ChallengeFragment extends Fragment {
private Activity mActivity;
private TextView nameText;
private Handler handler =new Handler();
public ChallengeFragment() {
}
public void onAttach(Activity activity) {
super.onAttach(activity);
mActivity = activity;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
LayoutInflater lf = getActivity().getLayoutInflater();
View v = lf.inflate(R.layout.fragment_challenge, null);
nameText = (TextView) v.findViewById(R.id.user_name_text_view);
....
return v;
}
public void setNameText(String s) {
nameText.setText(s);
}
public TextView getNameText() {
return nameText;
}
}
And this is the code for FragmentActivity that updates the text of TextView (ChallengePage.java):
public class ChallengePage extends FragmentActivity {
private FriendChallengeFragment initialFriendHabit;
private ChallengeFragment friendHabit;
private ChallengeFragment myHabit;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_challenge);
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fm.beginTransaction();
myHabit = new ChallengeFragment();
initialFriendHabit = new FriendChallengeFragment();
myHabit.onAttach(ChallengePage.this);
initialFriendHabit.onAttach(ChallengePage.this);
fragmentTransaction
.replace(R.id.my_habit, myHabit ,"fragment_top")
.replace(R.id.friend_habit, initialFriendHabit, "fragment_bottom")
.commit();
Intent intent = getIntent();
String challengedUsername = intent.getStringExtra("username");
if(challengedUsername != null) {
friendHabit = new ChallengeFragment();
friendHabit.onAttach(ChallengePage.this);
fragmentTransaction.replace(R.id.friend_habit, friendHabit, "fragment_bottom");
friendHabit.setNameText(challengedUsername);
}
}
}
And this is the layout file that contains the fragment (fragment_challenge.xml):
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
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:textColor="#color/white"
android:id="#+id/user_name_text_view"
android:layout_gravity="center_horizontal"
android:text="User Name"
android:textSize="30dp"
android:layout_marginTop="30dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#color/white"
android:id="#+id/habit_name_text"
android:layout_gravity="center_horizontal"
android:text="Habit Name"
android:textSize="40dp"
android:layout_marginTop="20dp"/>
<ProgressBar
android:layout_height="wrap_content"
android:layout_width="312dp"
style="#android:style/Widget.ProgressBar.Horizontal"
android:id="#+id/progressBar"
android:layout_marginTop="50dp"
android:layout_gravity="center_horizontal"/>
</LinearLayout>
I've looked at other stackoverflow questions relating to this but could not find answers.
The problem is your fragment's setNameText() method is called before onCreateView() has run, so your TextView has not been initialized yet. You have to wait until later to set the name text.
If you always have the name text when you are creating and adding the fragment, then it's better to pass that as an argument to the fragment and have it set the text of the TextView at the appropriate time. Something like this:
public class ChallengeFragment extends Fragment {
public static ChallengeFragment newInstance(String name) {
ChallengeFragment fragment = new ChallengeFragment();
Bundle args = new Bundle();
args.putString("username", name);
fragment.setArguments(args);
return fragment;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
Bundle args = getArguments();
if (args != null) {
String name = args.getString("username");
nameText.setText(name);
}
}
// everything else
}
A few things to note:
Do not create a constructor. Fragments need to have a default (no argument) constructor so that Android can instantiate them. This newInstance pattern is typically regarded as the best practice.
Use onActivityCreated because at that time you know the Activity is created and that the fragment's view hierarchy has been created.
Fragment arguments persist across configuration changes, so you shouldn't need to do anything special for that.
Also, you should not be calling onAttach() yourself, that's a lifecycle method that the OS calls on your fragment.
Related
I am trying to link a Fragment, RecycleView and CardView using a variation of the tutorial found on:
http://www.treyrobinson.net/blog/android-l-tutorials-part-3-recyclerview-and-cardview/
Unfortunately my app crashes with the following error message:
"java.lang.IllegalStateException: RecyclerView has no LayoutManager"
I am fairly new with Android development. I tried to find similar issues on Stackoverflow but am unable to find the issue. Any help would be greatly appreciated!
Layout of the main activity: "activity_library.xml":
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".LibraryActivity">
<android.support.v7.widget.RecyclerView
android:id="#+id/library_activity_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".LibraryActivity"
/>
</RelativeLayout>
The main activity class "LibraryActivity.java":
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
public class LibraryActivity extends AppCompatActivity{
private static final String TAG = LibraryActivity.class.getSimpleName();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); /**Create the activity and populate the savedInstanceState if the activity existed but has been destroyed (otherwise savedInstanceState will return 'null'*/
setContentView(R.layout.activity_library); /** Call to the XML layout library which display the activity */
if (savedInstanceState != null) {
// Restore value of members from saved state
} else {
// Probably initialize members with default values for a new instance
}
try {
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
BooksFragment bookFragment = new BooksFragment();
fragmentTransaction.add(R.id.library_activity_recycler_view,bookFragment);
/*The line below is the one generating the error - java.lang.IllegalStateException: RecyclerView has no LayoutManager*/
fragmentTransaction.commit();
}
catch(Exception e){
Log.d(TAG,"[ERROR] " + e.getMessage());
}
}
}
The layout of the fragment "fragment_books.xml":
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<android.support.v7.widget.RecyclerView
android:id="#+id/Book_Recycler_View"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v7.widget.RecyclerView>
</LinearLayout>
And the fragment class:
import android.app.Fragment;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class BooksFragment extends Fragment {
public BooksFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.activity_library, container, false);
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
RecyclerView bookRecycler = (RecyclerView) v.findViewById(R.id.library_activity_recycler_view);
bookRecycler.setLayoutManager(layoutManager);
BookRecyclerViewAdapter adapter = new BookRecyclerViewAdapter();
bookRecycler.setAdapter(adapter);
/*In the line below should we return the view 'v' or the RecyclerView 'bookRecycler'??*/
return bookRecycler;
}
}
As I said I am fairly new to Android and therefore apologies if my code contains quite a few errors. Thanks for your help!
For reference the complete error log:
04-18 14:04:52.323 11225-11225/com.wldtaster.tellmeastory E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.wldtaster.tellmeastory, PID: 11225
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.wldtaster.tellmeastory/com.wldtaster.tellmeastory.LibraryActivity}: java.lang.IllegalStateException: RecyclerView has no LayoutManager
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2325)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387)
at android.app.ActivityThread.access$800(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
Caused by: java.lang.IllegalStateException: RecyclerView has no LayoutManager
at android.support.v7.widget.RecyclerView.generateLayoutParams(RecyclerView.java:3393)
at android.view.LayoutInflater.inflate(LayoutInflater.java:492)
at android.view.LayoutInflater.inflate(LayoutInflater.java:414)
at com.wldtaster.tellmeastory.BooksFragment.onCreateView(BooksFragment.java:23)
at android.app.Fragment.performCreateView(Fragment.java:2053)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:894)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1067)
at android.app.BackStackRecord.run(BackStackRecord.java:834)
at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1452)
at android.app.Activity.performStart(Activity.java:6005)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2288)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387)
at android.app.ActivityThread.access$800(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
You must return the view ie. v in the onCreateView method of the Fragment inherited class.
I get this error when i try to run my android app:
Process: com.example.ronen.sunplantnew, PID: 28608
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.ronen.sunplantnew/com.example.ronen.sunplantnew.MainActivity}: android.view.InflateException: Binary XML file line #13: Error inflating class fragment
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2325)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387)
at android.app.ActivityThread.access$800(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
Caused by: android.view.InflateException: Binary XML file line #13: Error inflating class fragment
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:763)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:806)
at android.view.LayoutInflater.inflate(LayoutInflater.java:504)
at android.view.LayoutInflater.inflate(LayoutInflater.java:414)
at android.view.LayoutInflater.inflate(LayoutInflater.java:365)
at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:378)
at android.app.Activity.setContentView(Activity.java:2145)
at com.example.ronen.sunplantnew.MainActivity.onCreate(MainActivity.java:17)
at android.app.Activity.performCreate(Activity.java:5990)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2278)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387)
at android.app.ActivityThread.access$800(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.Button.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
at com.example.ronen.sunplantnew.HomeScreen.onCreate(HomeScreen.java:59)
at android.support.v4.app.Fragment.performCreate(Fragment.java:1939)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1029)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1226)
at android.support.v4.app.FragmentManagerImpl.addFragment(FragmentManager.java:1328)
at android.support.v4.app.FragmentManagerImpl.onCreateView(FragmentManager.java:2284)
at android.support.v4.app.FragmentController.onCreateView(FragmentController.java:111)
at android.support.v4.app.FragmentActivity.dispatchFragmentsOnCreateView(FragmentActivity.java:314)
at android.support.v4.app.BaseFragmentActivityHoneycomb.onCreateView(BaseFragmentActivityHoneycomb.java:31)
at android.support.v4.app.FragmentActivity.onCreateView(FragmentActivity.java:79)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:733)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:806)
at android.view.LayoutInflater.inflate(LayoutInflater.java:504)
at android.view.LayoutInflater.inflate(LayoutInflater.java:414)
at android.view.LayoutInflater.inflate(LayoutInflater.java:365)
at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:378)
at android.app.Activity.setContentView(Activity.java:2145)
at com.example.ronen.sunplantnew.MainActivity.onCreate(MainActivity.java:17)
at android.app.Activity.performCreate(Activity.java:5990)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2278)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387)
at android.app.ActivityThread.access$800(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
The main activity java file (MainActivity.java)
public class MainActivity extends FragmentActivity implements HomeScreen.OnFragmentInteractionListener, LightTest.OnFragmentInteractionListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public void onFragmentInteraction(Uri uri) {
}
}
the main activity xml file (activity_main.xml)
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/fragment_container"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.example.ronen.sunplantnew.MainActivity">
<fragment class="com.example.ronen.sunplantnew.HomeScreen"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/home"/>
</RelativeLayout>
HomeScreen java file (HomeScreen.java):
public class HomeScreen extends android.support.v4.app.Fragment {
private Button newTest;
private Button lastTests;
private Button plants;
private Button about;
private OnFragmentInteractionListener mListener;
public HomeScreen() {
// Required empty public constructor
}
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* #return A new instance of fragment HomeScreen.
*/
public static HomeScreen newInstance() {
HomeScreen fragment = new HomeScreen();
Bundle args = new Bundle();
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
newTest=(Button)getActivity().findViewById(R.id.newTest);
lastTests=(Button)getActivity().findViewById(R.id.lastTests);
plants=(Button)getActivity().findViewById(R.id.plants);
about=(Button)getActivity().findViewById(R.id.about);
newTest.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
toLightTest();
}
});
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_home_screen, container, false);
}
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p/>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(Uri uri);
}
public void toLightTest(){
// Create new fragment and transaction
Fragment newFragment = new LightTest();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);
// Commit the transaction
transaction.commit();
}
}
HomeScreen xml file (fragment_home_screen.xml):
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.ronen.sunplantnew.HomeScreen">
<ImageView
android:layout_width="150dp"
android:layout_height="wrap_content"
android:id="#+id/imageView2"
android:src="#drawable/sun_plant"
android:layout_centerHorizontal="true"
android:layout_gravity="center" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="About"
android:id="#+id/about"
android:layout_alignBottom="#+id/imageView2"
android:layout_centerHorizontal="true"
android:layout_gravity="center_horizontal|bottom" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Last Tests"
android:id="#+id/lastTests"
android:layout_below="#+id/newTest"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_marginTop="41dp"
android:layout_gravity="left|center_vertical" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New LightTest"
android:id="#+id/newTest"
android:layout_alignTop="#+id/imageView2"
android:layout_alignRight="#+id/imageView2"
android:layout_alignEnd="#+id/imageView2"
android:layout_marginTop="45dp"
android:layout_gravity="center_horizontal|top" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Plants Info"
android:id="#+id/plants"
android:layout_alignTop="#+id/lastTests"
android:layout_toLeftOf="#+id/newTest"
android:layout_toStartOf="#+id/newTest"
android:layout_gravity="right|center_vertical" />
What do i need to do to fix this error?
You're trying to find newTest in your Activity, but it's inside HomeScreen.
Try this instead:
HomeScreen.java
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_home_screen, container, false);
newTest = (Button)view.findViewById(R.id.newTest);
lastTests = (Button)view.findViewById(R.id.lastTests);
plants = (Button)view.findViewById(R.id.plants);
about=(Button)view.findViewById(R.id.about);
newTest.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
toLightTest();
}
});
return view;
}
I'm working on an application for android in Android Studio and I'm attempting to make an on-click listener like so:
Button menu_button = (Button)findViewById(R.id.menu_button);
menu_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
However, when I start genymotion it tells me that the app has stopped working. If I remove this code:
menu_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
The application runs fine. I'm very confused and was hoping maybe someone could point something out I'm not understanding.
Here's the full code of the main activity I'm working on, and I should note that the button is inside a ViewPager.
public class MainActivity extends FragmentActivity {
private ViewPager m_BackgroundViewPager;
private ViewPager m_PanelViewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature((int) Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
m_BackgroundViewPager = (ViewPager)(findViewById(R.id.mainViewPager));
m_PanelViewPager = (ViewPager)(findViewById(R.id.bottomViewPager));
m_BackgroundViewPager.setAdapter
(new BackgroundPagerAdapter(getSupportFragmentManager(), this));
m_PanelViewPager.setAdapter
(new PanelPagerAdapter(getSupportFragmentManager(), this));
Button menu_button = (Button)findViewById(R.id.menu_button);
menu_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
}
}
LogCat Results:
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.Button.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
at eqlogic.annswingsandthings.MainActivity.onCreate(MainActivity.java:37)
at android.app.Activity.performCreate(Activity.java:5933)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2251)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
at android.app.ActivityThread.access$800(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
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"
android:background="#998822">
<Button
android:layout_width="75dp"
android:layout_height="75dp"
android:id="#+id/menu_button"
android:text="Menu"
android:textSize="12dp" />
</FrameLayout>
Create a global variable for your Button as follows :
Button menu_button;
Then in your onCreate() you add this line :
menu_button = (Button)findViewById(R.id.menu_button);
And now whenever you want to make a setOnClickListener() you can do it like you were doing :
menu_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//Your click stuff
}
});
EDIT
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.Button.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
Make sure that in your activity_main.xml your button has this :
android:id="#+id/menu_button"
Problem is that the button is inside the view pager.
So in order to display the button either remove it out of the view pager or add it to the xml of the fragment which forms part of the view pager and inflate it in that fragment.
I am trying to display a list in my main activity using a ListFragment. The list is populated by my custom ArrayAdapter that uses a custom object. I am having trouble getting this list to show in the app. When I debug, it doesn't show any errors but the app immediately crashes.
Here is my fragment
Edit: I have tried several responses and have narrowed down the issue to the momentObjectListView.setAdapter(momentObjectAdapter) in the ListViewFragment. I cannot find a reason why the momentObjectAdapter would be null so it must be momentObjectListView however I cannot find where the issue stems. Any help would be much appreciated. My activity_main.xml, fragment, main activity, and adapter code are all included.
public class ListViewFragment extends ListFragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Activity myAct = getActivity();
View view = inflater.inflate(R.layout.activity_main, container, false);
ListView momentObjectListView = (ListView)view.findViewById(R.id.list_item);
//ListView momentObjectListView = getListView();
MomentObjectAdapter momentObjectAdapter = new MomentObjectAdapter(myAct, R.layout.moment_object_list_item);
//momentObjectListView.setAdapter(momentObjectAdapter);
List<MomentObject> myMoments = getMoments();
for(final MomentObject entry : myMoments) {
momentObjectAdapter.add(entry);
}
//ListViewFragment.this.setListAdapter(momentObjectAdapter);
momentObjectListView.setAdapter(momentObjectAdapter);
return view;
}
private List<MomentObject> getMoments() {
// Let's setup some test data.
// Normally this would come from some asynchronous fetch into a data source
// such as a sqlite database, or an HTTP request
final List<MomentObject> entries = new ArrayList<MomentObject>();
for(int i = 1; i < 50; i++) {
entries.add(
new MomentObject(
"Test Entry " + i,
"Anonymous Author",
new GregorianCalendar(2011, 11, i).getTime(),
R.drawable.photoicon
)
);
}
return entries;
}
}
And here is my activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin" tools:context=".MainActivity"
android:background="#ffffffff">
<fragment android:name="com.malatras.moment2.ListViewFragment"
android:id="#+id/list"
android:layout_weight="1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
Please let me know if there is anything I need to provide to solve this.
LogCat:
e02-24 18:54:29.119 2325-2325/com.malatras.moment2 I/art﹕ Not late-enabling -Xcheck:jni (already on)
02-24 18:54:29.191 2325-2325/com.malatras.moment2 D/AndroidRuntime﹕ Shutting down VM
02-24 18:54:29.191 2325-2325/com.malatras.moment2 E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.malatras.moment2, PID: 2325
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.malatras.moment2/com.malatras.moment2.MainActivity}: android.view.InflateException: Binary XML file line #9: Error inflating class fragment
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2298)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
at android.app.ActivityThread.access$800(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
Caused by: android.view.InflateException: Binary XML file line #9: Error inflating class fragment
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:763)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:806)
at android.view.LayoutInflater.inflate(LayoutInflater.java:504)
at android.view.LayoutInflater.inflate(LayoutInflater.java:414)
at android.view.LayoutInflater.inflate(LayoutInflater.java:365)
at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:377)
at android.app.Activity.setContentView(Activity.java:2144)
at com.malatras.moment2.MainActivity.onCreate(MainActivity.java:11)
at android.app.Activity.performCreate(Activity.java:5933)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2251)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
at android.app.ActivityThread.access$800(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ListView.setAdapter(android.widget.ListAdapter)' on a null object reference
at com.malatras.moment2.ListViewFragment.onCreateView(ListViewFragment.java:34)
at android.app.Fragment.performCreateView(Fragment.java:2053)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:870)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1045)
at android.app.FragmentManagerImpl.addFragment(FragmentManager.java:1147)
at android.app.FragmentManagerImpl.onCreateView(FragmentManager.java:2116)
at android.app.Activity.onCreateView(Activity.java:5282)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:733)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:806)
at android.view.LayoutInflater.inflate(LayoutInflater.java:504)
at android.view.LayoutInflater.inflate(LayoutInflater.java:414)
at android.view.LayoutInflater.inflate(LayoutInflater.java:365)
at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:377)
at android.app.Activity.setContentView(Activity.java:2144)
at com.malatras.moment2.MainActivity.onCreate(MainActivity.java:11)
at android.app.Activity.performCreate(Activity.java:5933)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2251)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
at android.app.ActivityThread.access$800(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
MainActivity:
public class MainActivity extends ListActivity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MomentObjectAdapter:
public final class MomentObjectAdapter extends ArrayAdapter<MomentObject> {
private final int momentObjectLayoutResource;
public MomentObjectAdapter(final Context context, final int momentObjectLayoutResource) {
super(context, 0);
this.momentObjectLayoutResource = momentObjectLayoutResource;
}
#Override
public View getView(final int position, final View convertView, final ViewGroup parent) {
// We need to get the best view (re-used if possible) and then
// retrieve its corresponding ViewHolder, which optimizes lookup efficiency
final View view = getWorkingView(convertView);
final ViewHolder viewHolder = getViewHolder(view);
final MomentObject entry = getItem(position);
// Setting the title view is straightforward
viewHolder.titleView.setText(entry.getTitle());
// Setting the subTitle view requires a tiny bit of formatting
final String formattedSubTitle = String.format("By %s on %s",
entry.getAuthor(),
DateFormat.getDateInstance(DateFormat.SHORT).format(entry.getPostDate())
);
viewHolder.subTitleView.setText(formattedSubTitle);
// Setting image view is also simple
viewHolder.imageView.setImageResource(entry.getIcon());
return view;
}
private View getWorkingView(final View convertView) {
// The workingView is basically just the convertView re-used if possible
// or inflated new if not possible
View workingView = null;
if(null == convertView) {
final Context context = getContext();
final LayoutInflater inflater = (LayoutInflater)context.getSystemService
(Context.LAYOUT_INFLATER_SERVICE);
workingView = inflater.inflate(momentObjectLayoutResource, null);
} else {
workingView = convertView;
}
return workingView;
}
private ViewHolder getViewHolder(final View workingView) {
// The viewHolder allows us to avoid re-looking up view references
// Since views are recycled, these references will never change
final Object tag = workingView.getTag();
ViewHolder viewHolder = null;
if(null == tag || !(tag instanceof ViewHolder)) {
viewHolder = new ViewHolder();
viewHolder.titleView = (TextView) workingView.findViewById(R.id.moment_object_title);
viewHolder.subTitleView = (TextView) workingView.findViewById(R.id.moment_object_subtitle);
viewHolder.imageView = (ImageView) workingView.findViewById(R.id.moment_object_icon);
workingView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) tag;
}
return viewHolder;
}
/**
* ViewHolder allows us to avoid re-looking up view references
* Since views are recycled, these references will never change
*/
private static class ViewHolder {
public TextView titleView;
public TextView subTitleView;
public ImageView imageView;
}
}
moment_object_list_item:
<?xml version="1.0" encoding="utf-8"?>
<!-- Layout for individual news entries in a list -->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<!-- Icon shown next to the title/subtitle -->
<ImageView
android:id="#+id/moment_object_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:padding="3dp" />
<!-- Title of the news entry -->
<TextView
android:id="#+id/moment_object_title"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_toRightOf="#id/moment_object_icon"
android:layout_alignTop="#id/moment_object_icon"
android:layout_margin="5dp"
android:textSize="14sp"
android:textStyle="bold" />
<!-- Subtitle contains author and date -->
<TextView
android:id="#+id/moment_object_subtitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#id/moment_object_title"
android:layout_below="#id/moment_object_title"
android:textSize="12sp" />
</RelativeLayout>
This code I don't like and not compatible with your method getMoments is:
for(final MomentObject entry : getMoments()) {
momentObjectAdapter.add(entry);
}
For now try this for a quick sample fix:
List<MomentObject> myMoments = getMoments();
for(final MomentObject entry : myMoments) {
The reason is getMoments() in the for loop is evaluated dynamically. I think so even though you declared it with final.
In the log,
Attempt to invoke virtual method 'void
android.widget.ListView.setAdapter(android.widget.ListAdapter)' on a
null object reference
I believe object momentObjectListView is null. I could not find the UI in fragment_list_view.xml. It is however in activity_main.xml. Sample code :
View view = inflater.inflate(R.layout.activity_main, container, false);
ListView momentObjectListView = (ListView)view.findViewById(R.id.list);
Sample layout element for a ListFragment in activity_main:
<fragment android:name="com.malatras.moment2.ListViewFragment"
android:id="#+id/list"
...>
A good webpage for explaining layouts is required for understanding the basics # Layouts .
Change in your XML file this line : android:id="#+id/list"
to:
android:id="#id/android:list
and in ListViewFragment change this : ListView momentObjectListView =(ListView)view.findViewById(R.id.list);
to this:
ListView momentObjectListView = (ListView)view.findViewById(android.R.id.list);
In your Logcat file, it says
android.view.InflateException: Binary XML file line #9: Error
inflating class fragment
This means an xml file is not proper. Also deeper in the log,
The code MainActivity.onCreate(MainActivity.java:11)
...
Caused by: java.lang.NullPointerException: Attempt to invoke virtual
method 'void
android.widget.ListView.setAdapter(android.widget.ListAdapter)' on a
null object reference at
com.malatras.moment2.ListViewFragment.onCreateView(ListViewFragment.java:34)
...
ListViewFragment.onCreateView(ListViewFragment.java:34)
Need to load file ListViewFragment.java too. In order to save time, perhaps post more files.
Another possible good code change is to modify ListViewFragment definition from:
public class ListViewFragment extends ListFragment {
to:
public class ListViewFragment extends Fragment implements AbsListView.OnItemClickListener {
The OnItemClickListener is optional.
The reason I say this is that MainActivity already hosts ListView object through ListActivity. Another reason, Android Studio wizard generates the "to" suggested code. And it sounds good to me.
Another way is to remove ListActivity from MainActivity to just Activity, with the same reason.
All these suggestions may be considered to be code style however.
Every time orientation changes Fragment crashes with error:
01-26 12:46:43.215 2895-2895/com.cbsystematic.mobile.itvdn
E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.cbsystematic.mobile.itvdn, PID: 2895
java.lang.RuntimeException: Unable to destroy activity {com.cbsystematic.mobile.itvdn/com.cbsystematic.mobile.itvdn.NavigationActivity}: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:3671)
at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:3689)
at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3889)
at android.app.ActivityThread.access$900(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1284)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
Caused by: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1365)
at android.support.v4.app.FragmentManagerImpl.popBackStackImmediate(FragmentManager.java:516)
at com.cbsystematic.mobile.itvdn.LessonsFragment.replaceFragment(LessonsFragment.java:126)
at com.cbsystematic.mobile.itvdn.LessonsFragment.onDetach(LessonsFragment.java:119)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1080)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1126)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1108)
at android.support.v4.app.FragmentManagerImpl.dispatchDestroy(FragmentManager.java:1954)
at android.support.v4.app.FragmentActivity.onDestroy(FragmentActivity.java:313)
at android.support.v7.app.ActionBarActivity.onDestroy(ActionBarActivity.java:169)
at android.app.Activity.performDestroy(Activity.java:6112)
at android.app.Instrumentation.callActivityOnDestroy(Instrumentation.java:1140)
at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:3658)
at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:3689)
at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3889)
at android.app.ActivityThread.access$900(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1284)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
I need to save state of current Fragment.
Fragment class code:
public class LessonsFragment extends Fragment implements AbsListView.OnItemClickListener {
private OnFragmentInteractionListener mListener;
/**
* The fragment's ListView.
*/
private AbsListView mListView;
/**
* The Adapter which will be used to populate the ListView/GridView with
* Views.
*/
private ListAdapter mAdapter;
private static String courseUrl;
private ParserJson parserJson = new ParserJson();
private TextView descriptionTextView;
private DescriptionData descriptionData;
// TODO: Rename and change types of parameters
public static LessonsFragment newInstance(String url) {
LessonsFragment fragment = new LessonsFragment();
courseUrl = url;
return fragment;
}
/**
* Mandatory empty constructor for the fragment manager to instantiate the
* fragment (e.g. upon screen orientation changes).
*/
public LessonsFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// TODO: Change Adapter to display your content
mAdapter = new LessonsItemAdapter(getActivity(),
R.layout.lessons_list_item, parserJson.getLessons(courseUrl).getLessonsArray());
descriptionData = parserJson.getLessons(courseUrl).getDescriptionData();
}
// #Override
// public void onSaveInstanceState(Bundle outState) {
// //No call for super(). Bug on API Level > 11.
// }
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_lessons_list, container, false);
descriptionTextView = (TextView) view.findViewById(R.id.lessons_description);
descriptionTextView.setText("Описание курса:\n" +
descriptionData.getShortDescription());
// Set the adapter
mListView = (AbsListView) view.findViewById(android.R.id.list);
((AdapterView<ListAdapter>) mListView).setAdapter(mAdapter);
// Set OnItemClickListener so we can be notified on item clicks
mListView.setOnItemClickListener(this);
return view;
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mListener = (OnFragmentInteractionListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement OnFragmentInteractionListener");
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
//this occurs when we move out of this Fragment
replaceFragment(CatalogFragment.newInstance(1));
}
private void replaceFragment (Fragment fragment){
String backStateName = fragment.getClass().getName();
String fragmentTag = backStateName;
boolean fragmentPopped = getFragmentManager().popBackStackImmediate (backStateName, 0);
if (!fragmentPopped && getFragmentManager().findFragmentByTag(fragmentTag) == null){ //fragment not in back stack, create it.
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.container, fragment, fragmentTag);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
ft.addToBackStack(backStateName);
ft.commit();
}
}
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if (null != mListener) {
mListener.onLessonFragmentInteraction(parserJson.getLessons(courseUrl).getLessonsArray().get(position).getId());
}
}
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p/>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
public void onLessonFragmentInteraction(String id);
}
}
Manifest:
<?xml version="1.0" encoding="utf-8"?>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".AuthorizationActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".NavigationActivity"
android:parentActivityName="com.cbsystematic.mobile.itvdn.AuthorizationActivity" >
<!-- The meta-data element is needed for versions lower than 4.1 -->
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.cbsystematic.mobile.itvdn.AuthorizationActivity" />
>
</activity>
</application>
Fragment's layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/fragment_lessons"
android:background="#FAF9F9"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.cbsystematic.mobile.itvdn.LessonsFragment">
<TextView
android:id="#+id/lessons_description"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textColor="#acacac" />
<ListView android:id="#android:id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#id/lessons_description"/>
I know that such problems are like pain in the neck. But please give your assumptions.
Will appreciate any help.
It crashes because the fragment gets recreated everytime you change the orientation.
Add this line to your activity in the manifest:
android:configChanges="keyboardHidden|orientation|screenSize"