2017-11-11 253 views
1

首先這是代碼。但這不是真正的代碼。如何使用Retrofit將數據設置爲listview?

API_Interface.java

public interface API_Interface{ 
    @GET("/api/foo") 
    Call<Foo> foo_API(); 
} 

foo.java

public class foo{ 
    @SerializedName("foo") 
    @Expose 
    private String foo; 

    public String getFoo() { 
     return foo; 
    } 

    public void setFoo(String foo) { 
     this.foo = foo; 
    } 
} 

MainActivity.java

public class MainActivity extends AppCompatActivity{ 
    String buzz; 
    Retrofit foo_retro; 

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

     ListView listView = (ListView) findViewById(R.id.list_view); 
     ArrayList<foo> fooList = new ArrayList<foo>(); 
     FooAdapter fooAdapter = new FooAdapter(this, 0, fooList); 
     listView.setAdapter(fooAdapter); 

     ... 

     foo_retro = new Retrofit.Builder() 
       .baseUrl("http://api.foo.com") 
       .addConverterFactory(GsonConverterFactory.create()) 
       .build(); 

     API_Interface foo_service = foo_retro.create(API_Interface.class) 

     Call<foo> foo_call=foo_service.foo_API(); 
     foo_call.enqueue(new Callback<foo>() {    
      @Override 
      public void onResponse(Call<foo> call, Response<foo> response) { 
       buzz = response.body().getFoo(); 
       System.out.println(buzz); 
      } 

      @Override 
      public void onFailure(Call<zaifExchange> call, Throwable t) { 
       Toast.makeText(MainActivity.this, "Error", Toast.LENGTH_SHORT); 
      } 
     }); 
     fooList.add(new foo(buzz)); 
     System.out.println(buzz); 
    } 
} 

當我運行這段代碼,我可以和打印buzz(如「蘋果「)在onResponse方法中。 但是,我無法將數據設置爲listviewbuzz爲空)。 我知道原因是enqueue是異步的,所以終端顯示:

I/System.out: null 
I/System.out: Apple 

那麼,應該怎麼辦? 謝謝。

+0

你的API響應是什麼? – Kuls

+0

onResponse將響應數據設置爲您的數組列表「fooList」,並設置爲適配器 –

回答

3

增加應答到fooListonResponse否則要添加null

@Override 
public void onResponse(Call<foo> call, Response<foo> response) { 
    buzz = response.body().getFoo(); 
    fooList.add(new foo(buzz)); 
    System.out.println(buzz); 
    fooAdapter.notifyDataSetChanged(); 
    // ^^^^ notify changes to display data 
    // you might want to declare references outside oncreate to avoid local variables 
} 

刪除

fooList.add(new foo(buzz)); 
System.out.println(buzz); 

(外enqueue),因爲響應之前buzznull

+0

感謝您的幫助!我可以顯示數據! (需要notifyDataSetChanged()) – NooNoo

+0

@NooNoo我很高興它有幫助,快樂的編碼 –

0

依我之見它,你的問題是雙重的:

  1. 考慮在打印onCreate()方法本身之前延遲添加。更好的是,在繼續之前確認buzz已經設置好。
  2. 因爲enqueue()是異步的,所以無論如何,buzz都可能不會被執行打印的父線程看到。相反,考慮使用AtomicReference類包裝buzz字段。這樣,無論線程如何,最新的值buzz都會被任何線程看到。
+0

'考慮加入一個延遲'壞主意,如果響應來得早和遲,而不是加延遲和2點完全不需要,只添加不需要的非工作複雜性 –

+0

@Pavneet_Singh這是一個公平的點,以及爲什麼我在最後說「更好的是,驗證在繼續之前實際上已設置了嗡嗡聲。」 – entpnerd

+0

,你是對的,雖然建議的解決方案只會帶來更多的代碼和意外的複雜性,在這種情況下,夥計 –

相關問題