Mike
Mike

Reputation: 6839

Should provide default constructor?

I have an app that I transferred to the new android studio. When I try and generate a signed apk I get this error:

Error:(24) Error: This fragment should provide a default constructor (a public constructor with no arguments) (com.example.mike.beerportfolionewicon.BarcodeFrag) [ValidFragment]

The class starts off like this:

public class BarcodeFrag extends Fragment implements ReadJSONResult.OnArticleSelectedListener {

    private ListView lv;
    View v;
    SearchView searchView;
    private SearchView mSearchView;
    private MenuItem mSearchMenuItem;
    String id;

    public BarcodeFrag(String scanContent) {
        id = scanContent;


    }

I selected an option to ignore inspection but it still will not create an apk...

Tried changing it to this, but same error:

public class BarcodeFrag extends Fragment implements ReadJSONResult.OnArticleSelectedListener {

    private ListView lv;
    View v;
    SearchView searchView;
    private SearchView mSearchView;
    private MenuItem mSearchMenuItem;
    String id;

    public BarcodeFrag(){}

    public BarcodeFrag(String scanContent) {
        id = scanContent;


    }

Actually its a different error:

Error:(35) Error: Avoid non-default constructors in fragments: use a default constructor plus Fragment#setArguments(Bundle) instead [ValidFragment]

The entire code now looks like this:

public class BarcodeFrag extends Fragment implements ReadJSONResult.OnArticleSelectedListener {

    private ListView lv;
    View v;
    SearchView searchView;
    private SearchView mSearchView;
    private MenuItem mSearchMenuItem;
    String id;

    public BarcodeFrag(){}

    public BarcodeFrag(String scanContent) {
        id = scanContent;


    }




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

        //set layout here
        v = inflater.inflate(R.layout.activity_search, container, false);
        setHasOptionsMenu(true);
        getActivity().setTitle("Search");


        //get user information
        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
        String userName = prefs.getString("userName", null);
        String userID = prefs.getString("userID", null);


        //run code with barcode content
        String url = "http://api.brewerydb.com/v2/search/upc?code="+ id +"&key=xxx&format=json&withBreweries=y";

        //run async task
        ReadJSONResult task = new ReadJSONResult(getActivity());
        task.setOnArticleSelectedListener(this);
        task.execute(url);




        return v;


    }

    @Override
    public void onArticleSelected(String b, String brewery){

        //code to execute on click
        Fragment Fragment_one;
        FragmentManager man= getFragmentManager();
        FragmentTransaction tran = man.beginTransaction();

        Fragment_one = new BeerTabs();
        SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
        SharedPreferences.Editor editor = preferences.edit();
        editor.putString("beerID",b);
        editor.putString("breweryID",brewery);
        editor.commit();


        tran.replace(R.id.main, Fragment_one);//tran.
        tran.addToBackStack(null);
        tran.commit();





    }
}

Upvotes: 2

Views: 6531

Answers (3)

Yash Sampat
Yash Sampat

Reputation: 30611

Remove

public BarcodeFrag(String scanContent) {
    id = scanContent;
}

A Fragment in Android should never have a non-empty constructor. Instead, you can create a static initiator factory method inside your Fragment as follows:

public static final String SCAN_CONTENT = "param";
private String scanContent;

public static final BarcodeFrag instanceOf(String scanContent) {
    BarcodeFrag fragment = new BarcodeFrag();
    Bundle args = new Bundle();
    args.putString(SCAN_CONTENT, scanContent);
    fragment.setArguments(args);
    return fragment;
}

Now, to create a new instance of BarcodeFrag from any other class,

Fragment f = BarcodeFrag.instanceOf(scanContent)

and to access the value scanContent within BarcodeFrag,

scanContent = getArguments().getString(SCAN_CONTENT);

The parameters passed can be of any type, i.e. int, float, String etc.

Try this. This should work;

Upvotes: 2

nbaroz
nbaroz

Reputation: 1795

Fragment must have an empty constructor due to life cycle reasons. consider replacing the one you got with en empty one and pass String scanContent via Bundle. in that way you can assure that the fragment always get your scanContent even if the fragment recreated itself.

Fragment fragment = new Fragment() {
        @Override
        public void onAttach(Activity activity) {
            super.onAttach(activity);
            if(getArguments() != null) {
                String scanContent = getArguments().getString("scanContent");
            }
        }
    };

Bundle bundle = new Bundle();
bundle.putString("scanContent", scanContent);
fragment.setArguments(bundle);

Edit:

From your Activity:

BarcodeFrag fragment = new BarcodeFrag();
Bundle bundle = new Bundle();
bundle.putString("scanContent", scanContent);
fragment.setArguments(bundle);

On your Fragment, replace

 public BarcodeFrag(String scanContent) {
    id = scanContent;
 }

with

public BarcodeFrag() {
}

and get the id from onCreateView(...) like so:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    if(id == null && getArguments() != null) {
        String scanContent = getArguments().getString("scanContent");
        this.id = scanContent;
    }
    .
    .
    .
    .
}

Upvotes: 2

Arun Kumar
Arun Kumar

Reputation: 2934

If no constructor is defined then Default constructor is automatically created by Compiler.

If any constructor with argument is defined.In case if you call default constructor then it will give compile time error.

public class P2 {

    public P2(int a) {

    }

    public static void main(String[] args) {
        P2 p = new P2(10);
        P2 p1 = new P2(); //compile time error      
    }
}

For remove compile time error, add default constructor too.

public class P2 {

    public P2() { //After adding this constructor, compile time error is removed

    }
    public P2(int a) {

    }

    public static void main(String[] args) {
        P2 p = new P2(10);
        P2 p1 = new P2();       
    }
}

Upvotes: 0

Related Questions