Error non-default constructors in fragments
I am dealing with maps apiv2. And I am getting the following error while coding for Dialog Fragment class.
Error : Avoid non-default constructors in fragments: use a default constructor plus Fragment#setArguments(Bundle) instead:
This is the code :
public PlaceDialogFragment(){ super(); } public PlaceDialogFragment(Place place, DisplayMetrics dm){ super(); this.mPlace = place; this.mMetrics = dm; }
Any help wud be appreciated..
Revised: This is the whole code...I m kind of a newbie and never before dealt with fragments..I was going through a maps tut and found this..can you elaborate now wat u were trying to explain..
package com.example.travelplanner; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.AsyncTask; import android.os.Bundle; import android.support.v4.app.DialogFragment; import android.util.DisplayMetrics; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; import android.widget.Toast; import android.widget.ViewFlipper; // Defining DialogFragment class to show the place details with photo public class PlaceDialogFragment extends DialogFragment{ TextView mTVPhotosCount = null; TextView mTVVicinity = null; ViewFlipper mFlipper = null; Place mPlace = null; DisplayMetrics mMetrics = null; public PlaceDialogFragment(){ super(); } public PlaceDialogFragment(Place place, DisplayMetrics dm){ super(); this.mPlace = place; this.mMetrics = dm; } @Override public void onCreate(Bundle savedInstanceState) { // For retaining the fragment on screen rotation setRetainInstance(true); super.onCreate(savedInstanceState); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View v = inflater.inflate(R.layout.dialog_layout, null); // Getting reference to ViewFlipper mFlipper = (ViewFlipper) v.findViewById(R.id.flipper); // Getting reference to TextView to display photo count mTVPhotosCount = (TextView) v.findViewById(R.id.tv_photos_count); // Getting reference to TextView to display place vicinity mTVVicinity = (TextView) v.findViewById(R.id.tv_vicinity); if(mPlace!=null){ // Setting the title for the Dialog Fragment getDialog().setTitle(mPlace.mPlaceName); // Array of references of the photos Photo[] photos = mPlace.mPhotos; // Setting Photos count mTVPhotosCount.setText("Photos available : " + photos.length); // Setting the vicinity of the place mTVVicinity.setText(mPlace.mVicinity); // Creating an array of ImageDownloadTask to download photos ImageDownloadTask[] imageDownloadTask = new ImageDownloadTask[photos.length]; int width = (int)(mMetrics.widthPixels*3)/4; int height = (int)(mMetrics.heightPixels*1)/2; String url = "https://maps.googleapis.com/maps/api/place/photo?"; String key = "key=AIzaSyBSo1xlML-tOFTCdJb6qIbVnF9e7y5nj0o"; String sensor = "sensor=true"; String maxWidth="maxwidth=" + width; String maxHeight = "maxheight=" + height; url = url + "&" + key + "&" + sensor + "&" + maxWidth + "&" + maxHeight; // Traversing through all the photoreferences for(int i=0;i<photos.length;i++){ // Creating a task to download i-th photo imageDownloadTask[i] = new ImageDownloadTask(); String photoReference = "photoreference="+photos[i].mPhotoReference; // URL for downloading the photo from Google Services url = url + "&" + photoReference; // Downloading i-th photo from the above url imageDownloadTask[i].execute(url); } } return v; } @Override public void onDestroyView() { if (getDialog() != null && getRetainInstance()) getDialog().setDismissMessage(null); super.onDestroyView(); } private Bitmap downloadImage(String strUrl) throws IOException{ Bitmap bitmap=null; InputStream iStream = null; try{ URL url = new URL(strUrl); /** Creating an http connection to communcate with url */ HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); /** Connecting to url */ urlConnection.connect(); /** Reading data from url */ iStream = urlConnection.getInputStream(); /** Creating a bitmap from the stream returned from the url */ bitmap = BitmapFactory.decodeStream(iStream); }catch(Exception e){ Log.d("Exception while downloading url", e.toString()); }finally{ iStream.close(); } return bitmap; } private class ImageDownloadTask extends AsyncTask<String, Integer, Bitmap>{ Bitmap bitmap = null; @Override protected Bitmap doInBackground(String... url) { try{ // Starting image download bitmap = downloadImage(url[0]); }catch(Exception e){ Log.d("Background Task",e.toString()); } return bitmap; } @Override protected void onPostExecute(Bitmap result) { // Creating an instance of ImageView to display the downloaded image ImageView iView = new ImageView(getActivity().getBaseContext()); // Setting the downloaded image in ImageView iView.setImageBitmap(result); // Adding the ImageView to ViewFlipper mFlipper.addView(iView); // Showing download completion message Toast.makeText(getActivity().getBaseContext(), "Image downloaded successfully", Toast.LENGTH_SHORT).show(); } } }
Answers
if you like to be out of rules just do next
@SuppressLint("ValidFragment") public PlaceDialogFragment(Place place, DisplayMetrics dm){ super(); this.mPlace = place; this.mMetrics = dm; }
Because of the nature of fragment and how there managed and shown on your screen it's very recommended not to create a non default constructor and in many cases this would cause problems in run time. In case you should do something like this:
public static final GridFragment newInstance(String tabId) { GridFragment f = new GridFragment(); Bundle bdl = new Bundle(2); bdl.putString(TAB_ID, tabId); f.setArguments(bdl); return f; }
and in onCreate extract the needed data from the bundle:
@Override public void onCreate(Bundle savedInstanceState) { String tabId = getArguments().getString(TAB_ID); }
And take a look at this question as well:
Do fragments really need an empty constructor?
@SuppressLint({"NewApi", "ValidFragment"}) public PlaceDialogFragment(Place place, DisplayMetrics dm){ super(); }
The easier way is to add these to the gradle:
android { lintOptions { checkReleaseBuilds false } }
Or you can add this line in each fragment
@SuppressLint("ValidFragment") public PlaceDialogFragment(Place place, DisplayMetrics dm){ super(); this.mPlace = place; this.mMetrics = dm; }
Best solution is add lines in gradle simply.
solution worked for me
android { lintOptions { checkReleaseBuilds false } }