質問

I'm trying to get a total of the values in my custom cursoradapter. I have added a method that returns an array of values which i call after applying setadapter in my fragment.

Within the adapter, I also have another method that updates the running total, called from bindview.

However, I always get 0 out, and with some logging it appears that even though i call getTotals after I've applied the adapter, getTotals fires way before the adapter is processed.

What I'm after is a way to know once the adapter has finished processing/adding the views so that i can then call getTotals?

A second query is how many times bindView is called. Through trying to debug it would appear that though i have 6 rows in my cursor, my adapter is calling bindview 60 times?!?! So my totals are coming out wrong anyway.

public Dialog onCreateDialog(Bundle savedInstanceState) {

    mLayoutInflater = LayoutInflater.from(getActivity()); 

    db = new MyDatabase(getActivity());
    Cursor c = db.getMealDetails(getArguments().getInt("id"));

    ListView mealDetailsList = new ListView(getActivity());
    LinearLayout headerRow = (LinearLayout) mLayoutInflater.inflate(R.layout.meal_details_row, null, false);
    ((TextView) headerRow.findViewById(R.id.meal_details_row_size)).setText("Size");
    ((TextView) headerRow.findViewById(R.id.meal_details_row_cals)).setText("cals");
    ((TextView) headerRow.findViewById(R.id.meal_details_row_protein)).setText("P");
    ((TextView) headerRow.findViewById(R.id.meal_details_row_carb)).setText("C");
    ((TextView) headerRow.findViewById(R.id.meal_details_row_fat)).setText("F");
    mealDetailsList.addHeaderView(headerRow);




    MealDetailsAdapter mealDetailsAdapter = new MealDetailsAdapter(getActivity(),c);
    mealDetailsList.setAdapter(mealDetailsAdapter);

    mTotals = mealDetailsAdapter.getTotals();
    LinearLayout footerRow = (LinearLayout) mLayoutInflater.inflate(R.layout.meal_details_row, null, false);
    ((TextView) footerRow.findViewById(R.id.meal_details_row_cals)).setText(String.valueOf(mTotals[0]));
    ((TextView) footerRow.findViewById(R.id.meal_details_row_protein)).setText(String.valueOf(mTotals[1]));
    ((TextView) footerRow.findViewById(R.id.meal_details_row_carb)).setText(String.valueOf(mTotals[2]));
    ((TextView) footerRow.findViewById(R.id.meal_details_row_fat)).setText(String.valueOf(mTotals[3]));
    mealDetailsList.addFooterView(footerRow);

    AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
    builder.setView(mealDetailsList);


            // Create the AlertDialog object and return it
    return builder.create();
}

public class MealDetailsAdapter extends CursorAdapter {
private LayoutInflater mLayoutInflater;
private Context mContext;
private int[] mTotals;
private int l = 0;

public MealDetailsAdapter(Context context, Cursor c) {
    super(context, c);
    mContext = context;
    mLayoutInflater = LayoutInflater.from(context);
    mTotals = new int[] {0,0,0,0};
    Log.e("a","totals 0 ="+mTotals[0]);
}

@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
    View v = mLayoutInflater.inflate(R.layout.meal_details_row, parent, false);
    return v;
}

@Override
public void bindView(View v, Context context, Cursor c) {
    Log.e("a","view ="+v.toString());

    String name = c.getString(c.getColumnIndexOrThrow("name"));
    Float protein = Float.parseFloat(c.getString(c.getColumnIndexOrThrow("protein")));
    Float carb = Float.parseFloat(c.getString(c.getColumnIndexOrThrow("carb")));
    Float fat = Float.parseFloat(c.getString(c.getColumnIndexOrThrow("fat")));
    String grams = c.getString(c.getColumnIndexOrThrow("grams"));
    String size = c.getString(c.getColumnIndexOrThrow("quantity_text"));
    String qGram = c.getString(c.getColumnIndexOrThrow("quantity_gram"));
    float ratio = Float.parseFloat(qGram) / Float.parseFloat(grams);
    protein = protein * ratio;
    fat = fat * ratio;
    carb = carb * ratio;
    Float cals = (protein * 4) + (carb * 4) + (fat * 9);

    //String qGram = c.getString(c.getColumnIndexOrThrow("quantity_gram"));
    //String name = c.getString(c.getColumnIndexOrThrow("meal_name"));

    TextView nameTextView = (TextView) v.findViewById(R.id.meal_details_row_name);
    if (nameTextView != null) {
        nameTextView.setText(name);
    }

    TextView sizeTextView = (TextView) v.findViewById(R.id.meal_details_row_size);
    if (sizeTextView != null) {
        sizeTextView.setText(size);
    }

    TextView proteinTextView = (TextView) v.findViewById(R.id.meal_details_row_protein);
    if (proteinTextView != null) {
        proteinTextView.setText(String.format("%.0f", protein));
    }

    TextView carbTextView = (TextView) v.findViewById(R.id.meal_details_row_carb);
    if (carbTextView != null) {
        carbTextView.setText(String.format("%.0f", carb));
    }

    TextView fatTextView = (TextView) v.findViewById(R.id.meal_details_row_fat);
    if (fatTextView != null) {
        fatTextView.setText(String.format("%.0f", fat));
    }

    TextView calsTextView = (TextView) v.findViewById(R.id.meal_details_row_cals);
    if (calsTextView != null) {
        calsTextView.setText(String.format("%.0f", cals));
    }
    int[] tempTotals = new int[]{Math.round(cals),Math.round(protein),Math.round(carb),Math.round(fat)};
    updateTotals(tempTotals);

}

public int[] getTotals() {

    Log.e("a","get totals 0 ="+mTotals[0]);
    return mTotals;
}

public void updateTotals(int[] totals) {


    Log.e("a","l ="+l);
    l++;
    Log.e("a","up totals 0 ="+mTotals[0]);
    Log.e("a","mtotals ="+mTotals.toString());
    Log.e("a","totals ="+totals[0]+" totals ="+totals[1]+"totals ="+totals[2]+"totals ="+totals[3]);
    for (int i = 0; i < totals.length; ++i) {
        mTotals[i] += totals[i];
    }

}
役に立ちましたか?

解決

You can't get total in such way. BindView in adapter will called only when list will draw. And even if you will call getTotals after it will be drawn, you will get wrong answer, because adapter will call bindView only for items on the screen.

As I see, you use cursorAdapter and ListView for only one row. It's not good Idea. ListView is made for large amount of rows. It very complex view, with reusing rows and other optimization technics for large data.

In your case, the best way is to use LayoutInflater to inflate view from xml and bind data like you make it for header view.

EDIT: In case you have really more then one row the best way to make another sql query like this:

SELECT SUM(cal), SUM(carb), SUM(fat) FROM ... WHERE ...

and get data from that query, insted of make calculation in bindView.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top