Android 打开新活动后的RecyclerView丢失状态
通过将应用程序扩展到自定义类,我为应用程序创建了自定义RecyclerView。在调用Android 打开新活动后的RecyclerView丢失状态,android,android-recyclerview,Android,Android Recyclerview,通过将应用程序扩展到自定义类,我为应用程序创建了自定义RecyclerView。在调用onBackPressed()之前,我使用canscrollvertical(-1)检查RecyclerView是否可以滚动到顶部。但问题是在打开新活动以查看其中一个RecyclerView项目的完整详细信息并按back返回列表后。RecyclerView似乎失去了焦点,调用CanScrollVertical总是正确的,即使它被认为是错误的。是否需要将方法重写到此自定义类 这是我的自定义RecyclerView
onBackPressed()
之前,我使用canscrollvertical(-1)
检查RecyclerView是否可以滚动到顶部。但问题是在打开新活动以查看其中一个RecyclerView项目的完整详细信息并按back返回列表后。RecyclerView似乎失去了焦点,调用CanScrollVertical
总是正确的,即使它被认为是错误的。是否需要将方法重写到此自定义类
这是我的自定义RecyclerView类
public class AutoPlayVideoRecyclerView extends RecyclerView {
private PublishSubject<Integer> subject;
private VideoHolder handingVideoHolder;
private int handlingPosition = 0;
private int newPosition = -1;
private int heightScreen;
public AutoPlayVideoRecyclerView(Context context) {
super(context);
initView(context);
Crashlytics.log("AutoPlayVideoRecyclerView");
}
public AutoPlayVideoRecyclerView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
initView(context);
}
public AutoPlayVideoRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initView(context);
}
public VideoHolder getHandingVideoHolder() {
return handingVideoHolder;
}
private void initView(Context context) {
heightScreen = getHeightScreen(context);
subject = createSubject();
addOnScrollListener(new OnScrollListener() {
@Override
public void onScrolled(@androidx.annotation.NonNull RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
checkPositionHandingViewHolder();
subject.onNext(dy);
}
});
}
private void checkPositionHandingViewHolder() {
if (handingVideoHolder == null) return;
Observable.just(handingVideoHolder)
.map(this::getPercentViewHolderInScreen)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<Float>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
}
@Override
public void onNext(@NonNull Float aFloat) {
if (aFloat < 50 && handingVideoHolder != null) {
handingVideoHolder.stopVideo();
handingVideoHolder = null;
handlingPosition = -1;
}
}
@Override
public void onError(@NonNull Throwable e) {
}
@Override
public void onComplete() {
}
});
}
private int getHeightScreen(Context context) {
DisplayMetrics displayMetrics = new DisplayMetrics();
WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
if (windowManager != null) {
windowManager.getDefaultDisplay().getMetrics(displayMetrics);
}
return displayMetrics.heightPixels;
}
@SuppressWarnings("ResultOfMethodCallIgnored")
@SuppressLint("CheckResult")
private PublishSubject<Integer> createSubject() {
subject = PublishSubject.create();
subject.debounce(300, TimeUnit.MILLISECONDS)
.filter(value -> true)
.switchMap((Function<Integer, ObservableSource<Integer>>) Observable::just)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(this::playVideo);
return subject;
}
private void playVideo(float value) {
Observable.just(value)
.map(aFloat -> {
VideoHolder videoHolder = getViewHolderCenterScreen();
if (videoHolder == null) return null;
if (videoHolder.equals(handingVideoHolder) && handlingPosition == newPosition)
return null;
handlingPosition = newPosition;
return videoHolder;
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<VideoHolder>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
}
@Override
public void onNext(@NonNull VideoHolder videoHolder) {
if (handingVideoHolder != null) handingVideoHolder.stopVideo();
videoHolder.playVideo();
handingVideoHolder = videoHolder;
}
@Override
public void onError(@NonNull Throwable e) {
}
@Override
public void onComplete() {
}
});
}
private VideoHolder getViewHolderCenterScreen() {
int[] limitPosition = getLimitPositionInScreen();
int min = limitPosition[0];
int max = limitPosition[1];
VideoHolder viewHolderMax = null;
float percentMax = 0;
for (int i = min; i <= max; i++) {
ViewHolder viewHolder = findViewHolderForAdapterPosition(i);
if (!(viewHolder instanceof VideoHolder)) continue;
float percentViewHolder = getPercentViewHolderInScreen((VideoHolder) viewHolder);
if (percentViewHolder > percentMax && percentViewHolder >= 50) {
percentMax = percentViewHolder;
viewHolderMax = (VideoHolder) viewHolder;
newPosition = i;
}
}
return viewHolderMax;
}
private float getPercentViewHolderInScreen(VideoHolder viewHolder) {
if (viewHolder == null) return 0;
View view = viewHolder.getVideoLayout();
int[] location = new int[2];
view.getLocationOnScreen(location);
int viewHeight = view.getHeight();
int viewFromY = location[1];
int viewToY = location[1] + viewHeight;
if (viewFromY >= 0 && viewToY <= heightScreen) return 100;
if (viewFromY < 0 && viewToY > heightScreen) return 100;
if (viewFromY < 0)
return ((float) (viewToY - (-viewFromY)) / viewHeight) * 100;
return ((float) (heightScreen - viewFromY) / viewHeight) * 100;
}
private int[] getLimitPositionInScreen() {
int findFirstVisibleItemPosition = ((LinearLayoutManager) Objects.requireNonNull(getLayoutManager())).findFirstVisibleItemPosition();
int findFirstCompletelyVisibleItemPosition = ((LinearLayoutManager) getLayoutManager()).findFirstCompletelyVisibleItemPosition();
int findLastVisibleItemPosition = ((LinearLayoutManager) getLayoutManager()).findLastVisibleItemPosition();
int findLastCompletelyVisibleItemPosition = ((LinearLayoutManager) getLayoutManager()).findLastCompletelyVisibleItemPosition();
int min = Math.min(Math.min(findFirstVisibleItemPosition, findFirstCompletelyVisibleItemPosition),
Math.min(findLastVisibleItemPosition, findLastCompletelyVisibleItemPosition));
int max = Math.max(Math.max(findFirstVisibleItemPosition, findFirstCompletelyVisibleItemPosition),
Math.max(findLastVisibleItemPosition, findLastCompletelyVisibleItemPosition));
return new int[]{min, max};
}
@Override
public boolean canScrollVertically(int direction) {
return super.canScrollVertically(direction);
}
@Override
public void setViewCacheExtension(@Nullable ViewCacheExtension extension) {
super.setViewCacheExtension(extension);
}
@Override
public void setItemViewCacheSize(int size) {
super.setItemViewCacheSize(size);
}
@Override
public void smoothScrollToPosition(int position) {
super.smoothScrollToPosition(position);
}
}
公共类AutoPlayVideoRecyclerView扩展了RecyclerView{
私人出版主体;
私人视频持有者处理视频持有者;
私有int handlingPosition=0;
private int newPosition=-1;
私用内屏幕;
公共自动播放视频回收视图(上下文){
超级(上下文);
initView(上下文);
Crashlytics.log(“自动播放视频回收视图”);
}
公共AutoPlayVideoRecyclerView(上下文上下文,@Nullable AttributeSet attrs){
超级(上下文,attrs);
initView(上下文);
}
公共AutoPlayVideoRecyclerView(上下文上下文,@Nullable AttributeSet attrs,int-defStyle){
超级(上下文、属性、定义样式);
initView(上下文);
}
公共视频持有者getHandingVideoHolder(){
返回处理视频持有者;
}
私有void initView(上下文){
heightScreen=getHeightScreen(上下文);
subject=createSubject();
addOnScrollListener(新的OnScrollListener(){
@凌驾
已克隆的公共无效(@androidx.annotation.NonNull RecyclerView RecyclerView,int dx,int dy){
super.onScrolled(recyclerView、dx、dy);
检查位置操纵视图支架();
主题.onNext(dy);
}
});
}
私有无效检查位置HandingViewHolder(){
if(handingVideoHolder==null)返回;
可观察。仅(手持视频支架)
.map(此::getPercentViewHolderInScreen)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.订阅(新观察员){
@凌驾
订阅时的公共无效(@NonNull-d){
}
@凌驾
public void onNext(@NonNull Float aFloat){
如果(漂浮<50&&handingVideoHolder!=空){
handingVideoHolder.stopVideo();
handingVideoHolder=null;
处理位置=-1;
}
}
@凌驾
公共无效onError(@NonNull可丢弃e){
}
@凌驾
未完成的公共空间(){
}
});
}
私有int getHeightScreen(上下文){
DisplayMetrics DisplayMetrics=新的DisplayMetrics();
WindowManager WindowManager=(WindowManager)context.getSystemService(context.WINDOW\u服务);
如果(windowManager!=null){
windowManager.getDefaultDisplay().getMetrics(displayMetrics);
}
返回displayMetrics.heightPixels;
}
@抑制警告(“ResultOfMethodCallIgnored”)
@SuppressLint(“检查结果”)
私有PublishSubject createSubject(){
subject=PublishSubject.create();
主题。去盎司(300,时间单位。毫秒)
.filter(值->真)
.switchMap((函数)可观察::just)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.订阅(此::播放视频);
返回主题;
}
私有void播放视频(浮动值){
可观察的。公正(价值)
.map(漂浮->{
VideoHolder VideoHolder=GetViewHolderCenter屏幕();
如果(videoHolder==null)返回null;
if(videoHolder.equals(handingVideoHolder)和&handlingPosition==newPosition)
返回null;
handlingPosition=新位置;
返回视频持有者;
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.订阅(新观察员){
@凌驾
订阅时的公共无效(@NonNull-d){
}
@凌驾
public void onNext(@NonNull VideoHolder VideoHolder){
if(handingVideoHolder!=null)handingVideoHolder.stopVideo();
playVideo();
handingVideoHolder=videoHolder;
}
@凌驾
公共无效onError(@NonNull可丢弃e){
}
@凌驾
未完成的公共空间(){
}
});
}
私有视频持有者GetViewHolderCenter屏幕(){
int[]limitPosition=getLimitPositionInScreen();
int min=限制位置[0];
int max=极限位置[1];
VideoHolder viewHolderMax=null;
浮动百分比max=0;
对于(int i=min;i percentMax&&percentViewHolder>=50){
percentMax=percentViewHolder;
viewHolderMax=(VideoHolder)viewHolder;
newPosition=i;
}
}
返回viewHolderMax;
}
私有浮动GetPercentViewHolderScreen(VideoHolder viewHolder){
if(viewHolder==null)返回0;
View=viewHolder.getVideoLayout();
int[]位置=新int[2];