How to add/remove Fragment on Button click? - java

At present I have got a "RELATIVE_LAYOUT" container which I am using for adding my fragment.
I am using OnClickListener on a button to load the fragment XML layout into the RelativeLayout container.
What I want to achieve is that when I press the button once, the fragment should load...and when I press it again the fragment should be removed. I've already tried using integer to identify if fragment is loaded, but failed.
Any help Appreciated...
CODE:
public class MainActivity extends Activity {
Button B1,B2;
int boolb1=0, boolb2=0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
B1 = (Button)findViewById(R.id.btn1);
B2 = (Button)findViewById(R.id.btn2);
B1.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
FragmentOne f1 = new FragmentOne();
if(boolb1==0)
{ft.add(R.id.frg1, f1);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
boolb1=1;}
else
{ft.remove(f1);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_CLOSE);
boolb1=0;}
//ft.addToBackStack("f1");
ft.commit();
}
});
B2.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
FragmentTwo f2 = new FragmentTwo();
if(boolb2==0) {
ft.add(R.id.frg2, f2);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
boolb2=1;
} else {
ft.remove(f2);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_CLOSE);
boolb2=0;
}
//ft.addToBackStack("f2");
ft.commit();
}
});
}

Your issue is that you create a new Fragment everytime you click the Button. You need to get a reference to the currently added Fragment and then remove that one.
Furthermore, you no longer need to use the flag.
When adding the Fragment, you can tag it. Upon removing the Fragment, you can use the tag used for adding the Fragment to get a reference to the currently added Fragment.
Here is an example of how you should do it:
private Button B1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
B1 = (Button)findViewById(R.id.btn1);
B1.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
FragmentOne f = (FragmentOne) fm.findFragmentByTag("tag");
if(f == null) { // not added
f = new FragmentOne();
ft.add(R.id.frg1, f, "tag");
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
} else { // already added
ft.remove(f);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_CLOSE);
}
ft.commit();
}
});
// and so on ...
}

Related

How to Save the last Fragment?

I have three Fragments and I have two buttons on main Activity b1 called next button and b2 called previous button when app is starting its show me blank Fragment , when click on b1 its show me XFragment called page 1 ,when click on b1 its show me YFragment called page 2 , I want when re-open app its show me the last Fragment has been opend ,I know should use shareprefrences but I dont know how to add it to this code
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void b1(View view) {
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
XFragment fragment = new XFragment();
ft.replace(R.id.mainfragment,fragment);
ft.commit();
}
public void b2(View view) {
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
YFragment fragment = new YFragment();
ft.replace(R.id.mainfragment,fragment);
ft.commit();
}
}
Below is your required code using SharedPreference.
public class MainActivity extends AppCompatActivity {
SharedPreference pref;
Editor editor;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
pref = getApplicationContext().getSharedPreferences("MyPref", 0);
editor = pref.edit();
int fragment_number=pref.getInt("fragment_number", -1); // getting Integer
if(int==1){
//start first fragment
}
if(int==2){
//start second fragment
}
}
public void b1(View view) {
editor.putInt("fragment_number", 1);
editor.apply();
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
XFragment fragment = new XFragment();
ft.replace(R.id.mainfragment,fragment);
ft.commit();
}
public void b2(View view) {
editor.putInt("fragment_number", 2);
editor.apply();
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
YFragment fragment = new YFragment();
ft.replace(R.id.mainfragment,fragment);
ft.commit();
}
}

how to manage new FrameLayout in the second activity based onClicklistener in fragment?

I'm doing android project implementing fragment and get a trouble.
here is the trouble story:
I've created Main activity which is hold the fragment using Fragment Layout. I do this because i want to implement navigation menu using drawer menu. It works fine for all these steps.
here is the code:
public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {
private DrawerLayout drawer;
private Toolbar toolbar;
private NavigationView navigationView;
private ActionBarDrawerToggle toggle;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
drawer = findViewById(R.id.layout_drawer);
navigationView = findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
toggle = new ActionBarDrawerToggle(this,drawer,toolbar,
R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.addDrawerListener(toggle);
toggle.syncState();
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,
new Main_fragment()).commit();
navigationView.setCheckedItem(R.id.home);
}
}
it works fine until here.
Then in the fragment activity, i triggered a Textview and invoke new activity. i do that because i want to make a new Place Holder for the fragments and put different Drawer Menu.
her is the code:
public class Main_fragment extends Fragment{
TextView t1,t2,t3,t4,t5,t6,t7;
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable final Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.main_fragment,container,false);
//define buttons
t1 = (TextView) v.findViewById(R.id.txt1);
t2 = (TextView) v.findViewById(R.id.txt2);
t3 = (TextView) v.findViewById(R.id.txt3);
t4 = (TextView) v.findViewById(R.id.txt4);
t5 = (TextView) v.findViewById(R.id.txt5);
t6 = (TextView) v.findViewById(R.id.txt6);
t7 = (TextView) v.findViewById(R.id.txt7);
t1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//intent to the second activity
Intent i = new Intent(getActivity(), Social_Container.class);
startActivity(i);
}
});
t2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(getActivity(), Social_Container.class);
startActivity(i);
}
});
t3.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(getActivity(), Social_Container.class);
startActivity(i);
}
});
t4.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(getActivity(), Social_Container.class);
startActivity(i);
/**
//this code just for trial fragment
FragmentTransaction fr = getFragmentManager().beginTransaction();
fr.replace(R.id.fragment_container, new Fragment_Pengurusan());
fr.commit();
**/
}
});
t5.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(getActivity(), Social_Container.class);
startActivity(i);
/**
FragmentTransaction fr = getFragmentManager().beginTransaction();
fr.replace(R.id.fragment_container, new Fragment_Politic());
fr.commit();
**/
}
});
t6.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(getActivity(), Social_Container.class);
startActivity(i);
/**
FragmentTransaction fr = getFragmentManager().beginTransaction();
fr.replace(R.id.fragment_container, new Fragment_Industri());
fr.commit();
**/
}
});
t7.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(getActivity(), Social_Container.class);
startActivity(i);
/**
FragmentTransaction fr = getFragmentManager().beginTransaction();
fr.replace(R.id.fragment_container, new Fragment_Awam());
fr.commit();
**/
}
});
return v;
}
}
the question is, how can i triggered the fragment activity to be set on the second class place holder (FrameLayout) based onCLick that i set on the Textview that i attached in the last Fragment activity which is inside the Main Activity?
note: I didn't set anything inside the second class yet. I just want to know how to invoke the fragment inside that Second Class based onClickListener from TextView there.

Android - NullPointerException in Fragment after callback

This is the first time I work with Fragments and I don't understand very well how to manage them. In this case I have two fragments that I show dinamically in a FrameLayout with id fragment_place. The issue is probably with the fragmentTransaction(addtobackstack / popbackstack).
In Fragment2 I show a popupmenu when I press the menubutton on the mobile and it works as expected the first time, but after I go back to the previous fragment and return to fragment2 now If I press the menubutton I get the following error
java.lang.NullPointerException
at android.support.v7.view.menu.MenuBuilder.<init>(MenuBuilder.java:216)
at android.support.v7.widget.PopupMenu.<init>(PopupMenu.java:103)
at android.support.v7.widget.PopupMenu.<init>(PopupMenu.java:78)
at android.support.v7.widget.PopupMenu.<init>(PopupMenu.java:63)
at package.Fragment2.showPopup(Fragment2.java:93)
Below is the code for the mainactivity and fragment2, this is driving me crazy, any help will be much appreciated.
public class MainActivity extends AppCompatActivity implements Fragment1.onEvent {
Fragment1 frag;
Fragment2 frag2;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
frag = new Frag1();
// Begin the transaction
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.fragment_place, frag);
ft.commit();
}
#Override
public void onEventSelected(String key) {
frag2 = new Frag2();
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.fragment_place,frag2);
ft.addToBackStack(null);
ft.commit();
}
#Override
public void onBackPressed(){
FragmentManager ft = getSupportFragmentManager();
if (ft.getBackStackEntryCount() > 0) {
ft.popBackStack();
} else {
super.onBackPressed();
}
}
#Override
public boolean dispatchKeyEvent(KeyEvent event) {
int action = event.getAction();
int keyCode = event.getKeyCode();
switch (keyCode) {
case KeyEvent.KEYCODE_MENU:
if (action == KeyEvent.ACTION_UP) {
Fragment f = getSupportFragmentManager().findFragmentById(R.id.fragment_place);
if (f instanceof Fragment2) {
sendBroadcast();
}
}
return true;
default:
return super.dispatchKeyEvent(event);
}
}
private void sendBroadcast(){
Intent intent = new Intent("popup_menu");
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}}
This is the problematic fragment. The error lines are basically the method showPopup
public class Fragment2 extends Fragment {
private String key;
private View view;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment, parent, false);
LocalBroadcastManager.getInstance(getActivity()).registerReceiver(mMessageReceiver,
new IntentFilter("popup_menu"));
return view;
}
private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
showPopup(view);
}
};
public void showPopup(View v) {
Button b = (Button) view.findViewById(R.id.b_attach);
PopupMenu popup = new PopupMenu(getActivity(), b);
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
//dosomething
}
});
MenuInflater inflater = popup.getMenuInflater();
inflater.inflate(R.menu.menu_popup, popup.getMenu());
popup.show();
}}
this is the way i do and it works for me:
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction().replace(R.id.content_frame,new fragment() ).commit();
I solved the issue getting rid of sendbroadcast() and broadcastReceiver(), instead of that now I call showPopup() directly from the mainActivity when I need it.

ListFragment called from Button

This batch of code will place a ListFragment into a LinearLayout that I have selected, and it works fine. The problem I have is that this initiates from onCreate and I would like it to trigger from a Button.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TamInputListFragment lstfragment=(TamInputListFragment)getSupportFragmentManager().findFragmentByTag("lstfragment");
if(lstfragment==null){
lstfragment=new TamInputListFragment();
FragmentTransaction transact=getSupportFragmentManager().beginTransaction();
transact.add(R.id.fragment_container,lstfragment,"lstfragment");
transact.commit();
}
This batch of code worked for a previous tutorial that just interchanged two simple Fragment with two separate Button.
public void selectFrag(View view){
Fragment fr;
if (view == findViewById(R.id.button2)) {
fr = new FragmentTwo();
}
else {
fr = new FragmentOne();
}
FragmentManager fm = getFragmentManager();
FragmentTransaction fragmentTransaction = fm.beginTransaction();
fragmentTransaction.replace(R.id.fragment_place, fr);
fragmentTransaction.commit();
}
But when I use this same batch of code and swap out FragmentOne() and FragmentTwo() for the two new ListFragment classes that I have made, TamInputListFragment and VerbInputListFragment, I get an "Incompatible Type" error saying that is wants a android.app.Fragment and not a com.example.petakirikiri.fragmenttest.Fragments.TamInputListFragment();
public void selectFrag(View view){
Fragment fr;
if (view == findViewById(R.id.verb_button) {
fr = new TamInputListFragment();
}
else {
fr = new VerbInputListFragment();
}
FragmentManager fm = getFragmentManager();
FragmentTransaction fragmentTransaction = fm.beginTransaction();
fragmentTransaction.replace(R.id.fragment_container, fr);
fragmentTransaction.commit();
}

SlidingMenu with ViewPager and ActionBarSherlock Tabs

In my calendar application, I am using ActionBarSherlock to display two tabs - 1) Calendar 2) Converter. On the click event of an ActionBar menu item, I'm using SlidingMenu drawer to display event summary for that month.
I want to use viewpager specifically for the Calendar tab and I have implemented it this way:
Main.java:
public class BaseActivity extends SlidingSherlockFragmentActivity
{
private ViewPager pager;
CalendarFragmentPagerAdapter mPagerAdapter;
private static final int MONTHS_LIMIT = 5;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setTitle(R.string.app_name);
setContentView(R.layout.main);
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.main, new CalendarFragment())
.commit();
setBehindContentView(R.layout.content_frame);
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.content_frame, new EventsSummary())
.commit();
setSlidingActionBarEnabled(false);
final ActionBar bar = getSupportActionBar();
bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
bar.setHomeButtonEnabled(true);
ActionBar.Tab calendar = bar.newTab();
ActionBar.Tab converter = bar.newTab();
calendar.setText(this.getResources().getString(R.string.calendar));
converter.setText(this.getResources().getString(R.string.converter));
calendar.setTabListener(new MyTabListener());
converter.setTabListener(new MyTabListener());
bar.addTab(calendar);
bar.addTab(converter);
// customize the SlidingMenu
SlidingMenu sm = getSlidingMenu();
sm.setShadowWidthRes(R.dimen.shadow_width);
sm.setShadowDrawable(R.drawable.shadow);
sm.setBehindOffsetRes(R.dimen.actionbar_home_width);
sm.setSlidingEnabled(false);
mPagerAdapter = new CalendarFragmentPagerAdapter(getSupportFragmentManager());
pager = (ViewPager) this.findViewById(R.id.viewpager);
pager.setAdapter(mPagerAdapter);
pager.setCurrentItem(MONTHS_LIMIT / 2);
}
private class MyTabListener implements ActionBar.TabListener
{
#Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
if(tab.getPosition()==0)
{
CalendarFragment frag = new CalendarFragment();
ft.replace(R.id.main, frag);
}
else
{
ConverterFragment frag = new ConverterFragment();
ft.replace(R.id.main, frag);
}
}
#Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
// TODO Auto-generated method stub
}
#Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
// TODO Auto-generated method stub
}
}
public boolean onOptionsItemSelected(MenuItem item) {
Intent newActivity;
// Handle item selection
switch (item.getItemId()) {
case R.id.menu_slidingmenu:
toggle();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
public class CalendarFragmentPagerAdapter extends FragmentPagerAdapter {
public CalendarFragmentPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
CalendarFragment fragment = new CalendarFragment();
Bundle args = new Bundle();
args.putInt("offset", position - MONTHS_LIMIT / 2);
fragment.setArguments(args);
return fragment;
}
#Override
public int getCount() {
return MONTHS_LIMIT;
}
}
}
CalendarFragment.java:
public class CalendarFragment extends Fragment
{
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle args = getArguments();
int offset = args.getInt("offset"); //throws NullPointerException
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.simple_calendar_view, container, false);
.....
return v;
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putBoolean("dummy", true);
}
}
The problem is at this line in the CalendarFragment:
int offset = args.getInt("offset");
It throws the error NullPointerException and debugging shows this is because Bundle args = getArguments() is null.
I tried to put the breakpoint at this line in the PagerAdapter:
Bundle args = new Bundle();
but it never reaches here and the application crashes throwing the NullPointerException.
Where am I going wrong?
Here
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.main, new CalendarFragment())
.commit();
and here
#Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
if (tab.getPosition() == 0) {
CalendarFragment frag = new CalendarFragment();
ft.replace(R.id.main, frag);
} else {
ConverterFragment frag = new ConverterFragment();
ft.replace(R.id.main, frag);
}
}
you're just creating an empty CalendarFragment instance without any arguments.
So your activity launches, creating an empty Fragment without arguments, and then crashes when trying to get those

Categories