android: ViewPager throwing null pointer - android

I have an application with multiple fragments.
My first fragment is HomeFragment where I am using viewpager and recycler view.
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_home, container, false);
ButterKnife.bind(this, view);
((AppCompatActivity) getActivity()).getSupportActionBar().setTitle(Constant.HOME_TITLE);
// view Pager
mPager = (ViewPager) view.findViewById(R.id.pager);
// recycler view
rv_transactions.setHasFixedSize(true);
LinearLayoutManager mLayoutmanager = new LinearLayoutManager(getContext());
rv_transactions.setLayoutManager(mLayoutmanager);
}
In HomeFragment's onStart I am doing network call using asyncTask. On compltion of asynctask I have a callback onTaskComplete() where I am setting my list and pager
public void onTaskComplete(JSONObject response){
// some jsonparsing logic, then
TransactionRecyclerViewAdapter adapter = new TransactionRecyclerViewAdapter(cardInfoAndTransactionArrayList.get(0).getTransactions());
Log.d("rv_adapter",""+cardInfoAndTransactionArrayList.get(0).getTransactions());
rv_transactions.setAdapter(adapter);
mPagerAdapter = new MultipleCardPagerAdapter(getChildFragmentManager(), cardInfoAndTransactionArrayList);
Log.d("ArrayList size",""+cardInfoAndTransactionArrayList.size());
Log.d("mPagerAdapter",""+mPagerAdapter);
Log.d("mPager",""+mPager);
mPager.setAdapter(mPagerAdapter);
mPager.addOnPageChangeListener(this);
}
Then there is one fragmentBy the name IgFragment from where I am coming back to HomeFragment
android.support.v4.app.FragmentManager fManager = getActivity().getSupportFragmentManager();
Boolean isPoped = fManager.popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
HomeFragment homeFragment = HomeFragment.newInstance(mobileNumber, "");
FragmentTransaction transaction = fManager.beginTransaction();
transaction.replace(R.id.fragment_container, homeFragment);
transaction.commit();
The flow of app is like HomeFragment --> 1st Frag --> 2nd Frag -->IGFragment --> HomeFragment and I am adding 1 & 2 to addToBackStack(null) to have back button navigation but at IGFragment I am clearing the back stack because I don't want any back navigation behaviour when I am at homeFragment but clearing backstack makes viewPager throw nullpointer exception
logcat output (before exception thrown)
ArrayList size: 2
/mPagerAdapter: com.example.worldline.adapters.MultipleCardPagerAdapter#36efdd11
/mPager: android.support.v4.view.ViewPager{5a27e76 VFED.... ......ID 0,0-1080,486 #7f0f00f8 app:id/pager}
logcat Output (Exception thrown at mPager.setAdapter(mPagerAdapter);)
java.lang.NullPointerException: Attempt to invoke virtual method 'int java.util.ArrayList.size()' on a null object reference
If I dont clear back stack everything works fine but HomeFragment shows multiple fragments one above other on press of back button (but no exception from viewpager) but if I clear backstack it throws null pointer even though arraylist have size 2(logact output printed just before setting adapter to viewpager)
MultipleCardPagerAdapter code
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.PagerAdapter;
import com.example.worldline.pojo.CardInfoAndTransactionsPojo;
import com.example.worldline.r_cug.MultipleCardViewPagerFragment;
import java.util.ArrayList;
/**
* Created by sunny.birman on 28-10-2016.
*/
public class MultipleCardPagerAdapter extends FragmentStatePagerAdapter {
private ArrayList<CardInfoAndTransactionsPojo> cardDetails;
private int cardListLength;
public MultipleCardPagerAdapter(FragmentManager fm, ArrayList<CardInfoAndTransactionsPojo> list) {
super(fm);
this.cardDetails= list;
cardListLength = list.size();
}
#Override
public Fragment getItem(int position) {
return MultipleCardViewPagerFragment.newInstance(cardDetails.get(position).getCardNumber(),cardDetails.get(position).getCardBalance(),position,cardListLength);
}
#Override
public int getCount() {
return cardDetails.size();
}
#Override
public int getItemPosition(Object object) {
return PagerAdapter.POSITION_NONE;
}
}

Related

How to access the host fragment from ViewPager page fragment using Navigation Architecture Components

I've a project that I want to migrate to Navigation Architecture Components.
Before the migration, I have an activity that has a fragment that hosts a ViewPager; and I can access a method in this fragment from the ViewPager adapter fragment by referencing the host fragment tag that I had set in the fragment transaction:
MyFragment fragment = (MyFragment ) ((MyActivity) requireActivity())
.getSupportFragmentManager().findFragmentByTag("fragment_tag");
fragment.someMethodInMyFragment();
Here is a diagram that deceits a part of the migration, and what I need to access through the yellow arrow:
In Navigation components, I didn't find a chance to set a tag to the destination fragment that hosts the ViewPager, so that I can access it through the tag like before. Also, the ViewPager adapter fragments are not a part of the Navigation components.
What I have tried: In the ViewPager adapter fragment:
Attempt 1
MyFragment fragment = (MyFragment) getParentFragment(); // This returns the navigation host fragment. So ClassCastException is raised
fragment.someMethodInMyFragment();
Attempt 2
MyFragment fragment = (MyFragment) requireActivity().getSupportFragmentManager()
.findFragmentById(R.id.myFragment); // id of myFragment in the nav graph.
fragment.someMethodInMyFragment(); // fragment is null
UPDATE:
posting ViewPager adapter
public class PageFragmentPagerAdapter extends FragmentStatePagerAdapter {
public PageFragmentPagerAdapter(FragmentManager fm) {
super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
}
#NonNull
#Override
public Fragment getItem(int position) {
return MyPagerFragment.newInstance(position);
}
#Override
public int getCount() {
return 10;
}
}
And I setup the ViewPager in MyFragment like below
public class MyFragment extends Fragment {
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
ViewPager viewPager = view.findViewById(R.id.viewpager);
PageFragmentPagerAdapter adapter = new PageFragmentPagerAdapter(requireActivity()
.getSupportFragmentManager());
viewPager.setAdapter(adapter);
}
Your problem is that you are using requireActivity().getSupportFragmentManager() as the FragmentManager for your adapter.
Instead, you should always use getChildFragmentManager() for Fragments that are fully contained within another fragment - you'll note that under configuration changes or process death and recreation, this is required to restore the state of each Fragment correctly.
When you use the child FragmentManager, then requireParentFragment() will return the correct fragment that you're looking for.

Custom Adapter Cannot be applied in navigation drawer's fragment

I want to display custom listview in navigation drawer's fragment page. However, in my fragment class, I'm getting an error which seems I cannot set a custom adapter.
package android_gcm_client.mynavigation;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;
import java.util.ArrayList;
public class List_Fragment extends Fragment {
View rootview;
ArrayList prgmName;
public static int [] prgmImages= {R.drawable.images,R.drawable.images1,R.drawable.images2,R.drawable.images3,R.drawable.images4,R.drawable.images5,R.drawable.images6,R.drawable.images7,R.drawable.images8};
public static String [] prgmNameList={"Let Us C","c++","JAVA","Jsp","Microsoft .Net","Android","PHP","Jquery","JavaScript"};
#Nullable
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
rootview=inflater.inflate(R.layout.custom_layout,container,false);
CustomAdapter ca = new CustomAdapter(this,prgmNameList,prgmImages);
ListView listview=(ListView) getView().findViewById(R.id.listView);
listview.setAdapter(ca);
return rootview;
}
}
It seems the error happens in line below (custom adapter can not be applied).
CustomAdapter ca = new CustomAdapter(this,prgmNameList,prgmImages);
In MainActivity I call the fragment as follows:
public void onNavigationDrawerItemSelected(int position) {
// update the main content by replacing fragments
Fragment objFragment=null;
switch(position) {
case 0:
objFragment=new ListFragment();
break;
}
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.container, objFragment)
.commit();
}
I tried different ways to display custom listview for navigation item selected method.
I tried to directly call activity instead of fragment but problem was navigation drawer not visible for all activity. So I tried to call CustomAdapter in activity as I'm doing in fragment.
I have struggle to solve this error. (Sorry for bad English).
You are using this in custom adapter. Usually adapters wants a Context in constructor call. But this constructor is called inside a fragment and this can't be used.
You can use getActivity() as Context inside a Fragment. But.
Sometimes it can return a null if it is called before onAttach() of this fragment.
CustomAdapter ca = new CustomAdapter(getActivity(), prgmNameList, prgmImages);
Also you can use Application context by creating static variable inside your Application class:
public class Application extends android.app.Application {
public static Context AppContext = null;
#Override
public void onCreate() {
super.onCreate();
AppContext = getApplicationContext();
// You can use this line to solve styling problems
// because Manifest android:theme is not working
AppContext.setTheme(R.style.AppTheme);
}
}
and create adapter like this:
CustomAdapter ca = new CustomAdapter(Application.AppContext, prgmNameList, prgmImages);

One Activity, multiple Fragments and setRetainInstance

in my app I'm using one activity and two fragments. The app uses a layout with a container so the fragments are added via transactions. The first fragment contains a listview and the other fragment a detail view for the listview items.
Both fragments use setRetainInstance(true). The fragments are added via a replace transaction and addToBackStack(null) is set. The listfragment contains an instance variable which holds some infos for the list. Now I'm changing to detail and press back and the instance variable is null. I read about setRetainInstance and addToBackStack and removed addToBackStack, but even then the instance variable is null.
Does anyone know what I might be doing wrong?
regards,
Thomas
setRetainInstance(true) will tell the FragmentManager to keep the fragment around when the containing Activity is killed and rebuilt for some reason. It doesn't guarantee that the Fragment instance will stick around after a transaction to add or replace. It sounds like your adapter is being garbage collected and you're not creating a new one.
A more generally easy solution would be to make a viewless Fragment to retain your ListAdapter. The way you do this is to create the Fragment, set the retain instance to true, and return null in the method onCreateView(). To add it, just called addFragment(Fragment, String) via the FragmentTransaction. You never remove or replace it, so it will always stay in memory for the length of the app. Screen rotations won't kill it.
Whenever your ListFragment is created, in onCreateView() get the FragmentManager and use either the method findFragmentById() or FindFragmentByTag() to retrieve your retained fragment from memory. Then get the adapter from that fragment and set it as your adapter for the list.
public class ViewlessFragment extends Fragment {
public final static string TAG = "ViewlessFragment";
private ListAdapter mAdapter;
#Override
public ViewlessFragment() {
mAdapter = createAdater();
setRetainInstance(true);
}
#Override
public void onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return null;
}
public ListAdapter getAdapter() {
return mAdapter;
}
}
public class MyListFragment extends ListFragment {
final public static String TAG = "MyListFragment";
#Override
public void onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final View returnView = getMyView();
final ViewlessFragment adapterFragment = (ViewlessFragment) getFragmentManager().findFragmentByTag(ViewlessFragment.TAG);
setListAdapter(ViewlessFragment.getAdapter());
return returnView;
}
}
public class MainActivity extends FragmentActivity {
#Override
public void onCreate(Bundle icicle) {
// ... setup code...
final FragmentManager fm = getSupportFragmentManager();
final FragmentTransaction ft = fm.beginTransaction();
ViewlessFragment adapterFragment = fm.findFragmentByTag(ViewlessFragment.TAG);
if(adapterFragment == null) {
ft.add(new ViewlessFragment(), ViewlessFragment.TAG);
}
ft.add(R.id.fragmentContainer, new MyListFragment(), MyListFragment.TAG);
ft.commit();
}
}

Action items from Viewpager initial fragment not being displayed

In the application I am developing I am using a ViewPager with fragments and each fragment constructs its own menu independently of all of the other fragments in the ViewPager.
The issue is that sometimes the fragments that are initialised by the ViewPager by default (i.e in it's initial state) are not having their items populated into the action items menu. What's worse is that this issue only occurs intermittently. If I swipe through the ViewPager enough so that the fragments are forced to re-initialise them selves, when I swipe back, the menu populates correctly.
Activity code:
package net.solarnz.apps.fragmentsample;
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentManager;
import android.os.Bundle;
import android.support.v13.app.FragmentStatePagerAdapter;
import android.support.v4.view.ViewPager;
public class FragmentSampleActivity extends Activity {
private ViewPagerAdapter mViewPagerAdapter;
private ViewPager mViewPager;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
if (mViewPagerAdapter == null) {
mViewPagerAdapter = new ViewPagerAdapter(getFragmentManager());
}
mViewPager = (ViewPager) findViewById(R.id.log_pager);
mViewPager.setAdapter(mViewPagerAdapter);
mViewPager.setCurrentItem(0);
}
private class ViewPagerAdapter extends FragmentStatePagerAdapter {
public ViewPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public int getCount() {
return 8;
}
#Override
public Fragment getItem(int position) {
Fragment f = Fragment1.newInstance(position);
// f.setRetainInstance(true);
f.setHasOptionsMenu(true);
return f;
}
}
}
Fragment code:
package net.solarnz.apps.fragmentsample;
import android.app.Fragment;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
public class Fragment1 extends Fragment {
int mNum;
static Fragment newInstance(int num) {
Fragment1 f = new Fragment1();
// Supply num input as an argument.
Bundle args = new Bundle();
args.putInt("num", num);
f.setArguments(args);
return f;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
mNum = getArguments() != null ? getArguments().getInt("num") : 0;
}
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.menu_list, menu);
}
}
Layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<android.support.v4.view.ViewPager
android:id="#+id/log_pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
Menu:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+id/menu_refresh"
android:title="Refresh"
android:icon="#android:drawable/ic_delete"
android:showAsAction="ifRoom|withText" />
</menu>
Action menu being populated:
http://i.stack.imgur.com/QFMDd.png
Action menu not being populated:
http://i.stack.imgur.com/sH5Pp.png
You should read this (by xcolw...)
Through experimentation it seems like the root cause is invalidateOptionsMenu getting called more than one without a break on the main thread to process queued up jobs. A guess - this would matter if some critical part of menu creation was deferred via a post, leaving the action bar in a bad state until it runs.
There are a few spots this can happen that aren't obvious:
calling viewPager.setCurrentItem multiple times for the same item
calling viewPager.setCurrentItem in onCreate of the activity. setCurrentItem causes an option menu invalidate, which is immediately followed by the activity's option menu invalidate
Workarounds I've found for each
Guard the call to viewPager.setCurrentItem
if (viewPager.getCurrentItem() != position)
viewPager.setCurrentItem(position);
Defer the call to viewPager.setCurrentItem in onCreate
public void onCreate(...) {
...
view.post(new Runnable() {
public void run() {
// guarded viewPager.setCurrentItem
}
}
}
After these changes options menu inside the view pager seems to work as expected. I hope someone can shed more light into this.
source http://code.google.com/p/android/issues/detail?id=29472
The simple answer is to not use menus within fragments in the ViewPager.
If you do need to use menus within the fragments, what I suggest is loading the menu's through the onCreateOptionsMenu method in the parent Activity. Obviously you will need to be able to determine which menu to show.
I was able to achieve this by using class reflection.
You will also need to use the invalidateOptionsMenu method each time you switch pages. You will need a OnPageChangeListener to call this when the ViewPager changes pages.
I also had same issue. In my case I have one activity with viewpager that contains two fragments, every fragment inflate its own action menu but fragment actions menu not shown.
View pager adapter code
public class ScreensAdapter extends FragmentPagerAdapter {
public TrackerScreensAdapter(Context context, FragmentManager fm) {
super(fm);
}
#Override
public int getCount() {
return 2;
}
public Fragment getItem(int position) {
Fragment fragment = null;
switch (position){
case 0:
fragment = new Fragment1();
break;
case 1:
fragment = new Fragment2();
break;
}
return fragment;
}
}
Activity on create
screensAdapter = new ScreensAdapter(this, getFragmentManager());
viewPager.setAdapter(screensAdapter);
This way my viewPager has two fragments, every fragment fire its own task in onActivityCreated, obtain data and draw its layout based on obtained data. Also every fragment has onCreateOptionsMenu
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setHasOptionsMenu(true);
MyTask task = new MyTask();
task.setTaskListener(this);
task.execute();
}
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.fragment_menu, menu);
}
Spent many times to solve this problem and figure out why fragment menu not shows.
All that I was need is
screenAdapter = new ScreenAdapter(this, getFragmentManager());
viewPager.post(new Runnable() {
public void run() {
viewPager.setAdapter(screenAdapter);
}
});
In my case I traced the root cause of the issue to what I believe is a bug in FragmentStatePagerAdapter which is calling Fragment#setMenuVisibility to false and failing to properly set it back to true when it restores it's state.
Workarounds:
Use FragmentPagerAdapter instead of FragmentStatePagerAdapter
If you must use FragmentStatePagerAdapter, in your adapter subclass override setPrimaryItem like so:
#Override
public void setPrimaryItem(ViewGroup container, int position, Object object) {
super.setPrimaryItem(container, position, object);
//This is a workaround for a bug in FragmentStatePagerAdapter
Fragment currentItem = getItem(position);
if (currentItem != null) {
currentItem.setMenuVisibility(true);
currentItem.setUserVisibleHint(true);
}
}
First create a method in the sub class of FragmentPagerAdapter to get the current fragment
public SherlockFragment getFragment() {
return currentFragment;
}
#Override
public void onTabSelected(final Tab tab, FragmentTransaction ft) {
((SherlockFragmentActivity) mContext).invalidateOptionsMenu();
Fragment f = ((SherlockFragmentActivity) mContext)
.getSupportFragmentManager().findFragmentByTag(
makeFragmentName(tab.getPosition()));
currentFragment=(SherlockFragment) f;
}
Now override below methods in Main Actvity
#Override
public boolean onCreateOptionsMenu(Menu menu) {
if (mTabsAdapter.getPositionOfTabSelected() != 0) {
menu.add("Read").setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
menu.add("Write").setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
menu.add("Clear").setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
menu.add("Factory data reset").setShowAsAction(
MenuItem.SHOW_AS_ACTION_IF_ROOM);
}
return super.onCreateOptionsMenu(menu);
}
Now call the onOptionItemSelected from activity to fragment
#Override
public boolean onOptionsItemSelected(MenuItem item) {
mTabsAdapter.getFragment().onOptionsItemSelected(item);
return super.onOptionsItemSelected(item);
}
I solved a very similar issue in which the Action bar icons assigned by the fragment inside of a ViewPager were disappearing onPause(). They would reappear when the Fragment came back into view and the user swiped left or right, but not immediately. The solution was calling notifyDataSetChanged() on the PagerAdapter in the onResume() method of the fragment.
#Override
public void onResume() {
mPagerAdapter.notifyDataSetChanged();
}
I was having this problem with the Action Bar Items while I was using HorizontalScrollView to show the tabs but I changed to PagerTitleStrip and the problem was solved.
Perhaps this information can help someone else.
My solution to this problem was to only inflate fragment menus if the fragment is currently visible. This solution may be too specific for your purposes, but it might help someone.
In the main activity:
boolean isFragmentVisible(int fragmentIndex) { ... }
In onCreateOptionsMenu() in your fragment:
if ( getActivity().isFragmentVisible(HOME_FRAGMENT_POS) ) {
inflater.inflate(R.menu.menu_home_fragment, menu);
}

How to implement show and hide fragment inside fragment in android

How to implement show and hide fragment inside fragment in Android? I have added two fragment inside activity. One fragment containing menu and one fragment contain sub menu. I have lot of button in menu fragment like home, idea, etc. If i click idea button. I have to show sub menu. If I again click idea button, I have to hide the sub menu. Can anybody provide example, or how to access one view fragment in another fragment?
this is my layout main
?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<fragment class="com.gcm.fragment.CommonFragment"
android:id="#+id/the_frag"
android:layout_width="wrap_content"
android:layout_height="match_parent" />
<fragment class="com.gcm.fragment.SubFragment"
android:id="#+id/the_frag1"
android:layout_marginTop="130dip"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
In My fragment
package com.gcm.fragment;
import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.widget.TextView;
public class CommonFragment extends Fragment implements OnClickListener {
TextView txtIhaveIdea=null;
boolean menuVisible=false;
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {
ViewGroup layout = (ViewGroup) inflater.inflate(R.layout.collapsed_menu2, container, false);
txtIhaveIdea=(TextView)layout.findViewById(R.id.txtIhaveAnIdea);
txtIhaveIdea.setOnClickListener(this);
return layout;
}
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
if(!menuVisible)
{
FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
fm.beginTransaction();
Fragment fragOne = new SubFragment();
ft.show(fragOne);
}
else
{
FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
fm.beginTransaction();
Fragment fragOne = new SubFragment();
ft.hide(fragOne);
}
}
}
Thanks
You could try get framelayout or fragment by id and change its visibility
View frag = findViewById(R.id.my_fragment);
frag.setVisibility(View.VISIBLE);
Considering this question has over 2K .. an answer may still help new readers so here it goes:
You don't really want to have FragmentManager and FragmentTransactions happening inside fragments not to have Casts nor potential harmful references to your Activity(s)
So what I do and works just fine is set an interface to the Fragment and give a method, say needsHide():
public class MyFrag extends Fragment {
public interface MyFragInterface {
public void needsHide();
}
Then implement it on your Activity:
public class MainActivity extends FragmentActivity implements MyFrag.MyFragInterface {
public void needsHide() {
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
//find the fragment by View or Tag
MyFrag myFrag = (MyFrag)fragmentManager.findFragmentByTag(SOME_TAG);
fragmentTransaction.hide(myFrag);
fragmentTransaction.commit();
//do more if you must
}}
The only part that requires thought is when to call needsHide(), this you might do in your Fragment's onViewCreated, since you are sure that it's not too early for your MainActivity to commit transactions. If you place it onCreate() it may not work depending on what you do with oter fragments:
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
// Making sure Main activity implemented interface
try {
if (USE_A_CONDITION) {
((MyFragInterface)this.getActivity()).needsHide();
}
} catch (ClassCastException e) {
throw new ClassCastException("Calling activity must implement MyFragInterface");
}
super.onViewCreated(view, savedInstanceState);
}
Simply, create a public method in your "parent" activity. which hides the fragment.
Then from within the fragment in your click event get the "parent|' activity, cast it and then call the method you created.
((ParentActitity)getActivity()).hideFragment();
You need to use an Interface to communicate with your parent Activity.
Take a look on Vogella's tutorial, "3.4. Application communication with Fragments". Here is the link
method hide():Hides an existing fragment. This is only relevant for fragments whose views have been added to a container, as this will cause the view to be hidden.
your code :
#Override
public void onClick(View v) {
if(!menuVisible)
{
FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
fm.beginTransaction();
Fragment fragOne = new SubFragment();
ft.show(fragOne);
}
else
{
FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
fm.beginTransaction();
// it's wrong , you just hide the fragment that not added to FragmentTransaction
Fragment fragOne = new SubFragment();
ft.hide(fragOne);
}
}
Below code worked for me..
View frag = findViewById(R.id.fragment);
frag.setVisibility(View.GONE);//Or View.INVISBLE

Categories

Resources