0

I'm unable to refresh my CustomListAdapter object which extends ArrayAdapter, the method notifyDataSetChanged() is not available on it. I can call this within the object itself though.

Knowing this, I have created a method in the custom adapter class like so:

public void refreshAdapter(){
    notifyDataSetChanged();
}

but I'm unable to call this method in the activity where I create the adapter object so I'm back to square one. Why am I unable to call this method and notifyDataSetChanged()?

Here is my Adapter as requested:

import android.content.Context;
import android.content.SharedPreferences;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.TextView;

import com.henleyb.aeropressbrewer.R;
import com.henleyb.aeropressbrewer.model.CoffeeClass;

public class RecipeDetailsListAdapter extends ArrayAdapter {

    public SharedPreferences sharedPrefs;

    private TextView greenBox;
    private TextView peachBox;
    private String grindSize = "non set";
    private String tempType;

    public RecipeDetailsListAdapter(Context context, String[] values) {
        super(context, R.layout.d_brew_coffee_list_item, values);

        sharedPrefs = context.getSharedPreferences("com.henleyb.aeropressbrewer", 0);

    }

    public void refreshAdapter(){
        notifyDataSetChanged();
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        LayoutInflater theInflater = LayoutInflater.from(getContext());

        View theView = theInflater.inflate(R.layout.d_brew_coffee_list_item, parent, false);

        // text for the list items (changes to populate everything)
        greenBox = (TextView) theView.findViewById(R.id.tvGreenText);
        peachBox = (TextView) theView.findViewById(R.id.tvPeachText);

        // Depending on the position of the list, we change the row data to suit
        switch (position) {
            case 0:
                getGrams();
                break;
            case 1:
                getTemp();
                Log.i("HEN","We're in getTemp switch");
                break;
            case 2:
                getGrindSize();
                break;
            case 3:
                getInverted();
                break;
            default:
                Log.i("HEN", "INVALID SWITCH POS");

        }
        notifyDataSetChanged();

        return theView;
    }

    private void getGrams() {
        Log.v("HEN", "position = 0");


        greenBox.setText("Grams");
        peachBox.setText(Integer.toString(CoffeeClass.getCurrentSelectedCoffeeObject().getRecipeDetailsGrams()));

    }

    private void getTemp() {


        Log.i("HEN","We're in getTemp method!");
        greenBox.setText("Temp");

        tempType = sharedPrefs.getString("TEMPTYPE", "fahrenheit");

        switch (tempType) {
            case "celsius":
                Log.i("HEN","tempType now celsius");
                peachBox.setText(String.valueOf((int) CoffeeClass.getCurrentSelectedCoffeeObject().getRecipeDetailsTemp()) + "\u00b0C");
                break;

            case "fahrenheit":
                peachBox.setText(String.valueOf((int) CoffeeClass.getCurrentSelectedCoffeeObject().getRecipeDetailsTemp()) + "\u00b0f");
                break;
            default:
                peachBox.setText(String.valueOf((int) CoffeeClass.getCurrentSelectedCoffeeObject().getRecipeDetailsTemp()) + "!");
        }
    }

    private void getGrindSize() {
        Log.v("HEN", "position = 1");
        greenBox.setText("Grind Size");
        peachBox.setText(convertGrindSize());

    }

    private void getInverted() {
        Log.v("HEN", "position = 3");
        greenBox.setText("Inverted?");

        if (CoffeeClass.getCurrentSelectedCoffeeObject().getBrewID() == 1) {
            if (CoffeeClass.getCurrentSelectedCoffeeObject().getRecipeInverted()) {
                peachBox.setText("YES");
            } else {
                peachBox.setText("NO");
            }
        } else {
            peachBox.setText("NA");
        }
    }

    private String convertGrindSize() {
        Integer gs = CoffeeClass.getCurrentSelectedCoffeeObject().getRecipeDetailsGrindSize();

        if (gs >= 0 && gs <= 20) {
            grindSize = "Turkish";
        } else if (gs > 20 && gs <= 30) {
            grindSize = "Very \nFine";
        } else if (gs > 30 && gs <= 40) {
            grindSize = "Fine";
        } else if (gs > 40 && gs <= 50) {
            grindSize = "Medium \nFine";
        } else if (gs > 50 && gs <= 60) {
            grindSize = "Medium";
        } else if (gs > 60 && gs <= 70) {
            grindSize = "Medium \nCoarse";
        } else if (gs > 70 && gs <= 80) {
            grindSize = "Coarse";
        } else if (gs > 80 && gs <= 90) {
            grindSize = "Very \nCoarse";
        } else if (gs > 90 && gs <= 100) {
            grindSize = "Like Huge \nBoulders";
        }

        return grindSize;
    }


}
Mint_Sauce
  • 55
  • 1
  • 11

3 Answers3

1

dont change the data of the Adapter, change the data's source

1

when you change in valueReceipe from MainActivity:

valueReceipe[i] = "Maggiie";

Then call refresh emthod :

RecipeDetailsListAdapter adapter = new RecipeDetailsListAdapter(getApplicationContext(), valueRecipe);

adapter.refreshAdapter(valueReceipe);

Change refreshAdapter() body like this :

public void refreshAdapter(String[] changedValues){
    values = changedValues;
    this.notifyDataSetChanged();
}

Declare values String[] also :

private String[] values;    // define above constructor
Kushal
  • 8,100
  • 9
  • 63
  • 82
1
  1. You DON'T need the:

    public void refreshAdapter() {
    
        notifyDataSetChanged();
    }
    

notifyDataSetChanged is a public method and it is available.

  1. You are never referencing the String[] values,(by using getItem(position)) which is the whole point of ArrayAdapter and notifyDataSetChanged(). notifyDataSetChanged() is meant to be called from the outside when you change the items of collection used in the Adapter (values in your case):

    values[5] = "My changed item";
    
    adapter.notifyDataSetChanged();
    

As Steve Jobs would say: 'You're holding it wrong' ;)

  • Thank you for this, I see you're right! Ok, so the adapter takes the data once and then constructs the views to populate the list using getView which works on the data provided. Should I pass in all my data to my 'values' variable that I'm going to be working on, and then use getView to 'switch case' it to show what i want for each list item? – Mint_Sauce Mar 18 '15 at 13:43
  • In get view you can use getItem(postition) to get the element stored in the supporting collection. Say you have array of strings - like {"One", "Two", "Three"}. If you pass this to your adapter on creation, in getView, it will iterate through visible cells and pass you the position. So for cell one you will get from getItem(position) -> "One" and so on. You can then use this info to populate cell view as you see fit. Hope this helps. If you change the array say add one more {..., "Four"} calling notifyDataSetChanged will trigger the update of the table. – Nemanja Maksimovic Mar 18 '15 at 14:31