We have code that creates a list view with detailed view upon click. There is a wrapper class called drink content containing a drink object and a static code segment that makes a call to an asyncTask that calls our web service. We need to build the URL based on data from another activity but I don't understand the way in which the object is created. We can't seem to replace the general DrinkContent references in the list and detail fragments with a single reference to an instantiated instance of DrinkContent. We wanted to use the instantiated instance of drink content so we could write a constructor that would take in URL parameters generated during another activity. We can pass the URL data to the fragments, but when a constructor was written multiple instances of Drink content were being created and our web service request didn't work. We are storing the parameters in another activities shared preferences and passing them to the new activity.
Code for DrinkListActivity:
package com.cs4720.drinkengine_android;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.NavUtils;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
public class DrinkListActivity extends FragmentActivity
implements DrinkListFragment.Callbacks {
private boolean mTwoPane;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_drink_list);
if (findViewById(R.id.drink_detail_container) != null) {
mTwoPane = true;
((DrinkListFragment) getSupportFragmentManager()
.findFragmentById(R.id.drink_list))
.setActivateOnItemClick(true);
}
Button button = (Button) findViewById(R.id.button1);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent i = new Intent(DrinkListActivity.this, LeaderboardActivity.class);
startActivity(i);
}
});
}
public void onItemSelected(String id) {
if (mTwoPane) {
Bundle arguments = new Bundle();
arguments.putString(DrinkDetailFragment.ARG_ITEM_ID, id);
DrinkDetailFragment fragment = new DrinkDetailFragment();
fragment.setArguments(arguments);
getSupportFragmentManager().beginTransaction()
.replace(R.id.drink_detail_container, fragment)
.commit();
} else {
Intent detailIntent = new Intent(this, DrinkDetailActivity.class);
detailIntent.putExtra(DrinkDetailFragment.ARG_ITEM_ID, id);
startActivity(detailIntent);
}
}
}
code for DrinkListFragment
package com.cs4720.drinkengine_android;
import com.cs4720.drinkengine_android.dummy.DrinkContent;
import com.cs4720.drinkengine_android.dummy.DrinkContent.GetDrinksTask;
import android.R;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.ListFragment;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ListView;
public class DrinkListFragment extends ListFragment {
private static final String STATE_ACTIVATED_POSITION = "activated_position";
private Callbacks mCallbacks = sDummyCallbacks;
private int mActivatedPosition = ListView.INVALID_POSITION;
public interface Callbacks {
public void onItemSelected(String id);
}
private static Callbacks sDummyCallbacks = new Callbacks() {
public void onItemSelected(String id) {
}
};
public DrinkListFragment() {
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setListAdapter(new ArrayAdapter<DrinkContent.Drink>(getActivity(),
R.layout.simple_list_item_activated_1,
R.id.text1,
DrinkContent.ITEMS));
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
if (savedInstanceState != null && savedInstanceState
.containsKey(STATE_ACTIVATED_POSITION)) {
setActivatedPosition(savedInstanceState.getInt(STATE_ACTIVATED_POSITION));
}
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
if (!(activity instanceof Callbacks)) {
throw new IllegalStateException("Activity must implement fragment's callbacks.");
}
mCallbacks = (Callbacks) activity;
}
@Override
public void onDetach() {
super.onDetach();
mCallbacks = sDummyCallbacks;
}
@Override
public void onListItemClick(ListView listView, View view, int position, long id) {
super.onListItemClick(listView, view, position, id);
mCallbacks.onItemSelected(DrinkContent.ITEMS.get(position).name);
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
if (mActivatedPosition != ListView.INVALID_POSITION) {
outState.putInt(STATE_ACTIVATED_POSITION, mActivatedPosition);
}
}
public void setActivateOnItemClick(boolean activateOnItemClick) {
getListView().setChoiceMode(activateOnItemClick
? ListView.CHOICE_MODE_SINGLE
: ListView.CHOICE_MODE_NONE);
}
public void setActivatedPosition(int position) {
if (position == ListView.INVALID_POSITION) {
getListView().setItemChecked(mActivatedPosition, false);
} else {
getListView().setItemChecked(position, true);
}
mActivatedPosition = position;
}
}
code for DrinkDetailActivity
package com.cs4720.drinkengine_android;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.NavUtils;
import android.view.MenuItem;
public class DrinkDetailActivity extends FragmentActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_drink_detail);
getActionBar().setDisplayHomeAsUpEnabled(true);
if (savedInstanceState == null) {
Bundle arguments = new Bundle();
arguments.putString(DrinkDetailFragment.ARG_ITEM_ID,
getIntent().getStringExtra(DrinkDetailFragment.ARG_ITEM_ID));
DrinkDetailFragment fragment = new DrinkDetailFragment();
fragment.setArguments(arguments);
getSupportFragmentManager().beginTransaction()
.add(R.id.drink_detail_container, fragment)
.commit();
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
NavUtils.navigateUpTo(this, new Intent(this, DrinkListActivity.class));
return true;
}
return super.onOptionsItemSelected(item);
}
}
code for drinkDetailFragment
package com.cs4720.drinkengine_android;
import com.cs4720.drinkengine_android.dummy.DrinkContent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public class DrinkDetailFragment extends Fragment {
public static final String ARG_ITEM_ID = "item_id";
DrinkContent.Drink mItem;
public DrinkDetailFragment() {
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments().containsKey(ARG_ITEM_ID)) {
mItem = DrinkContent.ITEM_MAP.get(getArguments().getString(ARG_ITEM_ID));
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_drink_detail, container, false);
if (mItem != null) {
String miss="";
if(mItem.missing == 0){
miss = "You can make this Drink!";
}
else{
miss = "Missing "+ mItem.missing + " ingredients";
}
StringBuilder sb = new StringBuilder();
sb.append("Name: " + mItem.name
+ "\n" + miss
+ "\nDecription: " + mItem.description
+ "\nCalories: " + mItem.calories
+ "\nStrength: " + mItem.strength
+ "\nIngredients: \n");
for(int i = 0; i < mItem.units.size(); i++)
sb.append(mItem.units.get(i) + " " + mItem.ingredients.get(i) + "\n");
((TextView) rootView.findViewById(R.id.drink_detail)).setText(sb.toString());
}
return rootView;
}
}
code for DrinkContent
package com.cs4720.drinkengine_android.dummy;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONObject;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.util.Log;
public class DrinkContent {
public static class Drink {
public String name;
public int missing;
public String description;
public int calories;
public int strength;
public List<String> units;
public List<String> ingredients;
public Drink(String name) {
super();
this.name = name;
}
@Override
public String toString() {
return name;
}
}
public static String url = "http://drinkengine.appspot.com/view";
public static List<Drink> ITEMS = new ArrayList<Drink>();
public static Map<String, Drink> ITEM_MAP = new HashMap<String, Drink>();
static{
new GetDrinksTask().execute(url);
}
private static void addItem(Drink item) {
ITEMS.add(item);
ITEM_MAP.put(item.name, item);
}
public static String getJSONfromURL(String url) {
// initialize
InputStream is = null;
String result = "";
// http post
try {
HttpClient httpclient = new DefaultHttpClient();
HttpGet httpget = new HttpGet(url);
HttpResponse response = httpclient.execute(httpget);
HttpEntity entity = response.getEntity();
is = entity.getContent();
} catch (Exception e) {
Log.e("DrinkEngine", "Error in http connection " + e.toString());
}
// convert response to string
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(
is, "iso-8859-1"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
is.close();
result = sb.toString();
} catch (Exception e) {
Log.e("DrinkEngine", "Error converting result " + e.toString());
}
return result;
}
// The definition of our task class
public static class GetDrinksTask extends AsyncTask<String, Integer, String> {
SharedPreferences prefs;
@Override
protected void onPreExecute() {
}
@Override
protected String doInBackground(String... params) {
String url = params[0];
ArrayList<Drink> lcs = new ArrayList<Drink>();
try {
String webJSON = getJSONfromURL(url);
JSONArray drinks = new JSONArray(webJSON);
for (int i = 0; i < drinks.length(); i++) {
JSONObject jo = drinks.getJSONObject(i);
Drink current = new Drink(jo.getString("name"));
current.missing = Integer.parseInt(jo.getString("missing"));
current.description = jo.getString("description");
current.calories = Integer.parseInt(jo.getString("calories"));
current.strength = Integer.parseInt(jo.getString("strength"));
JSONArray units = jo.getJSONArray("units");
current.units = new ArrayList<String>();
for(int j = 0; j < units.length(); j++){
current.units.add(units.getString(j));
}
JSONArray ingredients = jo.getJSONArray("ingredients");
current.ingredients = new ArrayList<String>();
for(int j = 0; j < ingredients.length(); j++){
current.ingredients.add(ingredients.getString(j));
}
addItem(current);
}
} catch (Exception e) {
Log.e("DrinkEngine", "JSONPARSE:" + e.toString());
}
return "Done!";
}
@Override
protected void onProgressUpdate(Integer... ints) {
}
@Override
protected void onPostExecute(String result) {
// tells the adapter that the underlying data has changed and it
// needs to update the view
}
}
}
So now that youve seen the code the question might make more sense. We need to access our URL params from within drink content. But those parameters changed based on user input from another activity. We store those params in the other activities shared prefs and them pass them the DrinkListActivity and attempted to write a constructor that would take in the params and build the url properly. This did not work when we replaced the generalized DrinkContent and DrinkContent.LIST references with our instance we created. So basically how do we get the info inside of this class from our shared prefs?