【问题标题】:Adding items to spinner dynamically in AsyncTask在 AsyncTask 中动态地将项目添加到微调器
【发布时间】:2017-01-23 19:57:35
【问题描述】:

我在 SO 上关注了一些线程,但我无法让它工作,即使我觉得它与示例匹配并且我不知道为什么。

我创建了一个简单的微调器。在我的 AsyncTaskRunner 类中,我从 REST API 中提取信息,然后在 onPostExecute 中尝试将其添加到微调器中。但是当我调试/运行我的应用程序时,微调器内容为空.调试时 webChannelList 肯定不为空并且有内容

如果我不尝试动态添加任何内容,而只是在 onCreate 方法中手动添加内容,它就可以正常工作。但出于现实目的,我正在尝试动态添加。

SO 说要传入我所做的 MainActivity.. 但它不起作用。救命!

解决方案:我的 doInBackground 函数中有Debug.waitForDebugger();...一旦我删除它就可以完美运行。

<Spinner
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/singularSpinner" />

我省略了与我要问的内容无关的内容

public class MainActivity extends AppCompatActivity {

  // Global Variables
  private List<String> webChannelList = new ArrayList<String>();
  private Spinner spinner;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);

      // Load Singular Web Channels into GUI
      AsyncTaskRunner runner = new AsyncTaskRunner(this);
      runner.execute();
  }

  class AsyncTaskRunner extends AsyncTask<Void, Void, Void> {

      MainActivity mainActivity;

      @Override
      protected Void doInBackground(Void... params) {
        Debug.waitForDebugger();  //REMOVING THIS WORKS            
        webChannelList = StuffFromAPI();
        return null;
      }

      @Override
      protected void onPostExecute(Void result) {
        if (!webChannelList.isEmpty()) {
          spinner = (Spinner) findViewById(R.id.singularSpinner);

          // Creating adapter for spinner
          ArrayAdapter<String> dataAdapter =
                new ArrayAdapter<String>(mainActivity, android.R.layout.simple_spinner_item, webChannelList);

          // Drop down layout style - list view with radio button
          dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

          // Attaching data adapter to spinner
          spinner.setAdapter(dataAdapter);
      }
    }
  }
}

编辑: 所以我省略了 StuffFromAPI() 函数,只是使用 webChannelList.add("hello"); 手动添加了东西;例如,它完美地从 StuffFromAPI() 函数运行.. 奇怪的是,即使我只是将它注释掉并手动添加了一些东西。几乎就像它的缓存?但是现在我无法复制它..所以发生了一些事情,我不知道是什么。我是 Android 开发的新手,也许我缺少一些非常明显的东西。我所做的只是去构建 --> 运行或构建 --> 调试并且我连接了一个平板电脑

编辑 2: onPostExecute 函数是否有可能在从我的 API 中获取项目之前运行?这仍然没有意义,因为我在调试时实际看到了其中的内容,但它仍然没有显示在 GUI 中

【问题讨论】:

  • 您是否检查过您是否从StuffFromAPI() 方法中获取了字符串列表?
  • @AjayP.Prajapati 是的,这是我检查的第一件事。我在那里放了一个断点,我清楚地看到了我要添加的字符串内容。感谢您的意见

标签: android android-layout android-asynctask


【解决方案1】:

Edit2 的回应:是的,这完全取决于您的 API 调用是否是异步的。您应该检查返回的数组列表的大小。你是如何获取数据的?

这不是您的问题,但我建议您以不同的方式安排代码。

为 ArrayAdapter 和响应数据列表 webChannelList 创建成员。然后在 onPostExecute 中,您需要做的就是调用通知数据已更改。这更灵活,更容易维护。

ArrayList<someType> webChannelList = new ArrayList<>();

protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);

            spinner = (Spinner) findViewById(R.id.singularSpinner);

            // Creating adapter for spinner
            dataAdapter = new ArrayAdapter<String>(mainActivity, android.R.layout.simple_spinner_item, webChannelList);

            // Drop down layout style - list view with radio button
            dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

            // Attaching data adapter to spinner
            spinner.setAdapter(dataAdapter);

            // Load Singular Web Channels into GUI
            AsyncTaskRunner runner = new AsyncTaskRunner(this);
            runner.execute();
        }

        class AsyncTaskRunner extends AsyncTask<Void, Void, Void> {

            MainActivity mainActivity;

            @Override
            protected Void doInBackground(Void... params) {
                webChannelList = StuffFromAPI();
                return null;
            }

            @Override
            protected void onPostExecute(Void result) {
                dataAdapter.notifyDataSetChanged();

            }
        }

【讨论】:

  • 感谢您的回复。我在 onPostExecute 中有一个检查“if (!webChannelList.isEmpty()) {” 我没有放入 OP .. 所以这没有意义我只是在 doInBackground 函数中非常简单地进行调用.一旦我弄清楚为什么这不起作用,我一定会研究您的结构建议。谢谢
  • 我现在正在查看您的建议。您是否缺少将 dataAdapter 声明为全局变量?
  • 是的,将其添加为类成员。
  • 我刚刚注意到了,但是为什么在AsyncTask中声明了MainActivity?
  • 我是 Android 新手.. 否则我不知道如何传递它。我只是想将 MainActivity 存储到一个变量中,以便我可以在 AsyncTask 中使用它。如果你能告诉我正确的方式会很酷。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-24
  • 1970-01-01
  • 1970-01-01
  • 2011-07-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多