Reputation: 23
I'm trying to make an app where I've a RecyclerView with the options to remove the objects and add random numbers. What I'm trying to do is show a fragment when any member of the recycler view list is clicked. I'm getting the error " java.lang.IllegalStateException: Activity has been destroyed". I'm pretty shure I'm doing something very wrong. What I tried to do is putting a call to the change fragment method on my AnimalsAdapter class. I'm letting the code below and a github link.
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.berna.recyclerviewtp2, PID: 18705
java.lang.IllegalStateException: Activity has been destroyed
at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:2114)
at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:683)
at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:637)
at com.example.berna.recyclerviewtp2.MainActivity.changeFragment(MainActivity.java:148)
at com.example.berna.recyclerviewtp2.AnimalsAdapter$1.onClick(AnimalsAdapter.java:81)
at android.view.View.performClick(View.java:6597)
at android.view.View.performClickInternal(View.java:6574)
at android.view.View.access$3100(View.java:778)
at android.view.View$PerformClick.run(View.java:25885)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
My Code Main class changeFragment:
public void changeFragment(View view){
Fragment fragment;
FragmentOne fragmentOne = new FragmentOne();
fragment = fragmentOne;
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.fragment,fragment);
ft.addToBackStack(null);
ft.commit();
FragmentOne class code:
public class FragmentOne extends Fragment {
@Override
public View onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstaceState){
//Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_blank,container,false);
}
}
Click Listener code:
// Set a click listener for TextView
holder.mTextView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
new MainActivity().changeFragment(view);
//String animal = mDataSet.get(position);
//Toast.makeText(mContext,animal,Toast.LENGTH_SHORT).show();
}
});
What I have to do to achieve the fragment when pressing the recyclerview member?
Original code I'm using to try what I'm trying
Github link for complete project
Upvotes: 0
Views: 320
Reputation: 3894
You should never instantiate your activity this way: new MainActivity().changeFragment(view);
, it will never initialise properly. So it's either you delegate the listener, or find another work around for the callback.
For example, create an interface for callback:
interface ItemClickListener {
void onItemClick(View v);
}
Let your MainActivity implements the interface:
public class MainActivity extends Activity implements ItemClickListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// ...
mAdapter = new AnimalsAdapter(mContext, animalsList, this);
// ...
}
@Override
public void onItemClick(View view) {
changeFragment(view);
}
}
Then allow your adapter to take ItemClickListener
as a parameter:
private ItemClickListener callback;
public AnimalAdapter(Context context, List<String> data, ItemClickListener callback) {
this.callback = callback;
And let your holder.mTextView
to forward the callback (back to activity):
holder.mTextView.setOnClickListener(callback::onItemClick);
Upvotes: 1
Reputation: 1278
You need two changes in your code. 1. Create an interface for click listener. 2. If you want to replace fragment then you need one more Layout in XML
We solve the first issue. 1. Create an interface for click listener. Below are some change you need to do in your adapter,
Create Interface in your adapter
public interface RecyclerItemInteraction { void onChangeFragmentClick(); }
The second change will pass this interface.
Deeclare gloabal variable private RecyclerItemInteraction mInteraction;
public AnimalsAdapter(Context context,List list,RecyclerItemInteraction interaction){ mDataSet = list; mContext = context; mInteraction = interaction; }
Replace this below line new MainActivity().changeFragment(view); : Remove it if (mInteraction!=null)mInteraction.onChangeFragmentClick(); add this line.
Now Go to your MainActivity and add below line mAdapter = new AnimalsAdapter(mContext, animalsList,this); You can see that add third parameter this.
Now override this method and enjoy your day.
@Override public void onChangeFragmentClick() { Fragment fragment; FragmentOne fragmentOne = new FragmentOne(); fragment = fragmentOne; FragmentManager fm = getSupportFragmentManager(); FragmentTransaction ft = fm.beginTransaction(); ft.replace(R.id.container,fragment); ft.addToBackStack(null); ft.commit(); }
Add this line to your main_activity.xml layout.
Upvotes: 0
Reputation: 3711
You should create fragment after activity created, that is a basic knowledge about activity life cycle.
holder.mTextView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(your_current_activity, MainActivity.class);
intent.putExtras(extras);
startActivity(intent);
}
});
then replace fragment in onCreate()
of MainActivity
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.your_activity_layout);
changeFragment(null); //because we don't using parameter view
}
If you have any problem else, please comment below.
Upvotes: 0