2017-05-15 12 views
0

私のアンドロイドアプリでは、SwipeRefreshLayoutを使ってListViewを更新したいのですが、onRefresh()メソッドの中でこのタスクの新しいスレッドを作成したいと思います。私のリフレッシュ方法はたくさんのファイルを取得しなければならないので、メインスレッドから呼び出されたときにアプリケーションを一時的にフリーズします。これは、SwipeRefrehLayoutを使用する目的を全面的に崩してしまいます(アプリケーションがリフレッシュしているとき、そうする)。メインスレッドの外部でSetRefreshing(false)を呼び出すことはできません。回避策?

最後の部分は私が問題を抱えている部分です。私はSwipeRefreshLayout.setRefreshing(false)を呼び出して、ファイルを取得した後でリフレッシュanmimationを停止したいと思っています。私はこれをやっている方法は、新しいスレッド内の同じリフレッシュ方法の終わりにsetRefreshingを呼び出すことであるが、問題は、私が作成する方法があります場合、私は思ってい

Only the original thread that created a view hierarchy can touch its views. 

を言って、エラーを取得していますそれを行う最善の方法であるスレッド終了リスナーですが、残念ながら私は解決策なしでこれを数週間研究しました。

誰もがSwipeRefreshLayoutで使用する明白な選択肢はありますか?どんな助けでも大歓迎です。 `

public class Refresher implements Runnable { 

    SwipeRefreshLayout refreshLayout; 
    Context context; 

    public Refresher (Context c, SwipeRefreshLayout rl) { 

     refreshLayout = rl; 
     context = c; 

    } 

    @Override 
    public void run() { 

     //Call the method that fetches the files. 
     ((CategoryMenu) context).RefreshCategories(CategoryMenu.SaveDirectory); 

     //Here's where my error gets thrown. 
     refreshLayout.setRefreshing(false); 
     //I understand why, but I don't know a good workaround. 

    } 

} 

`

+0

から 例はAsyncTask – Denny

+0

@Dennyこれは完全に働い使用してください!私はこの問題を解決として設定できるようにこれを答えとして追加できますか? – TheShadyColombian

+0

確かに、私は答えとして投稿しました – Denny

答えて

0

AsyncTaskを使用すると、UIをスムーズに保つために、バックグラウンドでアクションが実行され、進行状況の更新を取得し、タスクが完了したときに通知を受け取ることができます。 android dev site

private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> { 
    protected Long doInBackground(URL... urls) { 
     int count = urls.length; 
     long totalSize = 0; 
     // do some long running operation on the background 
     for (int i = 0; i < count; i++) { 
      totalSize += Downloader.downloadFile(urls[i]); 
      publishProgress((int) ((i/(float) count) * 100)); 
      // Escape early if cancel() is called 
      if (isCancelled()) break; 
     } 
     // pass the result to onPostExecute() 
     return totalSize; 
    } 

    protected void onProgressUpdate(Integer... progress) { 
     setProgressPercent(progress[0]); 
    } 

    protected void onPostExecute(Long result) { 
     // update the UI when you're done 
     showDialog("Downloaded " + result + " bytes"); 
    } 
} 
1
MainActivity.this.runOnUiThread(new Runnable() { 
      @Override 
      public void run() { 
       // TODO Auto-generated method stub 
       refreshLayout.setRefreshing(false); 
      } 
     }); 

runOnUiThreadで試してみてください:ここで

は私の説明はひどいものだった場合、いくつかのコード(それは理解しやすいだろう)

  public void onRefresh() { 

       // This method performs the actual data-refresh operation. 

       //I used refreshLayout.getContext() instead of the "this" keyword since "this" would return an OnRefreshListener instead of my actual context 
       //I pass my refreshLayout to the constructor so it knows which to stop animating at the end. 
       Thread thread = new Thread (new Refresher(refreshLayout.getContext(), refreshLayout)); 
       thread.start(); 

       //I use this to update the adapter in my ListView after it has been refreshed by my Refresher thread. 
       if (listView != null) 
        listView.setAdapter(new CategoryListAdapter(Categories, refreshLayout.getContext())); 
      } 

私リフレッシャークラスです、これがあなたの問題を解決することを願って

+0

残念ながら、これはまだリフレッシュ時にアプリがフリーズしました。 @DennyはAsyncTaskを使う正しい答えを持っていましたが、それはコメントですので、私はそれを解決して設定することはできません:(私はActivityClass.thisを使って、例えばonClickListenerの中に:) – TheShadyColombian

関連する問題