막무가내 삽질 블로그
android infinite/endless scroll 본문
728x90
infinite/endless scroll 이란?
페이지 이동없이 스크롤을 내리면 다음 페이지의 내용을 불러오는 것을 의미한다. 즉, 무한스크롤이다.
예제를 통해 실습해본 후 내 프로젝트에 맞게 변경했다.
서버에서 받아온 데이터가 100개라고 가정했을 때 100개를 담는 리스트를 하나를 할당한 후 스크롤 이벤트가 발생할때
10개의 데이터를 불러온다.
테스트 예제
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/recyclerview"/>
</LinearLayout>
item_recycler.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardElevation="8dp"
app:cardUseCompatPadding="true">
<TextView
android:id="@+id/tvItem"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp"
android:text="Item X" />
</androidx.cardview.widget.CardView>
item_loading.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:orientation="vertical">
<ProgressBar
android:id="@+id/progressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:indeterminate="true"
android:paddingLeft="8dp"
android:paddingRight="8dp"
/>
</LinearLayout>
RecyclerViewAdapter
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private final int VIEW_TYPE_ITEM = 0;
private final int VIEW_TYPE_LOADING = 1;
public List<String> mItemList;
public RecyclerViewAdapter(List<String> itemList) {
mItemList = itemList;
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
if (viewType == VIEW_TYPE_ITEM) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_recycler, parent, false);
return new ItemViewHolder(view);
} else {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_loading, parent, false);
return new LoadingViewHolder(view);
}
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) {
if (viewHolder instanceof ItemViewHolder) {
populateItemRows((ItemViewHolder) viewHolder, position);
} else if (viewHolder instanceof LoadingViewHolder) {
showLoadingView((LoadingViewHolder) viewHolder, position);
}
}
@Override
public int getItemCount() {
return mItemList == null ? 0 : mItemList.size();
}
@Override
public int getItemViewType(int position) {
return mItemList.get(position) == null ? VIEW_TYPE_LOADING : VIEW_TYPE_ITEM;
}
private class ItemViewHolder extends RecyclerView.ViewHolder {
TextView tvItem;
public ItemViewHolder(@NonNull View itemView) {
super(itemView);
tvItem = itemView.findViewById(R.id.tvItem);
}
}
private class LoadingViewHolder extends RecyclerView.ViewHolder {
ProgressBar progressBar;
public LoadingViewHolder(@NonNull View itemView) {
super(itemView);
progressBar = itemView.findViewById(R.id.progressBar);
}
}
private void showLoadingView(LoadingViewHolder viewHolder, int position) {
//
}
private void populateItemRows(ItemViewHolder viewHolder, int position) {
String item = mItemList.get(position);
viewHolder.tvItem.setText(item);
}
}
MainActivity
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
RecyclerView recyclerView;
RecyclerViewAdapter recyclerViewAdapter;
boolean isLoading = false;
ArrayList<String> allList = new ArrayList<>();
ArrayList<String> list = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = findViewById(R.id.recyclerview);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
firstData();
initAdapter();
initScrollListener();
}
private void firstData() {
Log.d(TAG, "firstData:");
// 총 아이템이 50개라 가정
for (int a=0; a<50; a++) {
allList.add("Item " + a);
}
// 총 아이템에서 10개를 받아옴
for (int i=0; i<10; i++) {
list.add(allList.get(i));
}
}
private void dataMore() {
Log.d(TAG, "dataMore: ");
list.add(null);
recyclerViewAdapter.notifyItemInserted(list.size() -1 );
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
list.remove(list.size() -1 );
int scrollPosition = list.size();
recyclerViewAdapter.notifyItemRemoved(scrollPosition);
int currentSize = scrollPosition;
int nextLimit = currentSize + 10;
for (int i=currentSize; i<nextLimit; i++) {
if (i == allList.size()) {
return;
}
list.add(allList.get(i));
}
recyclerViewAdapter.notifyDataSetChanged();
isLoading = false;
}
}, 2000);
}
private void initAdapter() {
recyclerViewAdapter = new RecyclerViewAdapter(list);
recyclerView.setAdapter(recyclerViewAdapter);
}
// 리싸이클러뷰 이벤트시
private void initScrollListener() {
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
Log.d(TAG, "onScrollStateChanged: ");
}
@Override
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
Log.d(TAG, "onScrolled: ");
LinearLayoutManager linearLayoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
if (!isLoading) {
if (linearLayoutManager != null && linearLayoutManager.findLastCompletelyVisibleItemPosition() == list.size() -1 ) {
dataMore();
isLoading = true;
Toast.makeText(MainActivity.this, "스크롤감지", Toast.LENGTH_SHORT).show();
}
}
}
});
}
}
참:https://www.journaldev.com/24041/android-recyclerview-load-more-endless-scrolling
코틀린 버전 페이징 : class-programming.tistory.com/manage/statistics/entry/108
안드로이드 스터디 모집
www.notion.so/fundevjay/Android-ddf96b24265e414fb2d9e8fc5d388b80
'Android' 카테고리의 다른 글
android glide image size (0) | 2020.01.21 |
---|---|
안드로이드 fcm push notification, send fcm device to device (1) | 2019.12.31 |
java.lang.IndexOutOfBoundsException: 에러 난 이유 (0) | 2019.12.17 |
android null object reference (0) | 2019.12.15 |
안드로이드 mvp + retrofit + php 간단 정리 (0) | 2019.12.08 |
Comments