【问题标题】:update listView on a fragment in Android在Android中的片段上更新listView
【发布时间】:2017-09-12 04:45:12
【问题描述】:

我无法在 Android 上更新 listView。我有一个带有 listView 的片段,它的项目由 REST 调用返回。

这里是异步任务:

 private class GetMenuPizzeria extends AsyncTask<String, Void, Object[]> {
    private final SelectPizzaFragment.ContentAdapter mListAdapter;
    private final Context appContext;
    private final String pizzeriaId;

    private GetMenuPizzeria(ContentAdapter mListAdapter, Context appContext, String id) {
        this.mListAdapter = mListAdapter;
        this.appContext = appContext;
        this.pizzeriaId = id;
    }

    @Override
    protected Object[] doInBackground(String... params) {
            return pizzeriaManager.getMenuPizzeria(pizzeriaId).toArray();
    }

    @Override
    protected void onPostExecute(Object[] result) {
        mListAdapter.updateItems(result, appContext);
    }
}

这里是调用 onPostExecute (updateItems) 的函数:

public void updateItems(Object[] newItems, Context appContext) {

            PizzaMenu pm;

            lPizzaNames.clear();
            lPizzaDesc.clear();
            lPizzaPrices.clear();

            Resources resources = appContext.getResources();
            TypedArray a = resources.obtainTypedArray(R.array.place_avator);

            for (int i = 0; i < newItems.length; i++) {
                pm = (PizzaMenu) newItems[i];
                lPizzaNames.add(pm.getName());
                lPizzaDesc.add(pm.getIngredients());
                lPizzaPrices.add(pm.getPrice());
                lPlaceAvators.add(a.getDrawable(0));
            }
            this.notifyDataSetChanged();
    }

然后,我这样调用 AsyncTask:

GetMenuPizzeria getMenuPizzeria = new GetMenuPizzeria(adapter, this.getContext(), id);
getMenuPizzeria.execute();

当我第一次调用它时,它在我的片段的 onCreateView 内起作用。 问题是,每次选择的比萨店发生变化时,我都要更新列表,所以我写了一个方法:

public void updatePizzeriaMenu(String idPizzeria) {
    GetMenuPizzeria getMenuPizzeria = new GetMenuPizzeria(new ContentAdapter(recyclerView.getContext()), this.getContext(), idPizzeria);
    getMenuPizzeria.execute();
}

该方法正确调用 AsyncTask 并且我没有收到任何错误,除了列表未更新(但调用了 notifyDataSetChanged() 并且还调用了 onBindViewHolder)。我想我检索适配器的方式是错误的或类似的东西,因为我每次调用 updatePizzeriaMenu 时填充的列表似乎都是空的。有人可以帮助我并告诉我我缺少什么吗?提前致谢

编辑:这是我的适配器类:

public static class ContentAdapter extends RecyclerView.Adapter<ViewHolder> {


    private final List<String> lPizzaNames = new ArrayList<String>();
    private final List<String> lPizzaDesc = new ArrayList<String>();
    private final List<String> lPizzaPrices = new ArrayList<String>();

    private final List<Drawable> lPlaceAvators = new ArrayList<Drawable>();

    public ContentAdapter(Context context) {
        Resources resources = context.getResources();
        TypedArray a = resources.obtainTypedArray(R.array.place_avator);
        a.recycle();
    }


    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        return new ViewHolder(LayoutInflater.from(parent.getContext()), parent);
    }

    public void updateItems(Object[] newItems, Context appContext) {
        //see above....
    }


    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        holder.avator.setImageDrawable(lPizzaAvators.get(position % lPizzaAvators.size()));
        holder.name.setText(lPizzaNames.get(position % lPizzaNames.size()));
        holder.description.setText(lPizzaDesc.get(position % lPizzaDesc.size()));
        holder.price.setText(lPizzaPrices.get(position % lPizzaPrices.size()));
    }



    @Override
    public int getItemCount() {
        return lPizzaPrices.size();
    }



}

【问题讨论】:

  • 你能发布你的适配器类吗

标签: android listview android-fragments android-asynctask android-recyclerview


【解决方案1】:

您每次都在 updatePizzeriaMenu(String idPizzeria) 方法中创建新的适配器。但我认为,这些适配器通过recyclerView.setAdapter() 方法与任何recyclerView 无关。所以不要每次都创建新的ContentAdapter,而是传递上一个适配器对象。

public void updatePizzeriaMenu(String idPizzeria) {
    GetMenuPizzeria getMenuPizzeria = new GetMenuPizzeria(adapter, this.getContext(), idPizzeria);
    getMenuPizzeria.execute();
}

因为你正在清除以前的数据

lPizzaNames.clear();
lPizzaDesc.clear();
lPizzaPrices.clear();

并更新新数据,它应该可以正常工作。

【讨论】:

  • 感谢您的回答 Sifat,但我正在创建一个新适配器,因为我用于视图的适配器在公共方法中不可用,所以我试图用以下方法检索它:new ContentAdapter (recyclerView.getContext())
  • 但是 new ContentAdapter(recyclerView.getContext()) 会给出一个新的对象实例。它不会给你之前的对象,对吧?
  • 没错,那么问题来了,如何从fragment内部的公共方法访问当前使用的适配器呢?我的意思是如何获取适配器的当前实例?
  • 您在哪个类中初始化了adapter 变量? updatePizzeriaMenu(String idPizzeria) 方法属于哪个类?他们不是在同一个片段类吗?如果是这样,那么您可以将adapter 变量声明为全局变量。
  • 谢谢你 Sifat,我像你说的那样解决了它,将适配器声明为全局变量(在片段中)。已解决。
【解决方案2】:

你在这个方法中没有更新适配器,你正在给一些变量赋值,而且这些变量似乎与适配器没有任何关系,你必须在适配器中设置对象!

例如,

 this.setPizzaMenuList(pizzaMenuList); 
 this.notifyDataSetChanged)();

将更新 ListView.and

lpizzaMenuList= pizzaMenuList;
this.notifyDataSetChanged)();

不会更新 ListView!

【讨论】:

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