I created an application with navigation drawer using this tutorial: http://www.androidhive.info/2013/11/android-sliding-menu-using-navigation-drawer/
And I have a button on the first fragment. So, I want to change fragment by clicking the button. This code can change fragment but not change navigation draver state (title, selected item):
public class FirstFragment extends Fragment {
public FirstFragment(){}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_today, container, false);
return rootView;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
ImageButton addButton = (ImageButton) getView().findViewById(R.id.add_button);
addButton.setOnClickListener(new addNewListener());
super.onActivityCreated(savedInstanceState);
}
private class addNewListener implements View.OnClickListener {
#Override
public void onClick(View v) {
final FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.frame_container, new NewFragment(), "NewFragmentTag");
ft.commit();
}
}
}
How can I fix it?
Thanks a lot!
Related
Good afternoon, please tell me how you can set a custom title for the fragment in Android Studio? I use this code: public class FirstFragment extends Fragment implements View.OnClickListener {
public FirstFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_home, container, false);
Button aboutBtn = (Button) rootView.findViewById(R.id.aboutButton);
aboutBtn.setOnClickListener(this);
return rootView;
}
#Override
public void onClick(View view) {
Fragment fragment = null;
switch (view.getId()) {
case R.id.aboutButton:
fragment = new AboutFragment();
replaceFragment(fragment);
break;
....
}
}
public void replaceFragment(Fragment someFragment) {
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.frame_container, someFragment);
transaction.addToBackStack(null);
transaction.commit();
}
}
When I tried to use title="Name1"; this is not works. then if use getActivity().setTitle("Name1"); it works, but when press the back button the title remains unchanged
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_home, container, false);
// Add this line here to change title
getActivity().setTitle("your title");
Button aboutBtn = (Button) rootView.findViewById(R.id.aboutButton);
aboutBtn.setOnClickListener(this);
return rootView;
}
There are two activities in my app:
MainActivity (containing 3 fragments)
FragmentHome
FragmentOrders
FragmentAccount
AccountEditActivity
The code to set fragments in MainActivity is this:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
BottomNavigationView navigation = (BottomNavigationView) findViewById(R.id.navigation);
navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
// set Home as the default fragment
setFragment(FragmentMainHome.getInstance());
}
private void setFragment(Fragment fragment){
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.frame_layout, fragment);
transaction.commit();
}
The code for FragmentAccount is:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_activity_main_account, container, false);
layout = rootView.findViewById(R.id.layout_fragment_main_account);
etName = (EditText) layout.findViewById(R.id.etNameLabelValue);
etEmail = (EditText) layout.findViewById(R.id.etEmailLabelValue);
etGender = (EditText) layout.findViewById(R.id.etGenderLabelValue);
etPhoneNumber = (EditText) layout.findViewById(R.id.etPhoneNumberLabelValue);
btnEditAccount = (ImageButton) layout.findViewById(R.id.btnEditAccount);
btnManageAddresses = (ImageButton) layout.findViewById(R.id.btnAccountManageAddresses);
btnManageAddresses.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
}
});
btnEditAccount.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
}
});
return rootView;
}
The code for FragmentOrders is:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_activity_main_order_history, container, false);
layout = rootView.findViewById(R.id.layout_fragment_main_order_history);
lvOrders = (ListView) layout.findViewById(R.id.lvOrders);
tvNoOrdersFound = (TextView) layout.findViewById(R.id.tvNoOrdersFound);
final SwipeRefreshLayout pullToRefresh = rootView.findViewById(R.id.swipe_refresh_layout_order_history);
pullToRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
// load orders
pullToRefresh.setRefreshing(false);
}
});
lvOrders.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
}
});
return rootView;
}
and similar kind of code goes for FragmentHome
The Problem
I can move between fragments and the view works fine.
Now from Account fragment, I move to AccountEditActivity
I do some update there and come back to MainActivity by pressing hardware back button
FragmentHome is displayed fine but when I click on FragmentAccount, screen goes blank
Now, if I click on Home fragment and click FragmentAccount again, it displays fine.
What is wrong here?
better use viewpager in your activity to show the fragments
it's easy to manage while using viewpagers
have a look at the link
Fragments in viewpager
and in your case just move this code from onCreate to onResume
setFragment(FragmentMainHome.getInstance());
for understanding better have a look at the lifecycle of activity in android
Activity life cycle
I have an Activity with a ViewPager, each page of the ViewPager has a Fragment.
Inside my Screen3Fragment I have a LinearLayout (lly_fragments) where I am showing some other fragments. I start by showing the fragment Screen3_1
public class Screen3Fragment extends Fragment {
private FragmentManager manager;
private FragmentTransaction transaction;
public static Screen3Fragment newInstance() {
final Screen3Fragment mf = new Screen3Fragment();
return mf;
}
public Screen3Fragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_screen3, container, false);
Screen3_1Fragment frag31 = new Screen3_1Fragment();
manager = getChildFragmentManager();
transaction = manager.beginTransaction();
transaction.add(R.id.lly_fragments,frag31,"frag31");
transaction.addToBackStack("frag31");
transaction.commit();
return v;
}
}
This works fine without problems. Problem comes when, from within frag31 (which is inside Screen3Fragment), I want to call fragt32, for that I do the following.
public class Screen3_1Fragment extends Fragment {
private ImageButton imgbt_timer;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_screen3_1,container,false);
imgbt_timer = (ImageButton) v.findViewById(R.id.bT_scr31_timer);
imgbt_timer.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
getChildFragmentManager().beginTransaction()
.replace(R.id.lly_fragments, new Screen3_2Fragment(), "frag32")
.commit();
}
});
return v;
}
}
As I read in other answers, the line transaction.replaceshould do the trick and replace the existing frag31 by the given frag32 inside the same given container lly_fragments.
However, I get java.lang.IllegalArgumentException: No view found for id..... I am not sure why.
getFragmentManager() will return always attributes from parent, in most cases the activities. getChildFragmentManager() wil return parent attributes (in your case, Screen3Fragment attributes). It should be used when you add a fragment inside a fragment.
In your case, Screen3Fragment should be added using getFragmentManager() and Screen3_1Fragment should be added using getChildFragmentManager() because Screen3_1Fragment is Screen3Fragment child. Screen3Fragment is the parent.
I recomand you to use always getFragmentManager() with add method, not replace because your parent will be the same.
getChildFragmentManager() can be used when you add a ViewPager inside a fragment.
You can use the callback, as following :
that worked for me, I hope my answers helps you
1) create a interface
public interface ChangeFragmentListener {
void onChangeFragmentLicked(int fragment);
}
2) implement the interface and transaction methods in your activity:
public class MainActivity extends AppCompatActivity implements ChangeFragmentListener {
FragmentTransaction fragmentTransaction;
Fragment1 fragment1;
Fragment2 fragment2;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
fragment1 = new Fragment1();
fragment1.setChangeFragmentListener(this);
fragment2 = new Fragment2();
fragment2.setChangeFragmentListener(this);
initListeners();
}
void changeToFrag1() {
fragmentTransaction = getFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.activity_main_fragment_container,fragment1, "");
fragmentTransaction.commit();
}
void changeToFrag2() {
fragmentTransaction = getFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.activity_main_fragment_container, fragment2, "");
fragmentTransaction.commit();
}
#Override
public void onChangeFragmentLicked(int fragment) {
switch (fragment){
case 1:
changeToFrag1();
break;
case 2:
changeToFrag2();
break;
}
}
3) Create object from the interface to handle the callback:
public class Fragment1 extends Fragment {
private ChangeFragmentListener changeFragmentListener;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_fragment1, container, false);
view.findViewById(R.id.fragment1_textView).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
changeFragmentListener.onChangeFragmentLicked(2);
}
});
return view;
}
public Fragment1 setChangeFragmentListener(ChangeFragmentListener changeFragmentListener) {
this.changeFragmentListener = changeFragmentListener;
return this;
}
}
I have two activities in my app. In MainActivity I am loading 2 fragments Fragment1 and Fragment2. From Fragment1 i am jumping to Fragment2 and from Fragment2 I am jumping to Activity2 which contains Fragment2_1 From Fragment 2_1 I want to jump back to Fragment2 in MainActivity but I am getting an error when I try to do this.
I want to know is it possible to jump from 1 activity fragment to another activity fragment?
My code is:
MainActivity.java
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FragmentTransaction fragmentTransaction=getSupportFragmentManager().beginTransaction();
Fragment fragment1=new Fragment1();
fragmentTransaction.replace(R.id.mainContainer,fragment1,"MainActivity");
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}
}
Fragment1.java:
public class Fragment1 extends Fragment {
public Fragment1() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view=inflater.inflate(R.layout.fragment_fragment1, container, false);
Button buttonfrag1=(Button)view.findViewById(R.id.buttonfrag1);
buttonfrag1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
FragmentManager fragmentManager=getActivity().getSupportFragmentManager();
FragmentTransaction fragmentTransaction=fragmentManager.beginTransaction();
Fragment2 fragment2 = new Fragment2();
fragmentTransaction.replace(R.id.mainContainer,fragment2,"Fragment1");
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}
});
return view;
}
Fragment2.java
public class Fragment2 extends Fragment {
public Fragment2() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view= inflater.inflate(R.layout.fragment_fragment2, container, false);
Button buttonfrag2=(Button)view.findViewById(R.id.buttonfrag2);
buttonfrag2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent=new Intent(getActivity(),Activity2.class);
startActivity(intent);
}
});
return view;
}
}
Activity2.java
public class Activity2 extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_2);
FragmentTransaction fragmentTransaction=getSupportFragmentManager().beginTransaction();
Fragment2_1 fragment2_1=new Fragment2_1();
fragmentTransaction.replace(R.id.frag2_1,fragment2_1,"Activity2");
fragmentTransaction.commit();
}
}
Fragment2_1.java
public class Fragment2_1 extends Fragment {
public Fragment2_1() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view= inflater.inflate(R.layout.fragment_fragment2_1, container, false);
Button buttonfrag2_1=(Button)view.findViewById(R.id.buttonfrag2_1);
buttonfrag2_1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
FragmentTransaction fragmentTransaction=getFragmentManager().beginTransaction();
Fragment2 fragment2=new Fragment2();
fragmentTransaction.replace(R.id.mainContainer,fragment2,"frag2_1");
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}
});
return view;
}
}
All code works fine but when I want to move from Fragment2_1 to Fragment1 my app crashes with an exception :
java.lang.IllegalArgumentException: No view found for id 0x7f0b0059 (saleskit.orbitsys.com.fragmentdemo:id/mainContainer) for fragment Fragment2{29eb9c90 #1 id=0x7f0b0059 frag2_1}
try this: in Fragment2_1
buttonfrag2_1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(getActivity(), MainActivity.class);
intent.putExtra("frag", "fragment2");
startActivity(intent);
}
});
Now in Mainactivity onResume() load your desired fragment in maincontainer
in MainActivity
#Override
public void onResume(){
super.onResume();
Intent intent = getIntent();
if(intent.getExtras() != null)
{
String frag = intent.getStringExtra("frag");
}
switch(frag){
case "fragment2":
//here you can load Fragment2 to your activity as usual;
fragmentManager.beginTransaction().replace(R.id.mainContainer, new Fragment2()).commit();
break;
}
}
In your Fragment2_1 within your second activity you are trying to place Fragment2 in the container R.id.mainContainer. Your code below :
FragmentTransaction fragmentTransaction=getFragmentManager().beginTransaction();
Fragment2 fragment2=new Fragment2();
fragmentTransaction.replace(R.id.mainContainer,fragment2,"frag2_1");
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
But since you are currently inside your second activity that container doesn't exist (it is part of your first activity). You need to either load your your MainActivity again or finish Activity2 by calling finish(). If you do the later android will by itself take you back to your MainActivity and since you moved to Activity2 from Fragment2 android will also remember that and show you Fragment2.
Your Fragment2_1 should look like this:
public class Fragment2_1 extends Fragment {
public Fragment2_1() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view= inflater.inflate(R.layout.fragment_fragment2_1, container, false);
Button buttonfrag2_1=(Button)view.findViewById(R.id.buttonfrag2_1);
buttonfrag2_1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
getActivity().finish();
}
});
return view;
}
}
OR, If you just want to show Fragment2 in your second activity you can do something like this :
public class Fragment2_1 extends Fragment {
public Fragment2_1() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view= inflater.inflate(R.layout.fragment_fragment2_1, container, false);
Button buttonfrag2_1=(Button)view.findViewById(R.id.buttonfrag2_1);
buttonfrag2_1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
FragmentTransaction fragmentTransaction=getFragmentManager().beginTransaction();
Fragment2 fragment2=new Fragment2();
fragmentTransaction.replace(R.id.frag2_1,fragment2,"frag2");
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}
});
return view;
}
}
R.id.frag2_1 is the container where you need to replace the fragment.
Note that : You will still be in your second activity. Just the fragment will be replaced.
I could implement shared element transition between two fragments WITHOUT RECYCLERVIEW!!!
This is FirstFragment:
public class FirstFragment extends Fragment {
ImageView img_small;
LinearLayout layout_ofc_cities;
LinearLayout layout;
public FirstFragment() {
// Required empty public constructor
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_first, container, false);
img_small = (ImageView) view.findViewById(R.id.img_small);
layout_ofc_cities = (LinearLayout) view.findViewById(R.id.layout_ofc_cities);
layout = (LinearLayout) view.findViewById(R.id.layout);
layout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
setSharedElementReturnTransition(TransitionInflater.from(getActivity()).inflateTransition(R.transition.change_image_trans));
setExitTransition(TransitionInflater.from(getActivity()).inflateTransition(android.R.transition.fade));
SecondFragment secondFragment = new SecondFragment();
secondFragment.setSharedElementEnterTransition(TransitionInflater.from(getActivity()).inflateTransition(R.transition.change_image_trans));
secondFragment.setEnterTransition(TransitionInflater.from(getActivity()).inflateTransition(android.R.transition.fade));
FragmentTransaction ft = getFragmentManager().beginTransaction()
.replace(R.id.container, secondFragment)
.addToBackStack(null)
.addSharedElement(layout_ofc_cities, "transitionTxt")
.addSharedElement(img_small, "transitionImg");
ft.commit();
}
}
});
return view;
}
}
and this is SecondFragment:
public class SecondFragment extends Fragment {
public SecondFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_second, container, false);
return view;
}
}
And it works!
but when I implements a RecyclerView in FirstFragment to use SharedElementTransition for a LinearLayout and an ImageView of RecyclerView to a LinearLayout and an ImageView in SecondFragment it doesn't work.
I want a sample code with two Fragments that the first one has RecyclerView in it, with animation between their shared elements. Can anyone help me?
I found the answer:
the solution is on this page:
http://jemsdevmobile.com/2016/02/11/lollipop-transition-between-activities/
just you need to change xml tags. for example change "imageview" to "ImageView"