NullPointerException at getArguments().getInten("index", index) - android

I'm presented with this unpleasant message on this code
public static HelpDetailsFragment newInstance(int index)
{
HelpDetailsFragment detailFragment = new HelpDetailsFragment();
Bundle bundleArgs = new Bundle();
bundleArgs.putInt("index", index);
detailFragment.setArguments(bundleArgs);
return detailFragment;
} // newInstance()
public int getCurrentIndex()
{
return getArguments().getInt("index", 0);
}
I'm using this code here:
HelpDetailsFragment detailFragment = (HelpDetailsFragment) getFragmentManager()
.findFragmentById(R.id.helpDetailsFrame);
if((detailFragment == null) || (detailFragment.getCurrentIndex() != index))
{
detailFragment = HelpDetailsFragment.newInstance(index);
Log.i(TAG, "HelpListFragment Create and replace details fragment for item:"+index);
FragmentTransaction fragTrans = getFragmentManager().beginTransaction();
fragTrans.replace(R.id.helpDetailsFrame, detailFragment);
fragTrans.commit();
}
What em I missing here??

Related

getArguments() always returns null in Fragment

I need to pass arguments to my fragments but getArguments() alway returns null
public static PersonFragment newInstance(int columnCount, ArrayList<Person> personenListe) {
PersonFragment personFragment = new PersonFragment();
Bundle args = new Bundle();
args.putSerializable("persList",personenListe);
args.putInt(ARG_COLUMN_COUNT, columnCount);
personFragment.setArguments(args);
return new PersonFragment();
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) { //getAguments() == null !!
mColumnCount = getArguments().getInt(ARG_COLUMN_COUNT);
mPersonenListe = (ArrayList<Person>) getArguments().getSerializable("persList");
}
}
I'm calling it in MainActivity
openFragment(PersonFragment.newInstance(personenListe.size(), personenListe));
With this method
public void openFragment(Fragment fragment) {
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.container, fragment);
transaction.addToBackStack(null);
transaction.commit();
}
Instead of returning the fragment that you set the arguments to, you returned a brand new fragment.
So change the newInstance to:
public static PersonFragment newInstance(int columnCount, ArrayList<Person> personenListe) {
PersonFragment personFragment = new PersonFragment();
Bundle args = new Bundle();
args.putSerializable("persList",personenListe);
args.putInt(ARG_COLUMN_COUNT, columnCount);
personFragment.setArguments(args);
// return new PersonFragment();
return personFragment ; // <<< change here
}

Bundle not working (getArguments() always null) [Android]

My code was working few hours ago but not anymore, I can't see what is the reason.
Here is my listener where I change fragment after a click :
CustomMarkRow.java
public void onClick(DialogInterface dialogInterface, int i){
Bundle bundle = new Bundle();
bundle.putInt("id", CustomMarkRow.this.mark.getId());
FragmentManager fragmentManager = CustomMarkRow.this.fragmentManager;
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); activity.getActionBar().setSelectedNavigationItem(CustomMarkRow.this.positionTab);
EditMarkFragment fragment = new EditMarkFragment();
fragment.setArguments(bundle);
fragmentTransaction.replace(R.id.fragmentContainer, fragment,"2");
fragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}
At this moment, fragment.getArguments() contains what I put inside :
{android.os.Bundle#3644} "Bundle[{id=1}]"
In my second file :
EditMarkFragment.java
public class EditMarkFragment extends Fragment {
public View view;
public EditMarkFragment(){
super();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
this.view = inflater.inflate(getResources().getIdentifier("edit_mark", "layout",container.getContext().getPackageName()), container, false);
if(this.getArguments()==null){ // always null
...
}
return this.view
}
getArguments() always return null here, What is bad in this sample ?
* edit *
Here is my launcher class :
public class Launcher extends Activity implements ActionBar.TabListener {
private HomeFragment frag1 = new HomeFragment();
private EditMarkFragment frag2 = new EditMarkFragment();
private MarkListFragment frag3 = new MarkListFragment();
private EditCategoryFragment frag4 = new EditCategoryFragment();
private CategoryListFragment frag5 = new CategoryListFragment();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().requestFeature(Window.FEATURE_ACTION_BAR);
setContentView(R.layout.launcher);
//Configuration de la barre d'onglet
getActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
ActionBar.Tab tab1 = getActionBar().newTab().setTabListener(this).setTag("1").setText("Home"); //.setIcon(R.drawable.homew);
getActionBar().addTab(tab1);
ActionBar.Tab tab2 = getActionBar().newTab().setTabListener(this).setTag("2").setText("New Mark"); //.setIcon(R.drawable.addw);
getActionBar().addTab(tab2);
ActionBar.Tab tab3 = getActionBar().newTab().setTabListener(this).setTag("3").setText("My Marks"); //.setIcon(R.drawable.listw);
getActionBar().addTab(tab3);
ActionBar.Tab tab4 = getActionBar().newTab().setTabListener(this).setTag("4").setText("New Category"); //.setIcon(R.drawable.categoryw);
getActionBar().addTab(tab4);
ActionBar.Tab tab5 = getActionBar().newTab().setTabListener(this).setTag("5").setText("Categories"); //.setIcon(R.drawable.categoryw);
getActionBar().addTab(tab5);
}
#Override
public void onTabSelected(ActionBar.Tab tab, android.app.FragmentTransaction ft) {
if(tab.getTag().equals("1")){
ft.replace(R.id.fragmentContainer, frag1);
}
else if(tab.getTag().equals("2")){
ft.replace(R.id.fragmentContainer, frag2);
}
else if(tab.getTag().equals("3")){
ft.replace(R.id.fragmentContainer, frag3);
}
else if(tab.getTag().equals("4")){
ft.replace(R.id.fragmentContainer, frag4);
}
else if(tab.getTag().equals("5")){
ft.replace(R.id.fragmentContainer, frag5);
}
}
#Override
public void onTabUnselected(ActionBar.Tab tab, android.app.FragmentTransaction ft) {
if(tab.getTag().equals("1")){
ft.remove(frag1);
}
else if(tab.getTag().equals("2")){
ft.remove(frag2);
}
else if(tab.getTag().equals("3")){
ft.remove(frag3);
} else if(tab.getTag().equals("4")){
ft.remove(frag4);
}
else if(tab.getTag().equals("5")){
ft.remove(frag5);
}
}
#Override
public void onTabReselected(ActionBar.Tab tab, android.app.FragmentTransaction ft) {
}
}
While your onClick() code is creating an arguments Bundle, your onCreate() is not. If that edition of your fragment calls getArguments(), the method will return null.
1-Update your EditMark fragment with as follows:-
public class EditMarkFragment extends Fragment {
public static View view;
public static EditMarkFragment newInstance(int id) {
EditMarkFragment fragment = new EditMarkFragment();
Bundle bundle = new Bundle();
bundle.putInt("id", id);
fragment.setArguments(bundle);
return fragment;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
this.view = inflater.inflate(getResources().getIdentifier("edit_mark", "layout",container.getContext().getPackageName()), container, false);
int id=getArguments.getInt("id");
return this.view}
2- Inside CustomMarkRow update your code as :-
public void onClick(DialogInterface dialogInterface, int i){
FragmentManager fragmentManager = CustomMarkRow.this.fragmentManager;
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); activity.getActionBar().setSelectedNavigationItem(CustomMarkRow.this.positionTab);
EditMarkFragment fragment = EditMarkFragment.newInstance(CustomMarkRow.this.mark.getId()) ;
fragmentTransaction.replace(R.id.fragmentContainer, fragment,"2");
fragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}
Try this,hope this will hep you.

I can not pass a string to fragment

call fragment from fragment. I need to pass a string to the fragment. how to do it?
if (position==1){
FragmentTransaction ft;
VideoList lf = new VideoList();
ft = getFragmentManager().beginTransaction();
ft.replace(R.id.fragmentsPanel, lf);
ft.addToBackStack(null);
ft.commit();
}
I want to pass String str = "absd"; and the second fragment to take String str1 = row of the first fragment
Use arguments!
public static VideoList videoListWithString(String string) {
VideoList videoList = new VideoList();
Bundle arguments = new Bundle();
arguments.putString("testString","test");
videoList.setArguments(arguments);
return videoList;
}
and in your fragments onCreate...
Bundle arguments = getArguments();
String testString = arguments.getString("testString");
You can use setArguments() and getArguments() methods in Fragments
like
if (position==1){
FragmentTransaction ft;
VideoList lf = new VideoList();
Bundle bundle = new Bundle();
bundle.putString("str", "absd");
ft = getFragmentManager().beginTransaction();
ft.replace(R.id.fragmentsPanel, lf);
ft.addToBackStack(null);
ft.commit();
}
and in the fragment you get this string like this
public class VideoList extends ListFragment {
public View onCreateView(LayoutInflater inflater,
ViewGroup containerObject,
Bundle savedInstanceState){
//here is your arguments
Bundle bundle=getArguments();
//here is your list array
String str=bundle.getString("str");
}
}
Bundle params = new Bundle();
params.putString("str1", "absd");
getFragmentManager().beginTransaction()
.replace(R.id.fragment_place, YourFragment.instantiate(getActivity(), YourFragment.class.getName(), params), "YourFragmentTag").commit();
If your requirement is to pass value from one fragment to another then try using bundle.
For example:
TalkDetail fragment = new TalkDetail();
Bundle bundle = new Bundle();
bundle.putString("title", title);
bundle.putString("largeimg", largeimg);
bundle.putString("excert", excert);
bundle.putString("description",description);
bundle.putString("cat", cat);
bundle.putString("header_title", "Talk");
//bundle.putInt("postid", postid);
fragment.setArguments(bundle);
((BaseContainerFragment)getParentFragment()).replaceFragment(fragment, true);
Here's your BaseContainerFragment class that will help to get better back track and other good stuff
public class BaseContainerFragment extends Fragment {
public void replaceFragment(Fragment fragment, boolean addToBackStack) {
FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
if (addToBackStack) {
transaction.addToBackStack(null);
}
transaction.replace(R.id.container_framelayout, fragment);
transaction.commit();
getChildFragmentManager().executePendingTransactions();
}
public boolean popFragment() {
Log.e("test", "pop fragment: " + getChildFragmentManager().getBackStackEntryCount());
boolean isPop = false;
if (getChildFragmentManager().getBackStackEntryCount() > 0) {
isPop = true;
getChildFragmentManager().popBackStack();
}
return isPop;
}
}

Android replace fragment fast

I am trying to find a way to replace fragments as fast as I can. The problem is with fragment recreation (inflating layout on recreation).
Why is this a bad idea?
private View view;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
if (view == null)
{
view= inflater.inflate(R.layout.fragment_one, container, false);
Log.e(TAG, "On create view !");
}
return view;
}
Or this variant:
User click on a tab from actionbar
#Override
public void onTabSelected(Tab tab, FragmentTransaction ft)
{
// tab contains a tag with the name of the Fragment, in this case is FRAGMENT_ONE
TabDataHolder tdh = (TabDataHolder) tab.getTag();
replaceFragment(R.id.mainContent, tdh.fragmentTag);
}
Method for replacing fragment:
private void replaceFragment(int fragmentContainerId, String fragmentTag)
{
Log.e(TAG, "Replace fragment !");
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.setCustomAnimations(android.R.animator.fade_in, android.R.animator.fade_out);
ft.replace(fragmentContainerId, getFragment(fragmentTag), fragmentTag).commit();
}
Method which creates or returns an existing fragment
private Fragment getFragment(String fragmentTag)
{
Fragment fg = getFragmentManager().findFragmentByTag(fragmentTag);
if (fg == null)
fg = getFragmentFromStack(fragmentTag);
if (fragmentTag.equals(FRAGMENT_ONE))
{
if (fg == null)
{
fg = new FragmentOne();
addFragmentToStack(fg, fragmentTag, false);
Log.e(TAG, "Adding fg to stack !");
}
}
else
if (fragmentTag.equals(FRAGMENT_TWO))
{
if (fg == null)
{
fg = new FragmentTwo();
addFragmentToStack(fg, fragmentTag, false);
Log.e(TAG, "Adding fg to stack !");
}
}
else
if (fragmentTag.equals(FRAGMENT_THREE))
{
if (fg == null)
{
fg = new FragmentThree();
addFragmentToStack(fg, fragmentTag, false);
Log.e(TAG, "Adding fg to stack !");
}
}
else
if (fragmentTag.equals(FRAGMENT_FOUR))
{
if (fg == null)
{
fg = new FragmentFour();
addFragmentToStack(fg, fragmentTag, false);
Log.e(TAG, "Adding fg to stack !");
}
}
if (fg == null)
new NullPointerException("Fragment not found");
return fg;
}
Method which returns an existing fragment from the stack (ArrayList) by tag
private ArrayList<FragmentData> fragmentDataStack = new ArrayList<FragmentData>();
private Fragment getFragmentFromStack(String fragmentTag)
{
for (FragmentData fgd : fragmentDataStack)
{
if (fgd.getTag().equals(fragmentTag))
return fgd.getFragment();
}
return null;
}
public class FragmentData
{
private Fragment fragment;
private String tag;
public FragmentData (Fragment fragment, String tag)
{
this.fragment = fragment;
this.tag = tag;
}
public Fragment getFragment() {
return fragment;
}
public void setFragment(Fragment fragment) {
this.fragment = fragment;
}
public String getTag() {
return tag;
}
public void setTag(String tag) {
this.tag = tag;
}
}
Method which will add a Fragment to the stack. The last parameter is for deleting the old fragment and adding a new fragment
private void addFragmentToStack(Fragment fragment, String fragmentTag, boolean replaceIfExists)
{
if (replaceIfExists)
{
for (int i = 0; i < fragmentDataStack.size(); i++)
{
if (fragmentDataStack.get(i).getTag().equals(fragmentTag))
{
fragmentDataStack.set(i, new FragmentData(fragment, fragmentTag));
return;
}
}
}
fragmentDataStack.add(new FragmentData(fragment, fragmentTag));
}
I am not sure if this the right procedure for fast fragment replacement.

switch fragments with button (with NavigationDrawer)

I have a NavigationDrawer which I use to switch between Fragments. What i would like to do is have a button in one of my fragments which acts as a 'shortcut' to another Fragment in the NavigationDrawer.
In the NavigationDrawer I switch fragments like this:
private class DrawerItemClickListener implements
ListView.OnItemClickListener {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
selectItem(position);
}
}
public void selectItem(int position) {
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager
.beginTransaction();
String fragmentTag = String.valueOf(position);
FragmentBase fragment = (FragmentBase) fragmentManager
.findFragmentByTag(fragmentTag);
if (null == fragment) {
fragment = createFragmentByPosition(position);
}
if (null == fragment)
return;
if (fragment.isAdded()) {
fragmentTransaction.show(fragment);
} else {
fragmentTransaction.replace(R.id.content_frame, fragment, fragmentTag);
}
if (mCurrentFragment != null) {
fragmentTransaction.hide(mCurrentFragment);
}
mCurrentFragment = fragment;
fragmentTransaction.commitAllowingStateLoss();
mDrawerList.setItemChecked(position, true);
setTitle(mNoterActivities[position]);
mDrawerLayout.closeDrawer(mDrawerList);
}
private FragmentBase createFragmentByPosition(int position) { // FragmentBase just extends Fragment
FragmentBase fragment = null;
if (position == 0) {
fragment = new Fragment1();
Bundle args = new Bundle();
fragment.setArguments(args);
} else if (position == 1) { // Reminder
fragment = new Fragment2();
Bundle args = new Bundle();
fragment.setArguments(args);
}
return fragment;
}
I'm not sure how I would go about doing this. I tried getting an instance of the NavigationDrawer class and then calling selectItem with the desired position, but this doesn't work as it gives an error "no view found".
In the NavigationDrawer class:
public Navigation_Drawer getInstance() {
if (null == instance) {
instance = new Navigation_Drawer();
}
return instance;
}
In FragmentB (position 1):
//onClick
Navigation_Drawer nd = new Navigation_Drawer().getInstance();
nd.selectItem(0); // Try to go to FragmentA
This seems far too simple so no wonder it doesn't work!
First, on selectItem method, using add method instead of replace method:
public void selectItem(int position) {
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
String fragmentTag = String.valueOf(position);
FragmentBase fragment = (FragmentBase) fragmentManager.findFragmentByTag(fragmentTag);
if (null == fragment) {
fragment = createFragmentByPosition(position);
}
if (null == fragment)
return;
if (fragment.isAdded()) {
fragmentTransaction.show(fragment);
} else {
// fragmentTransaction.replace(R.id.content_frame, fragment, fragmentTag);
fragmentTransaction.add(R.id.content_frame, fragment, fragmentTag);
}
if (mCurrentFragment != null) {
fragmentTransaction.hide(mCurrentFragment);
}
mCurrentFragment = fragment;
fragmentTransaction.commitAllowingStateLoss();
mDrawerList.setItemChecked(position, true);
setTitle(mNoterActivities[position]);
mDrawerLayout.closeDrawer(mDrawerList);
}
Second, getInstance method in Navigation_Drawer should not create a new Navigation_Drawer when instance is null, set instance to this in onCreate in Navigation_Drawer, then return instance when call getInstance:
private static Navigation_Drawer mInstance;
public static Navigation_Drawer getInstance() {
return mInstance;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
mInstance = this;
// other codes here:
}
The id to the QuickNoteFragment is 0, and to PendViewPager is 1. You can turn to PendViewPager in QuickNoteFragment:
Navigation_Drawer.getInstance().selectItem(1);
-
update1: how to pass data to fragment:
QuickNoteFragment and HistoryFragement have the same parent Class: FragmentBase, we add a method named onDataIn to receive data:
public class FragmentBase extends Fragment {
public void function onDataIn(Object data) {
}
}
We should change selectItem, add a paraments to receive data:
public void selectItem(int position, Object data) {
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
String fragmentTag = String.valueOf(position);
FragmentBase fragment = (FragmentBase) fragmentManager.findFragmentByTag(fragmentTag);
if (null == fragment) {
fragment = createFragmentByPosition(position);
}
if (null == fragment)
return;
// call onDataIn() method.
fragment.onDataIn(data);
if (fragment.isAdded()) {
fragmentTransaction.show(fragment);
} else {
// fragmentTransaction.replace(R.id.content_frame, fragment, fragmentTag);
fragmentTransaction.add(R.id.content_frame, fragment, fragmentTag);
}
if (mCurrentFragment != null) {
fragmentTransaction.hide(mCurrentFragment);
}
mCurrentFragment = fragment;
fragmentTransaction.commitAllowingStateLoss();
mDrawerList.setItemChecked(position, true);
setTitle(mNoterActivities[position]);
mDrawerLayout.closeDrawer(mDrawerList);
}
In order to make selectItem compatible, we should add a overloaded selectItem method.
public void selectItem(int postion) {
selectItem(position, null);
}
In this way, we do not need to change the old code where called selectItem and did not need pass a data to fragement.

Categories

Resources