【问题标题】:ListView Inside a RecyclerViewRecyclerView 中的 ListView
【发布时间】:2018-01-27 03:42:06
【问题描述】:

我正在 Recyclerview 中创建一个列表视图。我正在使用在线获取的数据填充 Recyclerview。 RecyclerView 正在正确填充。我想在单击按钮时在运行时填充列表视图。我正在为按钮定义 onClickListener 并在按钮单击时获取数据并填充将设置为列表视图的适配器。但是数据没有反映在列表视图中。

按钮的onClickListener

 holder.arrow_up.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
                new LoadClothes().execute(order.getOrderId());
        }
    });

Asynctask 用于加载列表视图的详细信息

 private class LoadClothes extends AsyncTask<String, Void, String> {


    @Override
    protected void onPreExecute() {
        super.onPreExecute();
    }

    @Override
    protected String doInBackground(String... strings) {
        String string = "";
        try {
            Request request = new Request.Builder()
                    .url(ORDERCLOTHES)
                    .addHeader("token", BaseApplication.getToken())
                    .addHeader("orderId", strings[0])
                    .build();
            Response response = client.newCall(request).execute();
            string = response.body().string();
            Logger.d(string);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return string;
    }

    @Override
    protected void onPostExecute(String string) {
        super.onPostExecute(string);

        Logger.d(string);

        Gson gson = new Gson();
        Type type = new TypeToken<List<OrderedCloth>>() {
        }.getType();
        cloths = gson.fromJson(string, type);
        viewHolder.listView.setVisibility(ListView.VISIBLE);
        CustomListOrderAdapter adapter = new CustomListOrderAdapter(context, cloths);
        viewHolder.listView.setAdapter(adapter);
        adapter.notifyDataSetChanged();
    }
}

【问题讨论】:

标签: android listview android-studio android-recyclerview


【解决方案1】:

您确定要这样做吗?这似乎是一个设计模式问题。如果您要显示通过 HTTP 请求获取的其他数据,更好的方法可能是另一个包含详细信息的活动。

但是,我认为问题出在“viewHolder”,您从哪里获得该变量?

解决它的一个简单方法似乎是将 ListView 传递给 AsyncTask:

private class LoadClothes extends AsyncTask<String, Void, String> {

    private ListView listView;

    public LoadCloathes(ListView listView) {
        this.listView = listView;
    }

    //...

    @Override
    protected void onPostExecute(String string) {
        super.onPostExecute(string);
        //mostly the same but
        //make sure somehow listview is still available
        listView.setAdapter...
    }
}

然后运行 ​​AsyncTask:

new LoadClothes(listView).execute(order.getOrderId());

正如你所见,AsyncTask 可以在构造函数中接受参数,execute() 方法中的参数是为了支持 AsyncTask 循环,但仍然是一个 Java 类。

【讨论】:

  • 谢谢。它就像一个魅力。但我不明白为什么通过构造函数传递 listview 是有效的,但 listview 的类变量不能工作。
  • 因为 Recycler.Adapter 会从字面上回收 ViewHolder,所以它会将其重新用于另一行,然后您不知道视图实际结束的位置。通过在 onCreate 和 onBind 方法中添加日志进行快速测试,您会看到有时 onCreate 日志不会,但 onBind 日志会。那是因为这个适配器创建了一个视图池,如果它可以通过获取一个视图来拯救其中一个视图而不是膨胀一个新视图来节省内存,它将回收它(这是与 ListView 适配器相比的性能提升)
【解决方案2】:

您不必这样做。 只需制作一个回收器视图,并在其中制作一个具有“垂直”方向的 LinearLayout 而不是 listView。 现在在 recyclerView 的 OnBindViewHolder 中,只需运行一个循环直到 list.size() 并使用 addView() 继续在 linearLayout 中膨胀视图。在 for 循环之前只需 removeAllView()。 这将起作用,并且不会使滚动体验变差。

【讨论】:

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