【问题标题】:Unable to call notifyDataSetChanged on CustomListAdapter无法在 CustomListAdapter 上调用 notifyDataSetChanged
【发布时间】:2015-03-18 10:28:02
【问题描述】:

我无法刷新扩展 ArrayAdapter 的 CustomListAdapter 对象,notifyDataSetChanged() 方法在其上不可用。不过,我可以在对象本身中调用它。

知道了这一点,我在自定义适配器类中创建了一个方法,如下所示:

public void refreshAdapter(){
    notifyDataSetChanged();
}

但我无法在创建适配器对象的活动中调用此方法,所以我回到了原点。为什么我无法调用此方法和 notifyDataSetChanged()?

这是我要求的适配器:

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


}

【问题讨论】:

  • 请参考这个[Link][1]..希望它对你有用[1]:stackoverflow.com/a/23342059/3513479
  • 我不确定你在说什么。 notifyDataSetChanged() 是 ArrayAdapter 的公共方法,所以...它可用... 'public void notifyDataSetChanged() { /* 编译代码 */ }'
  • 发布您的自定义适配器的完整代码。
  • 我已按要求添加了我的 CustomListAdapter,希望对您有所帮助。

标签: android notifydatasetchanged


【解决方案1】:
  1. 你不需要:

    public void refreshAdapter() {
    
        notifyDataSetChanged();
    }
    

notifyDataSetChanged 是一个公共方法,它是可用的。

  1. 您永远不会引用 String[] 值,(通过使用 getItem(position))这是 ArrayAdapter 和 notifyDataSetChanged() 的重点。 notifyDataSetChanged() 意味着当您更改适配器中使用的集合项(您的情况下的值)时从外部调用:

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

正如史蒂夫乔布斯所说:'你搞错了';)

【讨论】:

  • 谢谢你,我明白你是对的!好的,所以适配器获取数据一次,然后构造视图以使用 getView 填充列表,它适用于提供的数据。我是否应该将所有数据传递给我将要处理的“值”变量,然后使用 getView 来“切换大小写”以显示我想要的每个列表项的内容?
  • 在获取视图中,您可以使用 getItem(postition) 获取存储在支持集合中的元素。假设你有一个字符串数组——比如 {"One", "Two", "Three"}。如果您在创建时将此传递给适配器,则在 getView 中,它将遍历可见单元格并将位置传递给您。因此,对于单元格一,您将从 getItem(position) -> "One" 等获得。然后,您可以使用此信息来填充您认为合适的单元格视图。希望这可以帮助。如果您更改数组,说再添加一个 {..., "Four"} 调用 notifyDataSetChanged 将触发表的更新。
【解决方案2】:

不改变Adapter的数据,改变数据的来源

【讨论】:

    【解决方案3】:

    当您从 MainActivity 更改 valueReceipe 时:

    valueReceipe[i] = "Maggiie";
    

    然后调用刷新方法:

    RecipeDetailsListAdapter adapter = new RecipeDetailsListAdapter(getApplicationContext(), valueRecipe);
    
    adapter.refreshAdapter(valueReceipe);
    

    像这样更改 refreshAdapter() 主体:

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

    同时声明值 String[]:

    private String[] values;    // define above constructor
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-16
      相关资源
      最近更新 更多