问题
I have a TabLayout
with Recyclerview
so that when tabs are clicked then the Recyclerview
is scrolled to a particular position.
I want the reverse procedure as well such that when the Recyclerview
is scrolled to a particular position then the particular tab is highlighted.
For example: If there are 4 tabs in the TabLayout
and when Recyclerview
is scrolled to 5th position(Item visible and below TabLayout
) then 3rd tab should be highlighted.
Here when 'How it works' appears below TabLayout
then tabs 'How it works' should be highlighted.
回答1:
Try this
follow this steps
- Add a
ScrollListener
to yourRecyclerView
- than find first visible item of your
RecyclerView
- set the select the tab in
TabLayout
as per position of yourRecyclerView
SAMPLE CODE
myRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
int itemPosition=linearLayoutManager.findFirstCompletelyVisibleItemPosition();
if(itemPosition==0){ // item position of uses
TabLayout.Tab tab = myTabLayout.getTabAt(Index);
tab.select();
}else if(itemPosition==1){// item position of side effects
TabLayout.Tab tab = myTabLayout.getTabAt(Index);
tab.select();
}else if(itemPosition==2){// item position of how it works
TabLayout.Tab tab = myTabLayout.getTabAt(Index);
tab.select();
}else if(itemPosition==3){// item position of precaution
TabLayout.Tab tab = myTabLayout.getTabAt(Index);
tab.select();
}
}
});
EDIT
public class MyActivity extends AppCompatActivity {
RecyclerView myRecyclerView;
TabLayout myTabLayout;
LinearLayoutManager linearLayoutManager;
ArrayList<String> arrayList = new ArrayList<>();
DataAdapter adapter;
private boolean isUserScrolling = false;
private boolean isListGoingUp = true;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
myTabLayout = findViewById(R.id.myTabLayout);
myRecyclerView = findViewById(R.id.myRecyclerView);
linearLayoutManager = new LinearLayoutManager(this);
myRecyclerView.setLayoutManager(linearLayoutManager);
myRecyclerView.setHasFixedSize(true);
for (int i = 0; i < 120; i++) {
arrayList.add("Item " + i);
}
adapter= new DataAdapter(this,arrayList);
myRecyclerView.setAdapter(adapter);
myTabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
isUserScrolling = false ;
int position = tab.getPosition();
if(position==0){
myRecyclerView.smoothScrollToPosition(0);
}else if(position==1){
myRecyclerView.smoothScrollToPosition(30);
}else if(position==2){
myRecyclerView.smoothScrollToPosition(60);
}else if(position==3){
myRecyclerView.smoothScrollToPosition(90);
}
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
myRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
if (newState == RecyclerView.SCROLL_STATE_DRAGGING) {
isUserScrolling = true;
if (isListGoingUp) {
//my recycler view is actually inverted so I have to write this condition instead
if (linearLayoutManager.findLastCompletelyVisibleItemPosition() + 1 == arrayList.size()) {
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
if (isListGoingUp) {
if (linearLayoutManager.findLastCompletelyVisibleItemPosition() + 1 == arrayList.size()) {
Toast.makeText(MyActivity.this, "exeute something", Toast.LENGTH_SHORT).show();
}
}
}
}, 50);
//waiting for 50ms because when scrolling down from top, the variable isListGoingUp is still true until the onScrolled method is executed
}
}
}
}
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
int itemPosition = linearLayoutManager.findFirstVisibleItemPosition();
if(isUserScrolling){
if (itemPosition == 0) { // item position of uses
TabLayout.Tab tab = myTabLayout.getTabAt(0);
tab.select();
} else if (itemPosition == 30) {// item position of side effects
TabLayout.Tab tab = myTabLayout.getTabAt(1);
tab.select();
} else if (itemPosition == 60) {// item position of how it works
TabLayout.Tab tab = myTabLayout.getTabAt(2);
tab.select();
} else if (itemPosition == 90) {// item position of precaution
TabLayout.Tab tab = myTabLayout.getTabAt(3);
tab.select();
}
}
}
});
}
}
回答2:
private fun syncTabWithRecyclerView() {
// Move recylerview to the position selected by user
menutablayout.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
override fun onTabSelected(tab: TabLayout.Tab) {
if (!isUserScrolling) {
val position = tab.position
linearLayoutManager.scrollToPositionWithOffset(position, 0)
}
}
override fun onTabUnselected(tab: TabLayout.Tab) {
}
override fun onTabReselected(tab: TabLayout.Tab) {
}
})
// Detect recyclerview position and select tab respectively.
menuRecyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
if (newState == RecyclerView.SCROLL_STATE_DRAGGING) {
isUserScrolling = true
} else if (newState == RecyclerView.SCROLL_STATE_IDLE)
isUserScrolling = false
}
}
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy)
if (isUserScrolling) {
val itemPosition = linearLayoutManager.findLastVisibleItemPosition()
val tab = menutablayout.getTabAt(itemPosition)
tab?.select()
}
}
})
}
来源:https://stackoverflow.com/questions/51701488/how-to-sync-tablayout-with-recyclerview