I have to move Detailfragment to GridActivity.Workflow for activity
is GridActivity ->HomeActivity->DetailFragment.
In GridActvity I am using an image button.On Click the image button I
had set the position to move HomeActivity onArticlelistener.
With this listener I can move to fragment using position.
GridActivity1.java:
int position;
........
........
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_tour:
Intent i1=new Intent(GridActivity1.this,MainActivity.class);
i1.putExtra("tour",2);
i1.putExtra("position", position);
startActivity(i1);
break;
}
}
MainActivity.java:
public class MainActivity extends ActionBarActivity implements OnTabChangeListener,ArticleSelectedListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.app_main_tab_fragment_layout);
posGrid= getIntent().getExtras().getInt("position");
switch(posGrid){
case 0:
int posTour = getIntent().getIntExtra("tour", 0);
articleSelected(posTour, "Tour Guide");
break;
}
}
#Override
public void onArticleSelected(int position, String content)
{
articleSelected(position, content);
}
public void articleSelected(int position, String content)
{
if(position==2)
{
action_bar_hometext.setText(content);
FragmentManager manager = getFragmentManager();
FragmentTransaction ft = manager.beginTransaction();
DetailFragment newFragment = new DetailFragment();
ft.replace(R.id.realtabcontent, newFragment);
ft.addToBackStack(null);
ft.commit();
}
}
DetailFragment.java:
public class TourGuideFirstFragment extends BaseFragment implements
OnItemClickListener {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.fragment_tour_guide, container,
false);
return view;
}
}
I don't need action bar back button.Because I am using navigation
drawer in fragments.
My issue is,when I click the hardware back button in DetailFragment I
need to move directly to GridActivity.Now it is moving to HomeActivity then it back to GridActivity.
You are adding a FragmentTransaction to the backstack, so in order to get rid of this you just have to remove the line from MainActivity
ft.addToBackStack(null);
After that it should work as you want it to work
Related
I've been developing an android app which I included the default Navigation-Drawer from Android Studio and so on. In my home fragment, I've implemented CarViews, and then set those cardview(s) OnClickListener to replace the fragment with traditional procedure.
After the fragment replacement and new page comes, I wanted to change the Actionbar title.
So in the onCreateView(...) method, I tried,
((AppCompatActivity)getActivity()).getSupportActionBar().setTitle("B");
It worked. But after pressing the hardware back button to go back to the stacked fragment, the title remains changed & it doesn't change to "Home" again. I've tried other ways. Here's my following codes. Thanks in advance.
public class HomeFragment extends Fragment implements View.OnClickListener {
public View onCreateView(#NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.fragment_home, container, false);
Objects.requireNonNull(((AppCompatActivity) Objects.requireNonNull(getActivity())).getSupportActionBar()).setTitle("Home");
CardView cardView1 = root.findViewById(R.id.doctor_on);
CardView cardView2 = root.findViewById(R.id.ambulance_e);
CardView cardView3 = root.findViewById(R.id.maintainance_s);
cardView1.setOnClickListener(this);
cardView2.setOnClickListener(this);
cardView3.setOnClickListener(this);
return root;
}
#Override
public void onClick(View v) {
int id = v.getId();
switch (id) {
case R.id.doctor_on:
FragmentTransaction fragmentTransaction = Objects.requireNonNull(getActivity()).getSupportFragmentManager().beginTransaction();
Fragment fragment1 = new doctors();
fragmentTransaction.replace(R.id.container1, fragment1).addToBackStack(getString(R.string.menu_home)).commit();
return;
case R.id.ambulance_e:
//Put Actions
FragmentTransaction fragmentTransaction2 = Objects.requireNonNull(getActivity()).getSupportFragmentManager().beginTransaction();
Fragment fragment2 = new ambulance();
fragmentTransaction2.replace(R.id.container1, fragment2).addToBackStack(getString(R.string.menu_home)).commit();
return;
case R.id.maintainance_s:
//Put Actions
FragmentTransaction fragmentTransaction3 = Objects.requireNonNull(getActivity()).getSupportFragmentManager().beginTransaction();
Fragment fragment3 = new maintanance();
fragmentTransaction3.replace(R.id.container1, fragment3).addToBackStack(getString(R.string.menu_home)).commit();
return;
}
}
#Override
public void onResume() {
super.onResume();
((AppCompatActivity) getActivity()).getSupportActionBar().setTitle("Home");
}
}
To the next fragment(where I change the titlebar and pressed back button):
public class doctors extend Fragment{
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
((AppCompatActivity)getActivity()).getSupportActionBar().setTitle("B");
View root = inflater.inflate(R.layout.fragment_doctors, container, false);
return root;
}
}
And in the doctors Fragment... Should fix the title error.
#Override
public void onDestroyView() {
super.onDestroyView();
Objects.requireNonNull(((AppCompatActivity) Objects.requireNonNull(getActivity()))
.getSupportActionBar())
.setTitle(getString(R.string.your_title_here));
}
You have to override the method onBackPressed() and write the code:
#Override
public View onBackPressed(){
//Here goes the code that head back to your main fragment
FragmentTransaction fragmentTransaction3 = Objects.requireNonNull(getActivity()).getSupportFragmentManager().beginTransaction();
Fragment fragment3 = new maintanance();
fragmentTransaction3.replace(R.id.container1, fragment3).addToBackStack(getString(R.string.menu_home)).commit();
}
}`
Add below code in Home Fragment...
#Override
public void onHiddenChanged(Boolean hidden) {
super.onHiddenChanged(hidden);
((AppCompatActivity) getActivity()).getSupportActionBar().setTitle("Home");
}
My MainActivity contain buttons which is used to switch to different fragments. Inside each fragment there are also has buttons. Activity button onClickListener work fine before implementing button onClickListener in fragments. I wonder if this is not supported by Android or my code is not correct.
Any pointer is appreciated. Thank you.
Fragment code:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
v = inflater.inflate(fragment1, container, false);
b2=(Button)v.findViewById(R.id.button2);
b2.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v){
button2Clicked(v);
}
});
return inflater.inflate(R.layout.fragment1, container, false);
}
public void button2Clicked(View view){
//do something
}
Activity code:
public class MainActivity extends FragmentActivity {
private Button btnHealth;
private Button btnSetting;
private Button btnSleep;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Init component
btnHealth = (Button) findViewById(R.id.btnHealth);
btnSleep = (Button) findViewById(R.id.btnSleep);
btnSetting = (Button) findViewById(R.id.btnSetting);
replaceFragment(1);
btnHealth.setOnClickListener(new AdapterView.OnClickListener(){
#Override
//On click function
public void onClick(View view) {
replaceFragment(0);
}
});
btnSleep.setOnClickListener(new AdapterView.OnClickListener(){
#Override
//On click function
public void onClick(View view) {
replaceFragment(1);
}
});
btnSetting.setOnClickListener(new AdapterView.OnClickListener(){
#Override
//On click function
public void onClick(View view) {
replaceFragment(2);
}
});
}
//Create method replace fragment
private void replaceFragment(int pos) {
Fragment fragment = null;
switch (pos) {
case 0:
fragment = new Fragment1();
break;
case 1:
fragment = new Fragment2();
break;
case 2:
fragment = new Fragment3();
break;
default:
fragment = new Fragment2();
break;
}
if(null!=fragment) {
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.replace(R.id.main_content, fragment);
transaction.addToBackStack(null);
transaction.commit();
}
}
}
It is possible. If you want to handle the OnClick Event of the fragment inside the Activity class, you can do so by using FragmentInteractionListener (interface). Example: Android - handle fragment onClick from activity
I have button in fragment1. I want to click this buttton and replace fragment1 by fragment2 but my app still close when I try to run it
This is my code in fragment1
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.layout_menu, container, false);
// gallery = (Gallery) rootView.findViewById(android.R.id.list);
//gallery.setAdapter(new ItemAdapter(generateData(), getActivity()));
Button button = (Button) rootView.findViewById(R.id.imageButtonAll);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
HomeFragment homeFragment = new HomeFragment();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.frame_container, homeFragment);
transaction.commit();
}
});
return rootView;
}
}
You cant open a fragment from inside another fragment.
So you have to move your code from the onClick to your activity and run it there.
In your Activity (lets assume its MainActivity):
public void openMyFragment(){
HomeFragment homeFragment = new HomeFragment();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.frame_container, homeFragment);
transaction.commit();
}
And then, add this in your fragments onClick:
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
((MainActivity) getActivity()).openMyFragement();
}
});
The problem is that you are trying to replace a view that does not exist within the view that you are inflating. You have to switch these fragments from your FragmentActivity, which has the contentview containing the layout you are trying to replace.
MainActivity:
class MainActivity extends FragmentActivity {
public Fragment frag1;
public Fragment frag2;
#Override
protected void onCreate(Bundle savedInstanceState) {
...
frag1 = new Frag1();
frag2 = new Frag2();
//assumption to switch to frag 1 immediately
switchToFragment(R.id.frame_container, homeFragment);
...
}
/** Switch UI to the given fragment (example) */
void switchToFragment(Fragment newFrag) {
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, newFrag)
.commitAllowingStateLoss();
currentFragment = newFrag;
}
}
Fragment:
....
final Activity activity = getActivity();
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
about.setTextColor(Color.WHITE);
if(activity instanceof MainActivity) {
((MainActivity) activity).switchToFragment(((MainActivity) activity).frag1));
}
}
});
...
I have akivity with one button and frame:
public class MyActivity extends Activity implements View.OnClickListener {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button replaceBtn = (Button) findViewById(R.id.replaceFragment);
replaceBtn.setOnClickListener(this);
}
#Override
public void onClick(View view) {
switch (view.getId()){
case R.id.replaceFragment:
Fragment fragment1 = new Frag1();
FragmentTransaction fTrans = getFragmentManager().beginTransaction();
fTrans.replace(R.id.contentFrame, fragment1);
**fTrans.addToBackStack(null);**
fTrans.commit();
break;
}
}
}
button is pressed, etc. I create a fragment:
public class Frag1 extends Fragment implements View.OnClickListener {
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.frag1, null);
Button replaceBtn2 = (Button) v.findViewById(R.id.replaceFragment2);
replaceBtn2.setOnClickListener(this);
return v;
}
#Override
public void onClick(View view) {
switch (view.getId()){
case R.id.replaceFragment2:
Frag2 fragment2 = new Frag2();
FragmentTransaction fTrans = getFragmentManager().beginTransaction();
fTrans.replace(R.id.contentFrame,fragment2);
**fTrans.addToBackStack(null);**
fTrans.commit();
break;
}
}
}
it also has a button which when pressed I create fragment2:
public class Frag2 extends Fragment implements View.OnClickListener {
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.frag2, null);
Button replaceBtn3 = (Button) v.findViewById(R.id.replaceFragment3);
replaceBtn3.setOnClickListener(this);
return v;
}
#Override
public void onClick(View view) {
switch (view.getId()){
case R.id.replaceFragment3:
Frag3 fragment3 = new Frag3();
FragmentTransaction fTrans = getFragmentManager().beginTransaction();
fTrans.replace(R.id.contentFrame,fragment3);
**//do not add backstack**
fTrans.commit();
break;
}
}
}
fragment2 also creates a new fragment3:
public class Frag3 extends Fragment{
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.frag3, null);
return v;
}
}
then later when I press the "back" button on the screen will appear the fragments in reverse order. but I want to when I'm in fragmente3 when you press the "back" appears immediately fragment1.
that is because you don't added the fragment2 to backstack. The fragment wont be pop back or disappear when they excluded from backstack. backstack runs exactly as activity back stack or any other stack container works.
to explain better:
added first fragment to stack
[stack] topElement Fragment1 (is showing)
added 2nd but did not add to the stack [stack] topElement
Fragment1(is not showing)
added 3rd fragment to stack [stack] topElement Fragment3(is
showing)
now if you pop it will return in this order : 3rd,1st and nothing more.
EDIT
in this case you can simply override the onBackPressed() like this to achieve the behaviour you want:
onBackPressed(){
//default back pressed behaviour
if(mFragmentManager.getBackStackEntryCount()==0)//you can set it ==1 if you wish to close
finish();
mFragmentManager.popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
}
I have a problem related to fragment life cycle.
Before doing this, I will set DONT KEEP ACTIVITY mode(Setting -> Developer options).
In my project have 2 activity:
Activity 1: keep and control Fragment A and Fragment B
Activity 2: do not have fragment.
Activity 1 will be called first, then Fragment A and Fragment B will be called to visible.
Start Activity 2 from Activity 1, this cause Activity 1 will be destroyed and Fragment A & Fragment B will be destroyed too (Because of dont keep activity mode).
Press back key from Activity 2 to back Activity 1
Problem occurs here: Fragment A and Fragment B will be automatically called onCreateView() after back from activity 2 -> I want to avoid this. Can you give me some tips to resolve it?
Update Code
Activity 1
public class MainActivity extends Activity implements OnClickListener {
private Button mBtnShowFragmentA;
private Button mBtnShowFragmentB;
private Button mBtnGoAcitivity2;
protected String mCurrentFragmentTag;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_activity_1);
mBtnShowFragmentA = (Button) findViewById(R.id.btn_show_fragmentA);
mBtnShowFragmentB = (Button) findViewById(R.id.btn_show_fragmentB);
mBtnGoAcitivity2 = (Button) findViewById(R.id.btn_go_activity2);
mBtnShowFragmentA.setOnClickListener(this);
mBtnShowFragmentB.setOnClickListener(this);
mBtnGoAcitivity2.setOnClickListener(this);
}
#Override
protected void onDestroy() {
super.onDestroy();
}
protected void addFragment(int contentId, Fragment fragment, boolean isAddStack,
String stackName) {
FragmentManager fm = getFragmentManager();
String newFragment = fragment.getClass().getName();
FragmentTransaction ft = fm.beginTransaction();
Fragment currentFragment = fm.findFragmentByTag(mCurrentFragmentTag);
if (currentFragment != null && !TextUtils.equals(currentFragment.getTag(), newFragment)) {
ft.hide(currentFragment);
}
if (fm.findFragmentByTag(newFragment) != null) {
fragment = (Fragment) fm.findFragmentByTag(newFragment);
}
if (!fragment.isAdded()) {
ft.add(contentId, fragment, newFragment);
} else {
ft.show(fragment);
}
if (isAddStack) {
ft.addToBackStack(stackName);
}
try {
ft.commitAllowingStateLoss();
} catch (Exception e) {
}
mCurrentFragmentTag = newFragment;
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_show_fragmentA:
FragmentA fragmentA = new FragmentA();
addFragment(R.id.activity_main_content, fragmentA, false, null);
break;
case R.id.btn_show_fragmentB:
FragmentB fragmentB = new FragmentB();
addFragment(R.id.activity_main_content, fragmentB, false, null);
break;
case R.id.btn_go_activity2:
Intent intent = new Intent(getApplicationContext(), SettingActivity.class);
startActivity(intent);
break;
default:
break;
}
}
}
Fragment A
public class FragmentA extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.layout_fragment_a, container, false);
return view;
}
}
Fragment B
public class FragmentB extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.layout_fragment_b, container, false);
return view;
}
}
Activity 2
public class SettingActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_activity_2);
}
#Override
protected void onDestroy() {
super.onDestroy();
}
#Override
public void onBackPressed() {
super.onBackPressed();
}
}
...................
Use below code to remove activity from stack.
FragmentManager fragmentManager = getSupportFragmentManager();
if (fragmentManager .getBackStackEntryCount() > 0) {
fragmentManager .popBackStack();
}