Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Android

Method Error!

I'm wondering can anyone help with this error:

"Cannot reduce the visibility of the inherited method from Fragment"

it's referring to this onCreate method:

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main_list);

        mProgressBar = (ProgressBar) findViewById(R.id.progressBar1);

        if(NetworkIsAvailable())    {
            mProgressBar.setVisibility(View.VISIBLE);
            GetBlogPostsTask getBlogPostsTask = new GetBlogPostsTask();
            getBlogPostsTask.execute();
        }
        else {
            Toast.makeText(this, "Network is unavailable!", Toast.LENGTH_LONG).show();
        }

        //String message = getString(R.string.no_items);
        //Toast.makeText(this, message, Toast.LENGTH_LONG).show();

    }

It sounds like the class your onCreate method is implemented in is a subclass of Fragment, not Activity. What class does your class extend from?

8 Answers

The problem with the Toast is the type of the first parameter. The method makeText needs an instance of Context, and since the Activity class is a subclass of Context, using this within an Activity works just fine. However, Fragment is not a subclass of Context, therefore you cannot pass this in for that parameter.

What you can do, is use Fragment's method getActivity, which will return the Activity instance that your fragment is currently attached to. That will work just fine for a Toast message, as well as anywhere in your fragment's code where you need a Context instance.

The reason you are getting those errors is because those methods do not exist for Fragments. Setting up a view for a Fragment is a little different than doing it for an Activity. For example, in an Activity, you would use setContentView(int) to tell it what layout to load. In a Fragment, you must override onCreateView and return the view you want to display, which it looks like you are doing correctly. You can simply remove the setContentView from your onCreate method, and move the mProgressBar assignment into onCreateView.

Regarding the "Cannot reduce the visibility of the inherited method from Fragment" error, this means that you can't redefine a method marked as public in a superclass, as protected or private in a subclass. It's a little confusing on Android because Activity#onCreate is a protected method, whereas Fragment#onCreate is a public method. Just swap the protected for public and you should be good to go.

Ah, that is my fault for not explaining that one clearly. Again, #findViewById is a method on Activity and doesn't exist for Fragments. That's not a problem though since you have access to your view within onCreateView. Simply call rootView.findViewById after you have inflated it.

Another thing to keep in mind, in reading your code, is you will most likely get a NullPointerException within onCreate at this line:

mProgressBar.setVisibility(View.VISIBLE);

This is because at this point in the fragment's lifecycle, the view will not have been created yet, therefore your mProgressBar reference will be null. For more information on a fragment's lifecycle (a must read), check out the Android documentation here.

Well I originally had it in my main activity. then I copy and pasted it into a fragment because I was extending my app with tabs. So originally it was MainListActivity and I changed it to NewsFragment. Here is all the code from NewsFragment: (I highlighted the lines with an "//ERROR" message.

public class NewsFragment extends ListFragment{

public static final int NUMBER_OF_POSTS = 20;
public static final String TAG = NewsFragment.class.getSimpleName();
protected JSONObject mBlogData;
protected ProgressBar mProgressBar;

private final String KEY_TITLE = "title";
private final String KEY_DATE = "date";

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.fragment_news_list,
            container, false);

    return rootView;
}

@Override
protected void onCreate(Bundle savedInstanceState) {       //ERROR
    super.onCreate(savedInstanceState);
    setContentView(R.layout.fragment_news_list);     //ERROR

    mProgressBar = (ProgressBar) findViewById(R.id.progressBar1);  //ERROR

    if(NetworkIsAvailable())    {
        mProgressBar.setVisibility(View.VISIBLE);
        GetBlogPostsTask getBlogPostsTask = new GetBlogPostsTask();
        getBlogPostsTask.execute();
    }
    else {
        Toast.makeText(this, "Network is unavailable!", Toast.LENGTH_LONG).show();      //ERROR
    }

    //String message = getString(R.string.no_items);
    //Toast.makeText(this, message, Toast.LENGTH_LONG).show();

}

@Override
protected void onListItemClick(ListView l, View v, int position, long id) {  //ERROR
    super.onListItemClick(l, v, position, id);
    try {
    JSONArray jsonPosts = mBlogData.getJSONArray("posts");
    JSONObject jsonPost = jsonPosts.getJSONObject(position);
    String blogUrl = jsonPost.getString("url");

    Intent intent = new Intent(this,BlogWebViewActivity.class);    //ERROR
    intent.setData(Uri.parse(blogUrl));
    startActivity(intent);
}
    catch (JSONException e) {
        logException(e);
    }
}

private void logException(Exception e) {
    Log.e(TAG, "Exception caught!", e);
}

private boolean NetworkIsAvailable() {
    ConnectivityManager manager = (ConnectivityManager) 
            getSystemService(Context.CONNECTIVITY_SERVICE);  //ERROR
    NetworkInfo networkInfo = manager.getActiveNetworkInfo();

    boolean isAvailable = false;
    if(networkInfo != null && networkInfo.isConnected()) {
        isAvailable = true;
    }
    return isAvailable;
}

public void handleBlogResponse() {
    mProgressBar.setVisibility(View.INVISIBLE);
    if (mBlogData == null) {
        updateDisplayForError();
    }
    else {
        try {
            JSONArray jsonPosts = mBlogData.getJSONArray("posts");
            ArrayList<HashMap<String, String>> blogPosts = new ArrayList<HashMap<String, String>>();
            for (int i = 0; i < jsonPosts.length(); i++) {
                JSONObject post = jsonPosts.getJSONObject(i);
                String title = post.getString(KEY_TITLE);
                title = Html.fromHtml(title).toString();
                String date = post.getString(KEY_DATE);
                date = Html.fromHtml(date).toString();

                HashMap<String, String> blogPost = new HashMap<String, String>();
                blogPost.put(KEY_TITLE, title);
                blogPost.put(KEY_DATE, date);

                blogPosts.add(blogPost);
            }
            String[] keys = { KEY_TITLE, KEY_DATE };
            int[] ids = { android.R.id.text1, android.R.id.text2 };
            SimpleAdapter adapter = new SimpleAdapter(this, blogPosts, android.R.layout.simple_list_item_2, keys, ids);   //ERROR
            setListAdapter(adapter);
        } catch (JSONException e) {
            logException(e);
        }
    }

}


private void updateDisplayForError() {
    AlertDialog.Builder builder = new AlertDialog.Builder(this);    // ERROR
    builder.setTitle(getString(R.string.error_title));
    builder.setMessage(getString(R.string.error_message));
    builder.setPositiveButton(android.R.string.ok, null);
    AlertDialog dialog = builder.create();
    dialog.show();

    TextView emptyTextView = (TextView) getListView().getEmptyView();
    emptyTextView.setText(getString(R.string.no_items));
}

private class GetBlogPostsTask extends AsyncTask<Object, Void, JSONObject> {

    @Override
    protected JSONObject doInBackground(Object... params) {
        int responseCode = -1;
        JSONObject jsonResponse = null;
        StringBuilder builder = new StringBuilder();
        HttpClient client = new DefaultHttpClient();
        HttpGet httpget = new HttpGet("http://www.ilovelimerick.ie/?json=1&count=");

        try {
            HttpResponse response = client.execute(httpget);
            StatusLine statusLine = response.getStatusLine();
            responseCode = statusLine.getStatusCode();

            if (responseCode == HttpURLConnection.HTTP_OK) {
                HttpEntity entity = response.getEntity();
                InputStream content = entity.getContent();
                BufferedReader reader = new BufferedReader(new InputStreamReader(content));
                String line;
                while((line = reader.readLine()) != null){
                    builder.append(line);
                }

                jsonResponse = new JSONObject(builder.toString());
            }
            else {
                Log.i(TAG, String.format("Unsuccessful HTTP response code: %d", responseCode));
            }
        }
        catch (JSONException e) {
            logException(e);
        }
        catch (Exception e) {
            logException(e);
        }           

        return jsonResponse;
    }   

    @Override
    protected void onPostExecute(JSONObject result) {
        mBlogData = result;
        handleBlogResponse();
    }

}

}

the change worked for changing private to public but moving mProgress Bar is still showing an error even though I moved it into the onCreateView:

public class NewsFragment extends ListFragment{

public static final int NUMBER_OF_POSTS = 20;
public static final String TAG = NewsFragment.class.getSimpleName();
protected JSONObject mBlogData;
protected ProgressBar mProgressBar;

private final String KEY_TITLE = "title";
private final String KEY_DATE = "date";

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.fragment_news_list,
            container, false);
    mProgressBar = (ProgressBar) findViewById(R.id.progressBar1); //ERROR

    return rootView;
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    if(NetworkIsAvailable())    {
        mProgressBar.setVisibility(View.VISIBLE);
        GetBlogPostsTask getBlogPostsTask = new GetBlogPostsTask();
        getBlogPostsTask.execute();
    }
    else {
        Toast.makeText(this, "Network is unavailable!", Toast.LENGTH_LONG).show(); //ERROR
    }

    //String message = getString(R.string.no_items);
    //Toast.makeText(this, message, Toast.LENGTH_LONG).show();

}

@Override
public void onListItemClick(ListView l, View v, int position, long id) {
    super.onListItemClick(l, v, position, id);
    try {
    JSONArray jsonPosts = mBlogData.getJSONArray("posts");
    JSONObject jsonPost = jsonPosts.getJSONObject(position);
    String blogUrl = jsonPost.getString("url");

    Intent intent = new Intent(this,BlogWebViewActivity.class); //ERROR
    intent.setData(Uri.parse(blogUrl));
    startActivity(intent);
}
    catch (JSONException e) {
        logException(e);
    }
}

private void logException(Exception e) {
    Log.e(TAG, "Exception caught!", e);
}

private boolean NetworkIsAvailable() {
    ConnectivityManager manager = (ConnectivityManager) 
            getSystemService(Context.CONNECTIVITY_SERVICE); //ERROR
    NetworkInfo networkInfo = manager.getActiveNetworkInfo();

    boolean isAvailable = false;
    if(networkInfo != null && networkInfo.isConnected()) {
        isAvailable = true;
    }
    return isAvailable;
}

public void handleBlogResponse() {
    mProgressBar.setVisibility(View.INVISIBLE);
    if (mBlogData == null) {
        updateDisplayForError();
    }
    else {
        try {
            JSONArray jsonPosts = mBlogData.getJSONArray("posts");
            ArrayList<HashMap<String, String>> blogPosts = new ArrayList<HashMap<String, String>>();
            for (int i = 0; i < jsonPosts.length(); i++) {
                JSONObject post = jsonPosts.getJSONObject(i);
                String title = post.getString(KEY_TITLE);
                title = Html.fromHtml(title).toString();
                String date = post.getString(KEY_DATE);
                date = Html.fromHtml(date).toString();

                HashMap<String, String> blogPost = new HashMap<String, String>();
                blogPost.put(KEY_TITLE, title);
                blogPost.put(KEY_DATE, date);

                blogPosts.add(blogPost);
            }
            String[] keys = { KEY_TITLE, KEY_DATE };
            int[] ids = { android.R.id.text1, android.R.id.text2 };
            SimpleAdapter adapter = new SimpleAdapter(this, blogPosts, android.R.layout.simple_list_item_2, keys, ids); //ERROR
            setListAdapter(adapter);
        } catch (JSONException e) {
            logException(e);
        }
    }

}


private void updateDisplayForError() {
    AlertDialog.Builder builder = new AlertDialog.Builder(this);    //ERROR
    builder.setTitle(getString(R.string.error_title));
    builder.setMessage(getString(R.string.error_message));
    builder.setPositiveButton(android.R.string.ok, null);
    AlertDialog dialog = builder.create();
    dialog.show();

    TextView emptyTextView = (TextView) getListView().getEmptyView();
    emptyTextView.setText(getString(R.string.no_items));
}

private class GetBlogPostsTask extends AsyncTask<Object, Void, JSONObject> {

    @Override
    protected JSONObject doInBackground(Object... params) {
        int responseCode = -1;
        JSONObject jsonResponse = null;
        StringBuilder builder = new StringBuilder();
        HttpClient client = new DefaultHttpClient();
        HttpGet httpget = new HttpGet("http://www.ilovelimerick.ie/?json=1&count=");

        try {
            HttpResponse response = client.execute(httpget);
            StatusLine statusLine = response.getStatusLine();
            responseCode = statusLine.getStatusCode();

            if (responseCode == HttpURLConnection.HTTP_OK) {
                HttpEntity entity = response.getEntity();
                InputStream content = entity.getContent();
                BufferedReader reader = new BufferedReader(new InputStreamReader(content));
                String line;
                while((line = reader.readLine()) != null){
                    builder.append(line);
                }

                jsonResponse = new JSONObject(builder.toString());
            }
            else {
                Log.i(TAG, String.format("Unsuccessful HTTP response code: %d", responseCode));
            }
        }
        catch (JSONException e) {
            logException(e);
        }
        catch (Exception e) {
            logException(e);
        }           

        return jsonResponse;
    }   

    @Override
    protected void onPostExecute(JSONObject result) {
        mBlogData = result;
        handleBlogResponse();
    }

}

}

That worked! and thank you for the heads up, just one more thing actually. Is it the same deal so with the error on the line of code:

Toast.makeText(this, "Network is unavailable!", Toast.LENGTH_LONG).show();

this is the error:

The method makeText(Context, CharSequence, int) in the type Toast is not applicable for the arguments (NewsFragment, String, int)

So would the line now be: Toast.makeText(getActivity(), "Network is unavailable!", Toast.LENGTH_LONG).show();

That's correct!

cool! Thank you for all your help, really appreciate it