RecyclerView의 맨 아래로 스크롤하는 방법? scrollToPosition이 작동하지 않습니다
활동을로드 한 후 RecyclerView 목록의 맨 아래로 스크롤하고 싶습니다.
GENERIC_MESSAGE_LIST = (ArrayList) intent.getExtras().getParcelableArrayList(ConversationsAdapter.EXTRA_MESSAGE);
conversationView = (RecyclerView) findViewById(R.id.list_messages);
conversationView.setHasFixedSize(true);
conversationViewLayoutManager = new LinearLayoutManager(this);
conversationView.setLayoutManager(conversationViewLayoutManager);
conversationViewAdapter = new ConversationAdapter(GENERIC_MESSAGE_LIST, this);
conversationView.setAdapter(conversationViewAdapter);
conversationView.scrollTo(...)
RecyclerView에서 지원되지 않는 것에 대한 예외를 throw하고 conversationView.scrollToPosition(...)
아무것도하지 않는 것 같습니다.
위의 코드 블록 뒤에 추가했습니다
conversationView.scrollToPosition(GENERIC_MESSAGE_LIST.size() + 1)
작동하지 않습니다. 에 30 개의 요소가 GENERIC_MESSAGE_LIST
있습니다.
그냥 설정 setStackFromEnd=true
또는 setReverseLayout=true
너무 LLM은 끝에서 항목을 레이아웃 것이다.
이 두 가지의 차이점 setStackFromEnd
은 마지막 요소를 표시하도록보기를 설정하고 레이아웃 방향이 동일하게 유지된다는 것입니다. (왼쪽에서 오른쪽으로 가로 리사이클 러보기에서 마지막 요소가 표시되고 왼쪽으로 스크롤하면 이전 요소가 표시됩니다)
반면 setReverseLayout
어댑터가 추가 한 요소의 순서는 변경됩니다. 레이아웃은 LTR Recycler View에서 가장 왼쪽에있는 마지막 요소에서 시작한 다음 오른쪽으로 스크롤하면 이전 요소가 표시됩니다.
견본:
final LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity());
linearLayoutManager.setReverseLayout(true);
_listView.setLayoutManager(linearLayoutManager);
자세한 내용은 설명서 를 참조하십시오.
답을 찾기 위해이 게시물을보고 있었지만 ...이 게시물의 모든 사람이 나와 같은 시나리오에 직면했다고 생각합니다 scrollToPosition()
. 명백한 이유로 완전히 무시되었습니다.
내가 무엇을 사용하고 있었습니까?
recyclerView.scrollToPosition(items.size());
... 무슨 일 했어요 ?
recyclerView.scrollToPosition(items.size() - 1);
해결책을 알고 싶은 사람이 있다면 아래 답변이 늦습니다.
conversationView.smoothScrollToPosition(conversationView.getAdapter().getItemCount() - 1);
recyclerview의 임의의 위치에서 아래로 스크롤하려면
edittext.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
rv_commentList.postDelayed(new Runnable() {
@Override
public void run() {
rv_commentList.scrollToPosition(rv_commentList.getAdapter().getItemCount() - 1);
}
}, 1000);
}
});
메시지를 보낸 후와 서버에서 메시지를 받기 전에이 코드를 추가하십시오.
recyclerView.scrollToPosition(mChatList.size() - 1);
를 호출 setAdapter
하면 화면에 항목을 즉시 배치하고 배치하지 않습니다 (단일 레이아웃 패스가 필요함) scrollToPosition()
. 호출 할 때 스크롤 할 실제 요소가 없습니다.
대신 ViewTreeObserver.OnGlobalLayoutListener를 (에 의해 생성 된 addOnGlobalLayoutListner () 를 통해) 등록해야 첫 번째 레이아웃 통과 후까지 지연됩니다 .ViewTreeObserver
conversationView.getViewTreeObserver()
scrollToPosition()
conversationView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
public void onGlobalLayout() {
conversationView.scrollToPosition(GENERIC_MESSAGE_LIST.size();
// Unregister the listener to only call scrollToPosition once
conversationView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
// Use vto.removeOnGlobalLayoutListener(this) on API16+ devices as
// removeGlobalOnLayoutListener is deprecated.
// They do the same thing, just a rename so your choice.
}
});
코 틀린 솔루션 :
"recyclerView.adapter"를 설정 한 후 또는 "recyclerView.adapter.notifyDataSetChanged ()"후에 코드 아래에 적용
recyclerView.scrollToPosition(recyclerView.adapter.itemCount - 1)
class MyLayoutManager extends LinearLayoutManager {
public MyLayoutManager(Context context) {
super(context, LinearLayoutManager.VERTICAL, false);
}
@Override public void smoothScrollToPosition(RecyclerView recyclerView,
final RecyclerView.State state, final int position) {
int fcvip = findFirstCompletelyVisibleItemPosition();
int lcvip = findLastCompletelyVisibleItemPosition();
if (position < fcvip || lcvip < position) {
// scrolling to invisible position
float fcviY = findViewByPosition(fcvip).getY();
float lcviY = findViewByPosition(lcvip).getY();
recyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() {
int currentState = RecyclerView.SCROLL_STATE_IDLE;
@Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
if (currentState == RecyclerView.SCROLL_STATE_SETTLING
&& newState == RecyclerView.SCROLL_STATE_IDLE) {
// recursive scrolling
smoothScrollToPosition(recyclerView, state, position);
}
currentState = newState;
}
@Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
int fcvip = findFirstCompletelyVisibleItemPosition();
int lcvip = findLastCompletelyVisibleItemPosition();
if ((dy < 0 && fcvip == position) || (dy > 0 && lcvip == position)) {
// stop scrolling
recyclerView.setOnScrollListener(null);
}
}
});
if (position < fcvip) {
// scroll up
recyclerView.smoothScrollBy(0, (int) (fcviY - lcviY));
} else {
// scroll down
recyclerView.smoothScrollBy(0, (int) (lcviY - fcviY));
}
} else {
// scrolling to visible position
float fromY = findViewByPosition(fcvip).getY();
float targetY = findViewByPosition(position).getY();
recyclerView.smoothScrollBy(0, (int) (targetY - fromY));
}
}
}
과
MyLayoutManager layoutManager = new MyLayoutManager(context);
recyclerView.setLayoutManager(layoutManager);
RecyclerView.Adapter adapter = new YourAdapter();
recyclerView.setAdapter(adapter);
recyclerView.smoothScrollToPosition(adapter.getItemCount() - 1);
위의 코드는 작동하지만 부드럽 지 않고 시원하지 않습니다.
recyclerView에 어댑터가 연결되어 있으면이 작업을 수행하십시오.
mRecyclerView.smoothScrollToPosition(mRecyclerView.getAdapter().getItemCount());
In my case where views do not have the same height, calling scrollToPosition on the LayoutManager worked to really scroll to the bottom and see fully the last item:
recycler.getLayoutManager().scrollToPosition(adapter.getItemCount() - 1);
Roc answer is a great help. I would like to add a small block to it:
mRecyclerView.scrollToPosition(mAdapter.getItemCount() - 1);
In Kotlin:
recyclerView.viewTreeObserver.addOnGlobalLayoutListener { scrollToEnd() }
private fun scrollToEnd() =
(adapter.itemCount - 1).takeIf { it > 0 }?.let(recyclerView::smoothScrollToPosition)
This works perfectly fine for me:
AdapterChart adapterChart = new AdapterChart(getContext(),messageList);
recyclerView.setAdapter(adapterChart);
recyclerView.scrollToPosition(recyclerView.getAdapter().getItemCount()-1);
Only Ian's answer was able to make my RecyclerView
scroll to a specified position. However, The RecyclerView
was not able to scroll afterwards when I used scrollToPosition()
. smoothScrollToPosition()
worked but the initial animation made it too slow when the list was long. The reason was the listener was not removed. I used the code below to remove the current ViewTreeObserver
and it worked as a charm.
mRecyclerView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
mRecyclerView.scrollToPosition(mPosition);
mRecyclerView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
});
this code will give you latest post first, i think this answer is helpful.
mInstaList=(RecyclerView)findViewById(R.id.insta_list);
mInstaList.setHasFixedSize(true);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
mInstaList.setLayoutManager(layoutManager);
layoutManager.setStackFromEnd(true);
layoutManager.setReverseLayout(true);
Tried a method of @galex, it worked until refactoring. So I used an answer of @yanchenko and changed a bit. Probably this is because I called scrolling from onCreateView()
, where a fragment view was built (and probably didn't have right size).
private fun scrollPhotosToEnd(view: View) {
view.recycler_view.viewTreeObserver.addOnGlobalLayoutListener(object :
ViewTreeObserver.OnGlobalLayoutListener {
override fun onGlobalLayout() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
view.recycler_view.viewTreeObserver.removeOnGlobalLayoutListener(this)
} else {
@Suppress("DEPRECATION")
view.recycler_view.viewTreeObserver.removeGlobalOnLayoutListener(this)
}
adapter?.itemCount?.takeIf { it > 0 }?.let {
view.recycler_view.scrollToPosition(it - 1)
}
}
})
}
You can also add a check of viewTreeObserver.isAlive
like in https://stackoverflow.com/a/39001731/2914140.
Firsttime scroll when entering in recycler view first time then use linearLayoutManager.scrollToPositionWithOffset(messageHashMap.size()-1,put in minus for scroll down for scroll up put in positive value);
if view is very big in height then scrolltoposition particular offset is used for top of view then you use
int overallXScroldl =chatMessageBinding.rvChat.computeVerticalScrollOffset(); chatMessageBinding.rvChat.smoothScrollBy(0, Math.abs(overallXScroldl));
'IT' 카테고리의 다른 글
코코아에서 임의의 영숫자 문자열 생성 (0) | 2020.06.19 |
---|---|
ng는 내부 또는 외부 명령으로 인식되지 않습니다 (0) | 2020.06.19 |
TimeUnit 열거 형을 사용하여 나노초를 초로 변환하는 방법은 무엇입니까? (0) | 2020.06.19 |
정적 및 밀봉 클래스 차이 (0) | 2020.06.19 |
C의 숨겨진 기능 (0) | 2020.06.19 |