Search code examples
androidclassandroid-listviewandroid-fragmentslistadapter

Android ListAdapter How to Correct: Cannot make a static reference to the non-static method


I'm trying to put some custom list adapters into their own classes to make my app have less redundant code and to make it more manageable.

I call on the different adapter classes thru a conditional statement within a ListFragment. I originally had the adapters in the ListFragment class and this all worked as planed. Now to clean up everything and to get all that code out of the ListFragment, I moved the Adapters out and into their own classes. Since that was done, these methods have to be static so I can call on them but these new classes now containa lot of:

Cannot make a static reference to the non-static method setListAdapter(ListAdapter) from the type ListFragment

Specifically the setListAdapter, setListAdapter, getFragmentManager, and getFragmentManager methods. I don't want a ton of ListView Fragment classes and since a lot of code would be reused, It makes more since to only have one ListFragment and use conditionals to get the correct adapter but I don't know how to fix these new classes so I can use them.

Sorry for the long explanation. I'll try to only post the relevant code to get the idea to what I am trying to accomplish and for you to guide me.

Can this be done the way I am doing this and how do I correct it?

If there is a better way, please post some code with your explination or code in what needs to be changed within my Adapter Class.

In my fragment's onActivityCreated:

. . .

    // Get the string to query from last Fragment and pass it to this
    // Fragment
    Bundle args = this.getArguments();

    boolean rawRes = args.getBoolean(KEY_IS_RAW_RES);
    String url = args.getString(KEY_URL);
    int fileName = args.getInt(KEY_RES_FILE);

    this.getJsonFile(url, rawRes, fileName);

}

public void getJsonFile(String url, boolean rawRes, int fileName) {

    if (rawRes == true) {
        getFromRawRes(fileName);
    } else {
        getFromURL(url);
    }
}

public void getFromRawRes(int fileName) {
        InputStream file = getResources().openRawResource(fileName);
        JSONParser jParser = new JSONParser();
        JSONArray json = jParser.getJSONFromRes(file);
        ListAdapter_SevenItem.callback(json, context);//<--THIS IS A CALL TO THE ADAPTER!!
    }

One of the Adapters:

public class ListAdapter_SevenItem extends ListViewFragment {

. . .

public static void callback(JSONArray json, Context c) {
    if (json != null) {
    // Hashmap for ListView
    . . .
    // create the list item mapping
        String[] from = new String[]{TAG_LABEL, TAG_TITLE, TAG_DISCR, TAG_RES_FILE, TAG_IS_RAW_RES, TAG_CONT_ID};
        int[] to = new int[]{R.id.listLabel, R.id.listTitle, R.id.listDiscription, R.id.listResFile, R.id.listIsRawRes, R.id.listContID};

        // Updating parsed JSON data into ListView
        SimpleAdapter adapter = new SimpleAdapter(c, mList, R.layout.list_item, from, to);
        setListAdapter(adapter);

        // selecting single ListView item
        final ListView lv = setListAdapter();

        // Launching new screen on Selecting Single ListItem
        lv.setOnItemClickListener(new OnItemClickListener() {

            public void onItemClick(AdapterView<?> parent, View view, int pos, long id) {
                MainActivity.mLayout.toggleSidebar();
                setHasOptionsMenu(true);

                FragmentManager fm = getFragmentManager();
                final FragmentTransaction lcFT = fm.beginTransaction();
                lcFT.setCustomAnimations(R.anim.slide_in, R.anim.hyperspace_out, R.anim.hyperspace_in, R.anim.slide_out);

                final Bundle args = new Bundle();

                String resFile = ((TextView) view.findViewById(R.id.listResFile)).getText().toString();
                int passResFile = getFragmentManager().getIdentifier(resFile, "raw", "com.andaero.app");
                args.putInt("KEY_RES_FILE", passResFile);

                boolean isRawRes = true;
                args.putBoolean("KEY_IS_RAW_RES", isRawRes);

                // Delayed to improve animations
                final Handler handler = new Handler();
                handler.postDelayed(new Runnable() {
                    public void run() {
                        ListViewFragment lvf = new ListViewFragment();
                        lcFT.replace(R.id.listContainer, lvf).commit();
                        lvf.setArguments(args);
                    }
                }, 300);
            }
        });
    }
}

}


Solution

  • A ListView Fragment Class that can be reused thru-out an application.

    I use jgilfelt's universal JasonArrayAdapter class that can be downloaded on GitHub. The class here below can be used over and over thru-out the application so its the only ListView class needed - Which means a reduction in redundant code/classes. Esp., if you have list views that require different attributes and/or layouts.

    If your loading this ListViewFragment from another Fragment:

    String uri = "http://www.xxxx/myjsonfile.json";//EXAMPLE IF FROM A URL
    String uri = "json/myjsonfile.json";//EXAMPLE GETTING FROM YOUR ASSETS FOLDER
    args.putString("KEY_URI", uri);
    
    String adptrID = "#";//USED TO DETERMINE WHICH LAYOUT TO USE
    args.putString("KEY_ADPTR_ID", adptrID);
    
    ListViewFragment lvf = new ListViewFragment();
    lcFT.replace(R.id.myContainer, lvf).commit();
    lvf.setArguments(args);
    

    If If your loading this ListViewFragment from within it's self, just add the appropriate items in your JSON files and get them into your setArguments(args) Bundle.

    If you have any improvements/etc to the methods, feel free to add it to your comment/answer. I'm new to Android and learning as I go... Thnx

    ListViewFragment Class:

    public class ListViewFragment extends ListFragment implements OnItemClickListener {
    . . .
        @Override
        public void onActivityCreated(Bundle savedInstanceState) {
            super.onActivityCreated(savedInstanceState);
    
            Bundle getArgs = this.getArguments();
            String URI = getArgs.getString(KEY_URI);
                . . .
            new GetJSONTask().execute(URI);
        }
    
        class GetJSONTask extends AsyncTask<String, Integer, String> {
    
            protected String doInBackground(String... arg0) {
    
                String uri = arg0[0];
    
                InputStream is = null;
    
                if (uri.contains("http") == true) {// Get JSON from URL
                    try {
                        DefaultHttpClient httpClient = new DefaultHttpClient();
                        HttpPost httpPost = new HttpPost(uri);
                        HttpResponse httpResponse = httpClient.execute(httpPost);
                        HttpEntity httpEntity = httpResponse.getEntity();
                        is = httpEntity.getContent();
    
                        BufferedReader rd = new BufferedReader(new InputStreamReader(is, "UTF-8"));
                        while ((line = rd.readLine()) != null) {
                            json += line;
                        }
                        rd.close();
                        return json;
                    } catch (Exception e) {
                        e.printStackTrace();
                        return null;
                      }
                    } else {//Get JSON from Assets
    
                    Writer writer = new StringWriter();
                    char[] buffer = new char[1024];
    
                    try {
                        InputStream jsonFile = getActivity().getAssets().open(uri);
                        Reader reader = new BufferedReader(new InputStreamReader(jsonFile, "UTF-8"));
                        int n;
                        while ((n = reader.read(buffer)) != -1) {
                            writer.write(buffer, 0, n);
                        }
                        jsonFile.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    json = writer.toString();
                    // return JSON String
                    return json;
                }
            }
    
            @Override
            protected void onPostExecute(String result) {
                try {
                    showData(result);
                } catch (JSONException e) {
                    e.printStackTrace();
                    Toast.makeText(getActivity(), "something went wrong", Toast.LENGTH_SHORT).show();
                }
            }
        }
    
        private void showData(String json) throws JSONException {
            JSONObject o = new JSONObject(json);
            JSONArray data = o.getJSONArray("results");
    
            Bundle getArgs = this.getArguments();
            String adptrID = getArgs.getString(KEY_ADPTR_ID);
    
            if (adptrID == "3") {//Adapter for 3 items
                String[] from = new String[]{"label", "title", "description", "uri", "adapterID", "containerID"};
                int[] to = new int[]{R.id.listLabel, R.id.listTitle, R.id.listDiscription, R.id.listURI, R.id.listAdapterID, R.id.listContID};
                ListAdapter adapter = new JSONArrayAdapter(getActivity(), data, R.layout.list_item, from, to, null);
                getListView().setOnItemClickListener(this);
                getListView().setAdapter(adapter);
            }
            if (adptrID == "4") {//Adapter for 4 items - Get the idea?
            . . .
            } . . .//Additional Adapter can be added....
        }
    
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
    
            final Bundle args = new Bundle();
            Bundle getArgs = this.getArguments();
    
            String uri = ((TextView) view.findViewById(R.id.listURI)).getText().toString();
            args.putString("KEY_URI", uri);
    
            String adptrID = ((TextView) view.findViewById(R.id.listAdapterID)).getText().toString();
            args.putString("KEY_ADPTR_ID", adptrID);
    
            String contID = ((TextView) view.findViewById(R.id.listContID)).getText().toString();
            args.putString("KEY_CONTAINER_ID", contID);
    
            //Conditional to determine witch container to load the ListViewFragment(this)
             if (containerID == "listContainer") {
             lcFT.replace(R.id.listContainer, lvf).commit();
             lvf.setArguments(args);
             }
             if (containerID == "someOtherContainer") {
             lcFT.replace(R.id.discriptionListContainer, lvf).commit();
             lvf.setArguments(args);
             }. . .
        }