滚动时获取RecycleView的中心可见项

这是我想要的:

在这里输入图像描述

如上图所示,我想在RecycleView上绘制一个中心线,然后在滚动时(以及向左或向右移动)获取中心项目,
这里是我尝试绘制一个水平的RecycleView

  HorizontalAdapter adapter = new HorizontalAdapter(data); LinearLayoutManager layoutManager = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false); recycleView.setLayoutManager(layoutManager); recycleView.setAdapter(adapter); 

有没有什么办法知道哪个项目被移到RecycleView中心? 我怎样才能将RecycleView向左或向右滚动一个位置?

更新 :我试图使用滚动监听器来获取中间位置,但它不能作为方面。

  @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); int firstPos = layoutManager.findFirstVisibleItemPosition(); int lastPos = layoutManager.findLastVisibleItemPosition(); int middle = Math.abs(lastPos - firstPos) / 2 + firstPos; int selectedPos = -1; for (int i = 0; i < adapter.getItemCount(); i++) { if (i == middle) { adapter.getItem(i).setSelected(true); selectedPos = i; } else { adapter.getItem(i).setSelected(false); } } adapter.notifyDataSetChanged(); } 

并得到结果:

在这里输入图像描述

我只想改变select项目(使文本为白色),当它在蓝色的Rect

我做了这样的事情。 我可以做你所需要的。 首先,这是我的algorithm是如何工作的 在这里输入图像描述

这是我的recyclerView适配器

 public class DateAdapter extends RecyclerView.Adapter<DateAdapter.DateViewHolder> { private ArrayList<LabelerDate> dateDataList; private static final int VIEW_TYPE_PADDING = 1; private static final int VIEW_TYPE_ITEM = 2; private int paddingWidthDate = 0; private int selectedItem = -1; public DateAdapter(ArrayList<LabelerDate> dateData, int paddingWidthDate) { this.dateDataList = dateData; this.paddingWidthDate = paddingWidthDate; } @Override public DateViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { if (viewType == VIEW_TYPE_ITEM) { final View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_date, parent, false); return new DateViewHolder(view); } else { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_padding, parent, false); RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) view.getLayoutParams(); layoutParams.width = paddingWidthDate; view.setLayoutParams(layoutParams); return new DateViewHolder(view); } } @Override public void onBindViewHolder(DateViewHolder holder, int position) { LabelerDate labelerDate = dateDataList.get(position); if (getItemViewType(position) == VIEW_TYPE_ITEM) { if(labelerDate.dateType.equals(BirthDayActivity.DateType.C31)) holder.tvDate.setText(String.valueOf(labelerDate.valueDate)); holder.tvDate.setVisibility(View.VISIBLE); holder.imgSmall.setVisibility(View.VISIBLE); if (position == selectedItem) { holder.tvDate.setTextColor(Color.parseColor("#094673")); holder.tvDate.setTextSize(35); holder.imgSmall.setBackgroundResource(R.color.textviewbold); } else { holder.tvDate.setTextColor(Color.GRAY); holder.tvDate.setTextSize(35); holder.imgSmall.setBackgroundResource(R.color.gray); } } } public void setSelecteditem(int selecteditem) { this.selectedItem = selecteditem; notifyDataSetChanged(); } @Override public int getItemCount() { return dateDataList.size(); } @Override public int getItemViewType(int position) { LabelerDate labelerDate = dateDataList.get(position); if (labelerDate.dateType.equals(BirthDayActivity.DateType.NONE)) { return VIEW_TYPE_PADDING; } return VIEW_TYPE_ITEM; } public class DateViewHolder extends RecyclerView.ViewHolder { public TextView tvDate; public ImageView imgSmall; public DateViewHolder(View itemView) { super(itemView); tvDate = (TextView) itemView.findViewById(R.id.tvNumberDate); imgSmall = (ImageView) itemView.findViewById(R.id.small_marked_dob); } }} 

这是最重要的algorithm:

 public void getRecyclerviewDate() { recyclerViewDate = (RecyclerView) findViewById(R.id.recyclerViewDay); ViewTreeObserver vtoDate = recyclerViewDate.getViewTreeObserver(); vtoDate.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { @Override public boolean onPreDraw() { recyclerViewDate.getViewTreeObserver().removeOnPreDrawListener(this); finalWidthDate = recyclerViewDate.getMeasuredWidth(); itemWidthDate = getResources().getDimension(R.dimen.item_dob_width); paddingDate = (finalWidthDate - itemWidthDate) / 2; firstItemWidthDate = paddingDate ; allPixelsDate = 0; final LinearLayoutManager dateLayoutManager = new LinearLayoutManager(getApplicationContext()); dateLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL); recyclerViewDate.setLayoutManager(dateLayoutManager); recyclerViewDate.addOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); synchronized (this) { if(newState == RecyclerView.SCROLL_STATE_IDLE){ calculatePositionAndScrollDate(recyclerView); } } } @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); allPixelsDate += dx; } }); if (labelerDates == null) labelerDates = new ArrayList<>(); labelerDates.addAll(genLabelerDate(currentMonth, currentYear)); dateAdapter = new DateAdapter(labelerDates, (int) firstItemWidthDate); recyclerViewDate.setAdapter(dateAdapter); return true; } }); } /* this if most important, if expectedPositionDate < 0 recyclerView will return to nearest item*/ private void calculatePositionAndScrollDate(RecyclerView recyclerView) { int expectedPositionDate = Math.round((allPixelsDate + paddingDate - firstItemWidthDate) / itemWidthDate); if (expectedPositionDate == -1) { expectedPositionDate = 0; } else if (expectedPositionDate >= recyclerView.getAdapter().getItemCount() - 2) { expectedPositionDate--; } scrollListToPositionDate(recyclerView, expectedPositionDate); } /* this if most important, if expectedPositionDate < 0 recyclerView will return to nearest item*/ private void scrollListToPositionDate(RecyclerView recyclerView, int expectedPositionDate) { float targetScrollPosDate = expectedPositionDate * itemWidthDate + firstItemWidthDate - paddingDate; float missingPxDate = targetScrollPosDate - allPixelsDate; if (missingPxDate != 0) { recyclerView.smoothScrollBy((int) missingPxDate, 0); } } private void setDateValue() { int expectedPositionDateColor = Math.round((allPixelsDate + paddingDate - firstItemWidthDate) / itemWidthDate); setColorDate = expectedPositionDateColor + 1; //set color here dateAdapter.setSelecteditem(setColorDate); } @Override protected void onRestoreInstanceState(@NonNull Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); allPixelsDate = savedInstanceState.getFloat(BUNDLE_LIST_PIXELS_DATE); allPixelsDateChanged = savedInstanceState.getFloat(BUNDLE_LIST_PIXELS_DATE_CHANGED); } @Override protected void onSaveInstanceState(@NonNull Bundle outState) { super.onSaveInstanceState(outState); outState.putFloat(BUNDLE_LIST_PIXELS_DATE, allPixelsDate); outState.putFloat(BUNDLE_LIST_PIXELS_DATE_CHANGED, allPixelsDateChanged); } 

这是我的结果: 在这里输入图像描述

看看这个video链接 ,这是我的应用程序演示

有时需要整个示例代码块,因为我们可能会错过一些东西。 这里是我所拥有的,随时纠正任何事情,因为我可能在某个地方犯了一些小错误。 是的,这个答案是@tranhieu答案的延伸。 谢谢@tranhieu。

MainActivity.java

 package com.test; import android.app.Activity; import android.graphics.Color; import android.support.annotation.Nullable; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.ViewTreeObserver; import android.widget.TextView; import java.util.ArrayList; public class MainActivity extends Activity { private static final String TAG = MainActivity.class.getSimpleName(); public float firstItemWidthDate; public float paddingDate; public float itemWidthDate; public int allPixelsDate; public int finalWidthDate; private DateAdapter dateAdapter; private ArrayList<LabelerDate> labelerDates = new ArrayList<>(); @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); getRecyclerviewDate(); } public void getRecyclerviewDate() { final RecyclerView recyclerViewDate = (RecyclerView) findViewById(R.id.rv_tasks_date); if (recyclerViewDate != null) { recyclerViewDate.postDelayed(new Runnable() { @Override public void run() { setDateValue(); } }, 300); recyclerViewDate.postDelayed(new Runnable() { @Override public void run() { recyclerViewDate.smoothScrollToPosition(dateAdapter.getItemCount()-1); setDateValue(); } }, 5000); } ViewTreeObserver vtoDate = recyclerViewDate.getViewTreeObserver(); vtoDate.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { @Override public boolean onPreDraw() { recyclerViewDate.getViewTreeObserver().removeOnPreDrawListener(this); finalWidthDate = recyclerViewDate.getMeasuredWidth(); itemWidthDate = getResources().getDimension(R.dimen.item_dob_width); paddingDate = (finalWidthDate - itemWidthDate) / 2; firstItemWidthDate = paddingDate; allPixelsDate = 0; final LinearLayoutManager dateLayoutManager = new LinearLayoutManager(getApplicationContext()); dateLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL); recyclerViewDate.setLayoutManager(dateLayoutManager); recyclerViewDate.addOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); synchronized (this) { if (newState == RecyclerView.SCROLL_STATE_IDLE) { calculatePositionAndScrollDate(recyclerView); } } } @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); allPixelsDate += dx; } }); if (labelerDates == null) { labelerDates = new ArrayList<>(); } genLabelerDate(); dateAdapter = new DateAdapter(labelerDates, (int) firstItemWidthDate); recyclerViewDate.setAdapter(dateAdapter); dateAdapter.setSelecteditem(dateAdapter.getItemCount() - 1); return true; } }); } private void genLabelerDate() { for (int i = 0; i < 32; i++) { LabelerDate labelerDate = new LabelerDate(); labelerDate.setNumber(Integer.toString(i)); labelerDates.add(labelerDate); if (i == 0 || i == 31) { labelerDate.setType(DateAdapter.VIEW_TYPE_PADDING); } else { labelerDate.setType(DateAdapter.VIEW_TYPE_ITEM); } } } /* this if most important, if expectedPositionDate < 0 recyclerView will return to nearest item*/ private void calculatePositionAndScrollDate(RecyclerView recyclerView) { int expectedPositionDate = Math.round((allPixelsDate + paddingDate - firstItemWidthDate) / itemWidthDate); if (expectedPositionDate == -1) { expectedPositionDate = 0; } else if (expectedPositionDate >= recyclerView.getAdapter().getItemCount() - 2) { expectedPositionDate--; } scrollListToPositionDate(recyclerView, expectedPositionDate); } /* this if most important, if expectedPositionDate < 0 recyclerView will return to nearest item*/ private void scrollListToPositionDate(RecyclerView recyclerView, int expectedPositionDate) { float targetScrollPosDate = expectedPositionDate * itemWidthDate + firstItemWidthDate - paddingDate; float missingPxDate = targetScrollPosDate - allPixelsDate; if (missingPxDate != 0) { recyclerView.smoothScrollBy((int) missingPxDate, 0); } setDateValue(); } // private void setDateValue() { int expectedPositionDateColor = Math.round((allPixelsDate + paddingDate - firstItemWidthDate) / itemWidthDate); int setColorDate = expectedPositionDateColor + 1; // set color here dateAdapter.setSelecteditem(setColorDate); } public class DateAdapter extends RecyclerView.Adapter<DateAdapter.DateViewHolder> { private ArrayList<LabelerDate> dateDataList; private static final int VIEW_TYPE_PADDING = 1; private static final int VIEW_TYPE_ITEM = 2; private int paddingWidthDate = 0; private int selectedItem = -1; public DateAdapter(ArrayList<LabelerDate> dateData, int paddingWidthDate) { this.dateDataList = dateData; this.paddingWidthDate = paddingWidthDate; } @Override public DateViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { if (viewType == VIEW_TYPE_ITEM) { final View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, parent, false); return new DateViewHolder(view); } else { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, parent, false); RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) view.getLayoutParams(); layoutParams.width = paddingWidthDate; view.setLayoutParams(layoutParams); return new DateViewHolder(view); } } @Override public void onBindViewHolder(DateViewHolder holder, int position) { LabelerDate labelerDate = dateDataList.get(position); if (getItemViewType(position) == VIEW_TYPE_ITEM) { holder.tvDate.setText(labelerDate.getNumber()); holder.tvDate.setVisibility(View.VISIBLE); Log.d(TAG, "default " + position + ", selected " + selectedItem); if (position == selectedItem) { Log.d(TAG, "center" + position); holder.tvDate.setTextColor(Color.parseColor("#76FF03")); holder.tvDate.setTextSize(35); } else { holder.tvDate.setTextColor(Color.WHITE); holder.tvDate.setTextSize(18); } } else { holder.tvDate.setVisibility(View.INVISIBLE); } } public void setSelecteditem(int selecteditem) { this.selectedItem = selecteditem; notifyDataSetChanged(); } @Override public int getItemCount() { return dateDataList.size(); } @Override public int getItemViewType(int position) { LabelerDate labelerDate = dateDataList.get(position); if (labelerDate.getType() == VIEW_TYPE_PADDING) { return VIEW_TYPE_PADDING; } else { return VIEW_TYPE_ITEM; } } public class DateViewHolder extends RecyclerView.ViewHolder { public TextView tvDate; public DateViewHolder(View itemView) { super(itemView); tvDate = (TextView) itemView.findViewById(R.id.txt_date); } } } private class LabelerDate { private int type; private String number; public String getNumber() { return number; } public void setNumber(String number) { this.number = number; } public int getType() { return type; } public void setType(int type) { this.type = type; } } } 

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"> <FrameLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <android.support.v7.widget.RecyclerView android:id="@+id/rv_tasks_date" android:layout_width="match_parent" android:layout_height="48dp" /> <ImageView android:layout_width="48dp" android:layout_height="48dp" android:layout_gravity="center" android:layout_marginTop="48dp" android:src="@android:drawable/ic_dialog_info" /> </FrameLayout> </LinearLayout> 

item.xml

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="wrap_content" android:layout_height="match_parent"> <TextView android:id="@+id/txt_date" android:layout_width="@dimen/item_dob_width" android:layout_height="48dp" android:text="32" android:textColor="@android:color/white" android:background="@android:color/darker_gray" android:textSize="28sp" android:gravity="center"/> </LinearLayout> 

dimens.xml

 <resources> <dimen name="item_dob_width">100dp</dimen> </resources> 

我在这里使用了SnapHelper:

  // init snaphelper SnapHelper snapHelper = new LinearSnapHelper(); snapHelper.attachToRecyclerView(recyclerView) // init layout manager LinearLayoutManager layoutManager = new LinearLayoutManager(mainActivity); layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL); recyclerView.setLayoutManager(layoutManager); // init adapter adatper.setSnapHelper(snapHelper); adatper.setLayoutManager(layoutManager); adatper.initAdapter(new Float((DisplayHelper.getDisplayWidth(mainActivity) / 2) - (fooViewWidth / 2)).intValue()); recyclerView.setAdapter(adatper); 

正如TranHieu所说,插入2项填充(在开始和结束位置)的解决scheme是好的。

由于代码的可读性差,我不喜欢使用ViewTreeObserver。 使用这种技术,您还必须pipe理项目的重绘,如果它们被回收。

如果您使用的是customview类,则可以将其宽度直接设置到这些类中。

例如,这是我的填充类

 /** * Created by firegloves on 25/09/15. */ @EViewGroup(R.layout.view_padding) public class PaddingView extends FooView { Context mCtx; public PaddingView(Context context) { super(context); mCtx = context; } public void setWidth(int width) { setLayoutParams(new LayoutParams(width, ViewGroup.LayoutParams.WRAP_CONTENT)); } } 

在我的适配器中,我存储了所需的填充项宽度,等于(displayWidth / 2) – (realItemWidth / 2)

这是我的适配器,不要看不匹配RecyclerView.Adapter的方法,请注意initAdapter方法和onCreateItemView方法

 @EBean public class FooAdapterRecycler extends RecyclerViewAdapterBase<Foo, FooView> { private final int TYPE_PADDING_VIEW = 0; private final int TYPE_REAL_VIEW = 1; @RootContext Context ctx; @Bean(Finder.class) IFinder finder; SnapHelper snapHelper; RecyclerView.LayoutManager layoutManager; private int paddingWidth = 0; /** * preleva i dati dal finder */ public void initAdapter(int paddingWidth) { /******************************* * THIS CODE IS THE IMPORTANT ONE ******************************/ this.paddingWidth = paddingWidth; // add 1 item for initial space mItems = new ArrayList<>(); Foo foo = new Foo(); mItems.add(foo); // get real items from finder mItems.addAll(finder.findAll()); // add 1 item for final space mItems = new ArrayList<>(); Foo foo2 = new Foo(); mItems.add(foo2); } @Override public int getItemViewType(int position) { if (position == 0 || position == getItemCount()-1) { return TYPE_PADDING_VIEW; } else { return TYPE_REAL_VIEW; } } @Override protected FooView onCreateItemView(ViewGroup parent, int viewType) { /******************************* * THIS CODE IS THE IMPORTANT ONE ******************************/ if (viewType == TYPE_PADDING_VIEW) { PaddingView view = PaddingView_.build(ctx); view.setWidth(paddingWidth); return view; } else { return FooView_.build(ctx); } } public void setSnapHelper(SnapHelper snapHelper) { this.snapHelper = snapHelper; } public void setLayoutManager(RecyclerView.LayoutManager layoutManager) { this.layoutManager = layoutManager; } } 

我正在使用AndroidAnnotations库,但不是必需的

希望有所帮助

正如在另一个答案中提到的,没有直接的方法来做到这一点。

这可能是你如何实现你在问题中描述的。

  1. 知道在屏幕上可见的项目数量。
  2. 每次滚动视图时,以编程方式select中间项目。
  3. 保留一个部分透明的图像作为在recyclerview的中间项目的覆盖。 (您需要根据回收站视图的宽度或屏幕宽度以及您select放置的叠加图像的宽度来计算坐标。
  4. 每次滚动时,在回收站视图下方的文本视图中刷新选定的值。

图像叠加必须以它们看起来连接的方式放置,并作为一个单独的控件。

对于这个function使用EcoGallery库: https : //github.com/falnatsheh/EcoGallery

使用SNAPHELPER – 一个更好的解决scheme

这里是使用SnapHelper的另一个解决scheme。 从@TranHieu的答案开始:

https://stackoverflow.com/a/34647005/3944251

和@ sector11压缩在这里:

https://stackoverflow.com/a/38411582/3944251

我写了下面的代码也是基于上面的两个答案,但它更简单,并提供了一个更顺利的解决scheme,使用Android支持库中提供的SnapHelper 24.2.0

在这里你有MainActivity类。 其余的与@ sector11的答案是一样的。

 import android.graphics.Color; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.LinearSnapHelper; import android.support.v7.widget.RecyclerView; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.ViewTreeObserver; import android.widget.TextView; import java.util.ArrayList; public class MainActivity extends AppCompatActivity { private static final String TAG = MainActivity.class.getSimpleName(); public float firstItemWidthDate; public float itemWidthDate; public int allPixelsDate; public int finalWidthDate; private DateAdapter dateAdapter; private ArrayList<LabelerDate> labelerDates; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); labelerDates = new ArrayList<>(); getRecyclerviewDate(); } public void getRecyclerviewDate() { final RecyclerView recyclerViewDate = (RecyclerView) findViewById(R.id.rv_tasks_date); recyclerViewDate.postDelayed(new Runnable() { @Override public void run() { //recyclerViewDate.smoothScrollToPosition(dateAdapter.getItemCount()-1); setDateValue(); } }, 300); ViewTreeObserver vtoDate = recyclerViewDate.getViewTreeObserver(); vtoDate.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { @Override public boolean onPreDraw() { recyclerViewDate.getViewTreeObserver().removeOnPreDrawListener(this); finalWidthDate = recyclerViewDate.getMeasuredWidth(); itemWidthDate = getResources().getDimension(R.dimen.item_db_width); firstItemWidthDate = (finalWidthDate - itemWidthDate) / 2; allPixelsDate = 0; final LinearLayoutManager dateLayoutManager = new LinearLayoutManager(getApplicationContext()); dateLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL); recyclerViewDate.setLayoutManager(dateLayoutManager); /* Create a LinearSnapHelper and attach the recyclerView to it. */ final LinearSnapHelper snapHelper = new LinearSnapHelper(); snapHelper.attachToRecyclerView(recyclerViewDate); recyclerViewDate.addOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { allPixelsDate += dx; recyclerView.post(new Runnable() { public void run() { setDateValue(); } }); } }); genLabelerDate(); dateAdapter = new DateAdapter(labelerDates, (int) firstItemWidthDate); recyclerViewDate.setAdapter(dateAdapter); dateAdapter.setSelecteditem(dateAdapter.getItemCount() - 1); return true; } }); } private void genLabelerDate() { for (int i = 0; i < 32; i++) { LabelerDate labelerDate = new LabelerDate(); labelerDate.setNumber(Integer.toString(i)); labelerDates.add(labelerDate); if (i == 0 || i == 31) { labelerDate.setType(DateAdapter.VIEW_TYPE_PADDING); } else { labelerDate.setType(DateAdapter.VIEW_TYPE_ITEM); } } } // private void setDateValue() { int expectedPositionDateColor = Math.round(allPixelsDate / itemWidthDate); int setColorDate = expectedPositionDateColor + 1; // set color here dateAdapter.setSelecteditem(setColorDate); } public class DateAdapter extends RecyclerView.Adapter<DateAdapter.DateViewHolder> { private ArrayList<LabelerDate> dateDataList; private static final int VIEW_TYPE_PADDING = 1; private static final int VIEW_TYPE_ITEM = 2; private int paddingWidthDate = 0; private int selectedItem = -1; public DateAdapter(ArrayList<LabelerDate> dateData, int paddingWidthDate) { this.dateDataList = dateData; this.paddingWidthDate = paddingWidthDate; } @Override public DateAdapter.DateViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, parent, false); if (viewType == VIEW_TYPE_PADDING) { RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) view.getLayoutParams(); layoutParams.width = paddingWidthDate; view.setLayoutParams(layoutParams); } return new DateViewHolder(view); } @Override public void onBindViewHolder(DateAdapter.DateViewHolder holder, int position) { LabelerDate labelerDate = dateDataList.get(position); if (getItemViewType(position) == VIEW_TYPE_ITEM) { holder.tvDate.setText(labelerDate.getNumber()); holder.tvDate.setVisibility(View.VISIBLE); Log.d(TAG, "default " + position + ", selected " + selectedItem); if (position == selectedItem) { Log.d(TAG, "center" + position); holder.tvDate.setTextColor(Color.parseColor("#76FF03")); holder.tvDate.setTextSize(35); } else { holder.tvDate.setTextColor(Color.WHITE); holder.tvDate.setTextSize(18); } } else { holder.tvDate.setVisibility(View.INVISIBLE); } } public void setSelecteditem(int selecteditem) { this.selectedItem = selecteditem; notifyDataSetChanged(); } @Override public int getItemCount() { return dateDataList.size(); } @Override public int getItemViewType(int position) { LabelerDate labelerDate = dateDataList.get(position); if (labelerDate.getType() == VIEW_TYPE_PADDING) { return VIEW_TYPE_PADDING; } else { return VIEW_TYPE_ITEM; } } public class DateViewHolder extends RecyclerView.ViewHolder { public TextView tvDate; public DateViewHolder(View itemView) { super(itemView); tvDate = (TextView) itemView.findViewById(R.id.txt_date); } } } private class LabelerDate { private int type; private String number; public String getNumber() { return number; } public void setNumber(String number) { this.number = number; } public int getType() { return type; } public void setType(int type) { this.type = type; } } } 

我不认为有什么直接的办法来实现这一点。 你可以试试这个 –

listView.setOnScrollListener(收听);

@覆盖

 public void onScroll(AbsListView view, int firstVisibleItem,int visibleItemCount, int totalItemCount) { int firstVisibleRow = listView.getFirstVisiblePosition(); int lastVisibleRow = listView.getLastVisiblePosition(); int count - ((int*)count/2; int middle = listview.getChildAt(count - ((int)count/2)); } } 

你也可以参考这个答案https://stackoverflow.com/a/13134100/1320616 https://stackoverflow.com/a/19205940/1320616

起初,我需要类似的东西,而不是这个。 但是我能够根据自己的需要调整@TranHieu解决scheme,所以我投了他的解决scheme。

我想创build全屏水平recyclerview后,用户滚动更新scrollPosition为mostVisibleItem。

build立:

 private void setUpScrolling() { mRecyclerVIew.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { @Override public boolean onPreDraw() { mRecyclerVIew.getViewTreeObserver().removeOnPreDrawListener(this); CustomScrollListener listener = (CustomScrollListener) mScrollListener; listener.width = mRecyclerVIew.getMeasuredWidth(); listener.dx = 0; return true; } }); } 

听众:

 private class CustomScrollListener extends OnScrollListener { private int mLastDx = 0; int width = 0; int dx = 0; @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { if (newState == RecyclerView.SCROLL_STATE_IDLE) { if (mLastDx != dx) { scrollToMostVisibleItem(); } else { dx = 0; mLastDx = 0; } } super.onScrollStateChanged(recyclerView, newState); } @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); this.dx += dx; } private void scrollToMostVisibleItem() { int direction = (dx > 0) ? 1 : -1; dx = Math.abs(dx); int shiftCount = Math.round(dx / width); int pixelShift = dx % width; if (pixelShift > width / 2) { shiftCount++; } float targetScrollPixels = shiftCount * width; float finalScrollPixels = (targetScrollPixels - dx) * direction; if (finalScrollPixels != 0) { mRecyclerVIew.smoothScrollBy((int) finalScrollPixels, 0); mLastDx = (int) finalScrollPixels; dx = 0; } } } 

在我的情况下,我用另一种方法。

你可以在这里finddeatils: RecyclerView – 在滚动 1 期间如何突出中心可见项目

在我看来,我的解决scheme比其他解决scheme更容易。