Reputation: 6839
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
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
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
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