0

I don´t have so many experiences with fragments at the moment so i hope anybody can help me with this ! Before the app release compiled fine some month ago and now i have this problem

Android Studio says: "Problem avoid not default constructors in fragments. "

I hope anybody can help me here to solve this problem.

public  static  class TagClickDialog extends DialogFragment {
      private final TagClickDialogListener mListener;
      private final Context mContext;
      private final Tag[] mTags;

      public TagClickDialog(Context context, TagClickDialogListener listener, Tag[] tags) {
            mListener = listener;
            mContext = context;
            mTags = tags;
       }

       @Override
       public Dialog onCreateDialog(Bundle savedInstanceState) {
            String[] dialogItems = new String[mTags.length];
            for (int i=0; i<mTags.length; i++) {
                 dialogItems[i] = mTags[i].getValue();
            }
            AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
            builder.setTitle(getResources().getString(R.string.tags))
                    .setItems(dialogItems, new DialogInterface.OnClickListener() {
                  public void onClick(DialogInterface dialog,
                                int which) {
                       mListener.onTagClick(mTags[which]);
                  }
             });
             return builder.create();
       }
}
Frank
  • 2,738
  • 2
  • 14
  • 19
  • 1
    Possible duplicate of [Why do I want to avoid non-default constructors in fragments?](http://stackoverflow.com/questions/12062946/why-do-i-want-to-avoid-non-default-constructors-in-fragments) – Nabeel K Dec 15 '15 at 07:39
  • 2
    You use Intents to send stuff from activity to activity. To send stuff into a fragment use Bundle. Check out Pramod's answer. – denvercoder9 Dec 15 '15 at 07:57

3 Answers3

0

Every fragment must have an empty constructor, so it can be instantiated when restoring its activity's state. It is strongly recommended that subclasses do not have other constructors with parameters, since these constructors will not be called when the fragment is re-instantiated; instead, arguments can be supplied by the caller with setArguments(Bundle) and later retrieved by the Fragment with getArguments().

Due to this reason we have static factory method when we want an instance of that fragment newInstance() in case you want it to have some information instantiated.

check this out

Update you can use following code

public  static  class TagClickDialog extends DialogFragment {
    private TagClickDialogListener mListener;
    private Context mContext;
    private Tag[] mTags;

public TagClickDialog() {

}

**update**
@Override
public void onAttach(Context context) {
super.onAttach(context);
mListener = (TagClickDialogListener )context;
}

public static TagClickDialog newInstance(Context context, Tag[] tags) {

    mContext = context;
    mTags = tags;
    return this;
}

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        String[] dialogItems = new String[mTags.length];
        for (int i=0; i<mTags.length; i++) {
            dialogItems[i] = mTags[i].getValue();
        }
        AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
        builder.setTitle(getResources().getString(R.string.tags))
            .setItems(dialogItems, new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog,
                        int which) {
                    mListener.onTagClick(mTags[which]);
                }
            });
        return builder.create();
    }
}

}

this is how you can use it

TagClickDialog fragment = TagClickDialog.newInstance("put all the parameters");
fragment.show(fragmentManager, "some tag");
Community
  • 1
  • 1
Pankaj Nimgade
  • 4,529
  • 3
  • 20
  • 30
  • maybe you can give me an example with my piece of of code how i have to change it ? – Frank Dec 15 '15 at 07:46
  • Hi thanx but this is not working ..i tried it with an empty constructor too but then it says that this is not initialized : private final TagClickDialogListener mListener; private final Context mContext; private final Tag[] mTags; – Frank Dec 15 '15 at 07:58
  • TagClickDialog.newInstance(mListener, mContext, mTags); is this how you are initializing ? – Pankaj Nimgade Dec 15 '15 at 08:00
  • No sorry i had to remove the final ..now the code with your changes are working ! But now i have the next problem here : Error:(107, 40) error: constructor TagClickDialog in class PhotoOverviewFragment.TagClickDialog cannot be applied to given types; required: no arguments found: BaseActivity,PhotoOverviewFragment,Tag[] reason: actual and formal argument lists differ in length ....on this code : TagClickDialog d = new TagClickDialog(mActivity, PhotoOverviewFragment.this, allTags.toArray(new Tag[allTags.size()])); – Frank Dec 15 '15 at 08:06
  • are you using android studio ? – Pankaj Nimgade Dec 15 '15 at 08:12
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/97936/discussion-between-pankaj-nimgade-and-frank). – Pankaj Nimgade Dec 15 '15 at 08:14
  • yes i´m using android studio. this was not my source code. i just compiled the app some moth ago but now all theses problem occur – Frank Dec 15 '15 at 08:16
0

From Activity you can send data to Fragment with intent as:

Bundle bundle = new Bundle();
bundle.putString("message", "message is hi");
//set Fragmentclass Arguments
Fragmentclass fragobj=new Fragmentclass();
fragobj.setArguments(bundle);

and to receive in fragment in Fragments onCreateView method:

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
    Bundle savedInstanceState) {

    // get message from activity        
    String strtext=getArguments().getString("message");

    return inflater.inflate(R.layout.fragment, container, false);
    }

This is working fine for me. This may help you.

0

If you are creating a non-default constructor for a Fragment, you will be getting this error

Avoid non-default constructors in fragments: use a default constructor plus Fragment#setArguments(Bundle) instead.

Of course this means you have to remove non-default constructors.

WHAT I USUALLY DO IS

1. Use Bundle to pass data [Unless it's an Object, in which case you have to Serialize it] along with a key, so that in the Fragment, you can get the Bundle via the key

Bundle args = new Bundle();
args.putLong("key", value);
fragment.setArguments(args);

Inside the Fragment, you retrieve the argument as

getArguments().getType("key");

2. But sometimes I create a setter methods inside Fragment to set the data.

public void setData(int value) {
    this.value = value;
}

And when I initialise the Fragment, I call this method right away.

MyFragment fragment = new MyFragment();
fragment.setData(5);
capt.swag
  • 10,335
  • 2
  • 41
  • 41