在 AsyncTask 中动态地将项目添加到微调器

Posted

技术标签:

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

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

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

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

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

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

<Spinner
    android:layout_
    android:layout_
    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 是的,这是我检查的第一件事。我在那里放了一个断点,我清楚地看到了我要添加的字符串内容。感谢您的意见 【参考方案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 中使用它。如果你能告诉我正确的方式会很酷。

以上是关于在 AsyncTask 中动态地将项目添加到微调器的主要内容,如果未能解决你的问题,请参考以下文章

如何将项目添加到 Android 中的微调器?

如何在 doInBackgroung() 时制作 android AsyncTask 加载微调器

如何动态地将选项添加到 Bootstrap 选择器?

根据微调器项目选择更新 ArrayAdapter

在 Android 中动态禁用微调器项目

使用装饰器动态地将方法添加到类中