0

我们有代码可以在单击时创建带有详细视图的列表视图。有一个名为drink content 的包装类,其中包含一个drink 对象和一个静态代码段,该代码段调用调用我们的Web 服务的asyncTask。我们需要根据来自另一个活动的数据构建 URL,但我不明白创建对象的方式。我们似乎无法用对 DrinkContent 实例化实例的单个引用替换列表和详细信息片段中的一般 DrinkContent 引用。我们想使用饮料内容的实例化实例,因此我们可以编写一个构造函数来接收另一个活动期间生成的 URL 参数。我们可以将 URL 数据传递给片段,但是当编写构造函数时,会创建多个 Drink 内容实例,而我们的 Web 服务请求没有 不工作。我们将参数存储在另一个活动共享首选项中,并将它们传递给新活动。

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

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

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

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

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

    }
}
}

所以现在你已经看到了代码,这个问题可能更有意义。我们需要从饮料内容中访问我们的 URL 参数。但是这些参数会根据来自另一个活动的用户输入而改变。我们将这些参数存储在其他活动共享首选项中,并将它们传递给 DrinkListActivity 并尝试编写一个构造函数来接收参数并正确构建 url。当我们用我们创建的实例替换通用的 DrinkContent 和 DrinkContent.LIST 引用时,这不起作用。所以基本上我们如何从我们的共享偏好中获取这个类的信息?

4

1 回答 1

0

SharedPreferences 跨应用程序级别共享,而不仅仅是活动级别。如果设置为公开,它实际上可以在应用程序之间共享。你应该去阅读这里这里的文档,因为它很好地解释了这一点。

于 2012-12-03T07:52:53.527 回答