私は、ページングアルゴリズム持ってRecyclerView
行っている場合、Scroll
スクロールリスナートリガーおよび負荷のより多くの要素を。最初は、私は、サーバーへのリクエストに負荷への要素の数を割り当てられた20で、デフォルトでは固定サイズ(持っている私のRecyclerView、ためないwrap_contentを)。
私は、データをロードする前に定義されたRecyclerViewの幅/高さで表示することができるアイテムの数を知っておく必要があり、初期負荷で要求されるアイテムの量を決定するために、いくつかのデバイス上の20の項目にないことを考えるとスクロールのリスナーをアクティブにし、より多くの要素をロードするのに十分な。
これは、パディング、マージンなどとしてビューの余分な性質を、考慮しないで...
溶液は、Java AndroidやXamarinアンドロイド(ないフォーム)C#であることができます。
更新:
あなたは手掛かりを持っているために、私はこれを試してみましたし、それは私の作品の大きさはときに私はそれを呼び出す場合にのみ、RecyclerView
内部で、割り当てられていますOnLayoutChange
:
public int GetMaxVisibleItemCountFromRecyclerView(RecyclerView recyclerView)
{
if (recyclerView == null) return 0;
int Width = recyclerView.Width;
int Height = recyclerView.Height;
if (Width == 0 || Height == 0)
return 0;
var layoutManager = recyclerView.GetLayoutManager() as GridLayoutManager;
if (layoutManager == null) return 0;
int widthRatio = Width / layoutManager.SpanCount;
int quantity = (Height / widthRatio) * layoutManager.SpanCount;
return quantity;
}
このソリューションは、のみで動作しRecyclerViews
ている使用GridLayoutManager
。私は他の持っているRecyclerViews
にもしてページング・アルゴリズムを使用して定義されたサイズでLinearLayoutManager
。
私はこれが可能である、RecyclerViewのいずれかのLayoutManagerでその作品を同様のソリューションを必要とOnLayoutChange内部で呼び出されなければならないのですか?
代わりに計算複製しようとしているのRecyclerView
計算レイアウトにないが、システムはあなたのための作業を行うことができます。次の例では、することができますRecyclerView
一つのアイテムをレイアウトし、測定はそこから取られています。ダミー項目が表示されなくなり、単に測定のために使用されています。
この方法の利点は、私たちが何を複製する必要がないことであるRecyclerView
項目を測定することがありません。すべてのキーの測定は、パディング、マージンや装飾品など、考慮されています。
これがために行うことができる方法を次のサンプルショーGridLayoutManager
とLinearLayoutManager
。StaggeredGridLayoutManager
そしてFlexboxLayoutManager
特殊なケースであり、ここでは考慮されません。
ここではアイテムの1ページだけがロードされたことを示す、このデモアプリケーションの結果を示す短いビデオです。
MainActivity.java
public class MainActivity extends AppCompatActivity {
private List<String> mItems = new ArrayList<>();
private RecyclerView mRecycler;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRecycler = findViewById(R.id.recyclerView);
// Sample for vertical LinearLayoutManager.
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
// Sample for GridLayoutManager with 4 spans. Each item comsumes 2 spans.
// GridLayoutManager layoutManager = new GridLayoutManager(this, 4);
// layoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
// @Override
// public int getSpanSize(int position) {
// return 2;
// }
// });
// Add single dummy item that will be measured but not be displayed.
mItems.add("Dummy item");
RecyclerViewAdapter mAdapter = new RecyclerViewAdapter(mItems);
mRecycler.setLayoutManager(layoutManager);
mRecycler.setAdapter(mAdapter);
// Take measurements in OnPreDraawListener(). This could also be accomplished with
// mRecyclerView.post(new Runnable()...)
mRecycler.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
mRecycler.getViewTreeObserver().removeOnPreDrawListener(this);
// RecyclerView is laid out with single dummy entry. Get how many of this type
// of item can fit into the visible portion of the RecyclerView.
final int nItems = getInitialLoadCount(mRecycler);
Log.d(TAG, "<<<<Items per page=" + nItems);
// Don't need the dummy entry any more.
mItems.clear();
mRecycler.getAdapter().notifyDataSetChanged();
mItems = new ArrayList<>();
// Fake load...
loadInitialItems(nItems);
return false;
}
});
}
// Determine how many items will fill one screen of the RecyclerView. Call with the
// RecyclerView loaded with at least one item for measurement.
private int getInitialLoadCount(RecyclerView recyclerView) {
int itemsToLoad = 0;
RecyclerView.LayoutManager lm = recyclerView.getLayoutManager();
View firstChild = recyclerView.getChildAt(0);
if (lm instanceof LinearLayoutManager) {
Rect bounds = new Rect();
recyclerView.getDecoratedBoundsWithMargins(firstChild, bounds);
if (lm.canScrollVertically()) {
int recyclerHeightForItems = recyclerView.getHeight() - recyclerView.getPaddingTop()
- recyclerView.getPaddingBottom();
itemsToLoad = (recyclerHeightForItems + bounds.height() - 1) / bounds.height();
} else if (lm.canScrollHorizontally()) {
int recyclerWidthForItems = recyclerView.getWidth() - recyclerView.getPaddingLeft()
- recyclerView.getPaddingRight();
itemsToLoad = (recyclerWidthForItems + bounds.width() - 1) / bounds.width();
}
if (lm instanceof GridLayoutManager) {
// Adjust for GridLayoutManager. All items should to be the same number of spans.
GridLayoutManager glm = (GridLayoutManager) lm;
itemsToLoad *= glm.getSpanCount() / glm.getSpanSizeLookup().getSpanSize(0);
}
}
return itemsToLoad;
}
private void loadInitialItems(final int itemCount) {
// Simulate load of nItems...should be on non-UI thread.
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 1; i <= itemCount; i++) {
sleep(250);
mItems.add("Item #" + i);
}
runOnUiThread(new Runnable() {
@Override
public void run() {
mRecycler.swapAdapter(new RecyclerViewAdapter(mItems), true);
}
});
}
}).start();
}
private static final String TAG = "MainActivity";
}