2017-03-04 4 views
0

TMDBからデータを取得して、リサイクラビューで表示しています。無限のスクロールリサイクラービューを使用したいので、チュートリアルを見て実装しました。問題は、最初のロード後、最初の5つの要素をスクロールした後、新しいデータでデータ全体がリフレッシュされることです。これをどうやって解決するのですか?私が間違っているRecycler無限のスクロールを正しく表示できない

EndlessRecyclerViewScrollListener.java

public abstract class EndlessRecyclerViewScrollListener extends RecyclerView.OnScrollListener { 
/The minimum amount of items to have below your current scroll position 
// before loading more. 
private int visibleThreshold = 15; 
// The current offset index of data you have loaded 
private int currentPage = 1; 
// The total number of items in the dataset after the last load 
private int previousTotalItemCount = 0; 
// True if we are still waiting for the last set of data to load. 
private boolean loading = true; 
// Sets the starting page index 
private int startingPageIndex = 1; 

RecyclerView.LayoutManager mLayoutManager; 

public EndlessRecyclerViewScrollListener(LinearLayoutManager layoutManager) { 
    this.mLayoutManager = layoutManager; 
} 

public EndlessRecyclerViewScrollListener(GridLayoutManager layoutManager) { 
    this.mLayoutManager = layoutManager; 
    visibleThreshold = visibleThreshold * layoutManager.getSpanCount(); 
} 

public EndlessRecyclerViewScrollListener(StaggeredGridLayoutManager layoutManager) { 
    this.mLayoutManager = layoutManager; 
    visibleThreshold = visibleThreshold * layoutManager.getSpanCount(); 
} 

public int getLastVisibleItem(int[] lastVisibleItemPositions) { 
    int maxSize = 0; 
    for (int i = 0; i < lastVisibleItemPositions.length; i++) { 
     if (i == 0) { 
      maxSize = lastVisibleItemPositions[i]; 
     } 
     else if (lastVisibleItemPositions[i] > maxSize) { 
      maxSize = lastVisibleItemPositions[i]; 
     } 
    } 
    return maxSize; 
} 

// This happens many times a second during a scroll, so be wary of the code you place here. 
// We are given a few useful parameters to help us work out if we need to load some more data, 
// but first we check if we are waiting for the previous load to finish. 
@Override 
public void onScrolled(RecyclerView view, int dx, int dy) { 
    int lastVisibleItemPosition = 0; 
    int totalItemCount = mLayoutManager.getItemCount(); 

    if (mLayoutManager instanceof StaggeredGridLayoutManager) { 
     int[] lastVisibleItemPositions = ((StaggeredGridLayoutManager) mLayoutManager).findLastVisibleItemPositions(null); 
     // get maximum element within the list 
     lastVisibleItemPosition = getLastVisibleItem(lastVisibleItemPositions); 
    } else if (mLayoutManager instanceof GridLayoutManager) { 
     lastVisibleItemPosition = ((GridLayoutManager) mLayoutManager).findLastVisibleItemPosition(); 
    } else if (mLayoutManager instanceof LinearLayoutManager) { 
     lastVisibleItemPosition = ((LinearLayoutManager) mLayoutManager).findLastVisibleItemPosition(); 
    } 

    // If the total item count is zero and the previous isn't, assume the 
    // list is invalidated and should be reset back to initial state 
    if (totalItemCount < previousTotalItemCount) { 
     this.currentPage = this.startingPageIndex; 
     this.previousTotalItemCount = totalItemCount; 
     if (totalItemCount == 0) { 
      this.loading = true; 
     } 
    } 
    // If it’s still loading, we check to see if the dataset count has 
    // changed, if so we conclude it has finished loading and update the current page 
    // number and total item count. 
    if (loading && (totalItemCount > previousTotalItemCount)) { 
     loading = false; 
     previousTotalItemCount = totalItemCount; 
    } 

    // If it isn’t currently loading, we check to see if we have breached 
    // the visibleThreshold and need to reload more data. 
    // If we do need to reload some more data, we execute onLoadMore to fetch the data. 
    // threshold should reflect how many total columns there are too 
    if (!loading && (lastVisibleItemPosition + visibleThreshold) > totalItemCount) { 
     currentPage++; 
     onLoadMore(currentPage, totalItemCount, view); 
     loading = true; 
    } 
} 

// Call this method whenever performing new searches 
public void resetState() { 
    this.currentPage = this.startingPageIndex; 
    this.previousTotalItemCount = 0; 
    this.loading = true; 
} 

// Defines the process for actually loading more data based on page 
public abstract void onLoadMore(int page, int totalItemsCount, RecyclerView view);/ The minimum amount of items to have below your current scroll position 
// before loading more. 
private int visibleThreshold = 15; 
// The current offset index of data you have loaded 
private int currentPage = 1; 
// The total number of items in the dataset after the last load 
private int previousTotalItemCount = 0; 
// True if we are still waiting for the last set of data to load. 
private boolean loading = true; 
// Sets the starting page index 
private int startingPageIndex = 1; 

RecyclerView.LayoutManager mLayoutManager; 

public EndlessRecyclerViewScrollListener(LinearLayoutManager layoutManager) { 
    this.mLayoutManager = layoutManager; 
} 

public EndlessRecyclerViewScrollListener(GridLayoutManager layoutManager) { 
    this.mLayoutManager = layoutManager; 
    visibleThreshold = visibleThreshold * layoutManager.getSpanCount(); 
} 

public EndlessRecyclerViewScrollListener(StaggeredGridLayoutManager layoutManager) { 
    this.mLayoutManager = layoutManager; 
    visibleThreshold = visibleThreshold * layoutManager.getSpanCount(); 
} 

public int getLastVisibleItem(int[] lastVisibleItemPositions) { 
    int maxSize = 0; 
    for (int i = 0; i < lastVisibleItemPositions.length; i++) { 
     if (i == 0) { 
      maxSize = lastVisibleItemPositions[i]; 
     } 
     else if (lastVisibleItemPositions[i] > maxSize) { 
      maxSize = lastVisibleItemPositions[i]; 
     } 
    } 
    return maxSize; 
} 

// This happens many times a second during a scroll, so be wary of the code you place here. 
// We are given a few useful parameters to help us work out if we need to load some more data, 
// but first we check if we are waiting for the previous load to finish. 
@Override 
public void onScrolled(RecyclerView view, int dx, int dy) { 
    int lastVisibleItemPosition = 0; 
    int totalItemCount = mLayoutManager.getItemCount(); 

    if (mLayoutManager instanceof StaggeredGridLayoutManager) { 
     int[] lastVisibleItemPositions = ((StaggeredGridLayoutManager) mLayoutManager).findLastVisibleItemPositions(null); 
     // get maximum element within the list 
     lastVisibleItemPosition = getLastVisibleItem(lastVisibleItemPositions); 
    } else if (mLayoutManager instanceof GridLayoutManager) { 
     lastVisibleItemPosition = ((GridLayoutManager) mLayoutManager).findLastVisibleItemPosition(); 
    } else if (mLayoutManager instanceof LinearLayoutManager) { 
     lastVisibleItemPosition = ((LinearLayoutManager) mLayoutManager).findLastVisibleItemPosition(); 
    } 

    // If the total item count is zero and the previous isn't, assume the 
    // list is invalidated and should be reset back to initial state 
    if (totalItemCount < previousTotalItemCount) { 
     this.currentPage = this.startingPageIndex; 
     this.previousTotalItemCount = totalItemCount; 
     if (totalItemCount == 0) { 
      this.loading = true; 
     } 
    } 
    // If it’s still loading, we check to see if the dataset count has 
    // changed, if so we conclude it has finished loading and update the current page 
    // number and total item count. 
    if (loading && (totalItemCount > previousTotalItemCount)) { 
     loading = false; 
     previousTotalItemCount = totalItemCount; 
    } 

    // If it isn’t currently loading, we check to see if we have breached 
    // the visibleThreshold and need to reload more data. 
    // If we do need to reload some more data, we execute onLoadMore to fetch the data. 
    // threshold should reflect how many total columns there are too 
    if (!loading && (lastVisibleItemPosition + visibleThreshold) > totalItemCount) { 
     currentPage++; 
     onLoadMore(currentPage, totalItemCount, view); 
     loading = true; 
    } 
} 

// Call this method whenever performing new searches 
public void resetState() { 
    this.currentPage = this.startingPageIndex; 
    this.previousTotalItemCount = 0; 
    this.loading = true; 
} 

// Defines the process for actually loading more data based on page 
public abstract void onLoadMore(int page, int totalItemsCount, RecyclerView view);}} 

MainActivity.java

public class MainActivity extends AppCompatActivity implemens ConnectivityReceiver.ConnectivityReceiverListener { 

private static final String API_KEY = "***************"; 
private static final String TAG = "MainActivity"; 
private int page = 1; 
private TextView no_data_tv; 
private RecyclerView mainMoviesView; 
private View noInternetLayout; 
private ProgressBar progressBar; 
private EndlessRecyclerViewScrollListener scrollListener; 
private LinearLayoutManager llm; 
List<Movies> movies; 


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

    no_data_tv = (TextView) findViewById(R.id.text_no_data); 

    movies = new ArrayList<>(); 

    llm = new LinearLayoutManager(this); 
    mainMoviesView = (RecyclerView) findViewById(R.id.main_recycler_view); 
    mainMoviesView.setLayoutManager(llm); 

    // This is the layout which is displayed if there is no internet connection. It is currently set to View.INVISIBLE 
    noInternetLayout = findViewById(R.id.no_internet_layout); 
    noInternetLayout.setVisibility(View.INVISIBLE); 

    progressBar = (ProgressBar) findViewById(R.id.loading_main_activity); 


    if(checkConnetion()) 
    { 
     getDataFromServer(page); 
     progressBar.setVisibility(View.INVISIBLE); 
    }else 
    { 
     noInternetLayout.setVisibility(View.VISIBLE); 
     progressBar.setVisibility(View.INVISIBLE); 
    } 

    scrollListener = new EndlessRecyclerViewScrollListener(llm) { 
     @Override 
     public void onLoadMore(int page, int totalItemsCount, RecyclerView view) { 
      getDataFromServer(page); 
      Log.v(TAG,"Page loaded is"+page); 
     } 
    }; 
    mainMoviesView.addOnScrollListener(scrollListener); 
} 

private boolean checkConnetion() { 
    return ConnectivityReceiver.isConnected(); 
} 

private void getDataFromServer(int page) 
{ 
    // These are the retrofit codes to get the data from TMDB API 
    ApiInterface apiService = ApiClient.getClient().create(ApiInterface.class); 

    Call<Response> call = apiService.getPopularMovies(API_KEY , page); 


    call.enqueue(new Callback<Response>() { 
     @Override 
     public void onResponse(Call<Response> call, retrofit2.Response<Response> response) { 
      List<Movies> movies = response.body().getMovies(); 
      progressBar.setVisibility(View.INVISIBLE); 
      if(movies.size() == 0) 
      { 
       no_data_tv.setVisibility(View.VISIBLE); 
      }else{ 
       mainMoviesView.setAdapter(new MoviesAdapter(movies,MainActivity.this)); 
      } 
     } 

     @Override 
     public void onFailure(Call<Response> call, Throwable t) { 
      Log.e(TAG,t.toString()); 
     } 
    }); 


} 



@Override 
protected void onResume() { 
    super.onResume(); 
    // register connection status listener 
    MyApplication.getInstance().setConnectivityListener(this); 

} 

@Override 
public void onNetworkConnectionChanged(boolean isConnected) { 
    if(isConnected) 
    { 
     getDataFromServer(page); 

    }else{ 
     progressBar.setVisibility(View.INVISIBLE); 
     noInternetLayout.setVisibility(View.VISIBLE); 
    } 
}} 

?常に

List<Movies> movies = response.body().getMovies(); 
あなたがデータセットに要素を追加する必要があります


movies.addAll(response.body().getMovies()); 

答えて

1

デュードを呼び出します新しいデータであなたの見解を初期化する

mainMoviesView.setAdapter(new MoviesAdapter(movies,MainActivity.this)); 

これは、onCreate()、onCreateView()またはその他の初期化メソッドになります。

MoviesAdapter moviesAdapter = new MoviesAdapter(movies,MainActivity.this); 
mainMoviesView.setAdapter(moviesAdepter); 

次に、新しいコールエンキュー。

call.enqueue(new Callback<Response>() { 
    @Override 
    public void onResponse(Call<Response> call, retrofit2.Response<Response> response) { 
     movies.addAll(response.body().getMovies()); // this line updated your movies list. 
     progressBar.setVisibility(View.INVISIBLE); 
     if(movies.size() == 0) 
     { 
      no_data_tv.setVisibility(View.VISIBLE); 
     }else{ 
      moviesAdapter.notifyDataSetChanged(); // this new line. 
     } 
    } 

    @Override 
    public void onFailure(Call<Response> call, Throwable t) { 
     Log.e(TAG,t.toString()); 
    } 
}); 
0

このライン - あなたは新しい値を毎回割り当てる 、あなたは、この行で
見て、

+0

これは機能しますが、アダプターを設定した最初の時点でリストムービーがヌルであるため、ヌルポイント例外が返されませんか? –

+0

setAdapterは常にイニシャライザメソッドにあります。それはonCreate、onCreateView、さらにはonResume()でも可能です。 setAdapter()は常にアダプタを初期化します。あなたのアダプタでonCreateView()のnull要素をチェックすることができます。 – Kaloglu

+0

@SriramRいいえ、それは でリストを初期化するためではありません。リストモデル=新しいArrayList <>(); – MadScientist

関連する問題