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);
}
});
}
}
}
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);
}. . .
}