gpt4 book ai didi

android - RecyclerView 在设备方向更改时保存位置

转载 作者:塔克拉玛干 更新时间:2023-11-02 21:15:52 27 4
gpt4 key购买 nike

在我的应用程序中,我有一个与适配器连接的 RecyclerView,但每次我的设备从横向变为纵向或其他方式时, View 都会重新加载,我会再次回到顶部。我想将我的滚动位置保存到我看到的最后一个项目

这是我尝试过的:

我有一个从另一个 fragment 延伸的 fragment ,状态应该保存在 MainPageFragment 中。我试图保存最后加载的位置并将其放入 savedState,它被正确检索但是如果我调用“scrollToPosition”没有任何反应。

package com.pr0.pr0grammreloaded.fragment;

/**
* Created by Dominik on 22.02.2015.
*/
import android.app.Activity;
import android.app.FragmentManager;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.pr0.pr0grammreloaded.MainActivity;
import com.pr0.pr0grammreloaded.R;
import com.pr0.pr0grammreloaded.config.FilterConfig;
import com.pr0.pr0grammreloaded.util.FixedRecyclerView;
import com.pr0.pr0grammreloaded.util.MainPageSaveParcelable;
import com.pr0.pr0grammreloaded.util.MyLayoutManager;
import com.pr0.pr0grammreloaded.util.RecyclerViewDelegate;

import java.util.ArrayList;

import uk.co.senab.actionbarpulltorefresh.extras.actionbarsherlock.PullToRefreshLayout;
import uk.co.senab.actionbarpulltorefresh.library.ActionBarPullToRefresh;
import uk.co.senab.actionbarpulltorefresh.library.listeners.OnRefreshListener;
import uk.co.senab.actionbarpulltorefresh.library.viewdelegates.AbsListViewDelegate;

/**
* Created by Dominik on 17.01.2015.
*/
public class MainPageFragment extends Pr0MainPageFragment {


/**
* The fragment argument representing the section number for this
* fragment.
*/
private static final String ARG_SECTION_NUMBER = "section_number";

/**
* Returns a new instance of this fragment for the given section
* number.
*/
public static MainPageFragment newInstance(FilterConfig config) {
MainPageFragment fragment = new MainPageFragment();
fragment.config = config;
return fragment;
}

public MainPageFragment() {

}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {

if(savedInstanceState != null){
MainPageSaveParcelable saveParcelable = savedInstanceState.getParcelable("save");
View rootView = inflater.inflate(R.layout.mainpage_fragment, container, false);

recyclerView = (RecyclerView) rootView.findViewById(R.id.list);
adapter = new ItemAdapter();
itemList = saveParcelable.itemList;
config = saveParcelable.config;
// use better layout manager, maybe write our own?
recyclerView.setLayoutManager(new GridLayoutManager(MainActivity.getActivity(), 3));
recyclerView.setAdapter(adapter);
restorePositon = saveParcelable.position;

mPullToRefreshLayout = (PullToRefreshLayout) rootView.findViewById(R.id.ptr_layout);

// Now setup the PullToRefreshLayout
ActionBarPullToRefresh.from(getActivity())
// Mark All Children as pullable
.allChildrenArePullable()
// Set a OnRefreshListener
.listener(new OnRefreshListener() {
@Override
public void onRefreshStarted(View view) {
if (!isBlocked()) {
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.container, MainPageFragment.newInstance(MainActivity.filterConfig))
.commit();
}
}


})
// Finally commit the setup to our PullToRefreshLayout
.useViewDelegate(FixedRecyclerView.class, new RecyclerViewDelegate())
.setup(mPullToRefreshLayout);

loadFeed();
// recyclerView.scrollToPosition(saveParcelable.);
return rootView;
}else {
View rootView = inflater.inflate(R.layout.mainpage_fragment, container, false);

recyclerView = (RecyclerView) rootView.findViewById(R.id.list);

adapter = new ItemAdapter();
itemList = new ArrayList<>();
// use better layout manager, maybe write our own?
recyclerView.setLayoutManager(new GridLayoutManager(MainActivity.getActivity(), 3));
recyclerView.setAdapter(adapter);

mPullToRefreshLayout = (PullToRefreshLayout) rootView.findViewById(R.id.ptr_layout);

// Now setup the PullToRefreshLayout
ActionBarPullToRefresh.from(getActivity())
// Mark All Children as pullable
.allChildrenArePullable()
// Set a OnRefreshListener
.listener(new OnRefreshListener() {
@Override
public void onRefreshStarted(View view) {
if (!isBlocked()) {
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.container, MainPageFragment.newInstance(MainActivity.filterConfig))
.commit();
}
}


})
// Finally commit the setup to our PullToRefreshLayout
.useViewDelegate(FixedRecyclerView.class, new RecyclerViewDelegate())
.setup(mPullToRefreshLayout);

loadFeed();
return rootView;
}
}

@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
}

@Override
public void onSaveInstanceState(Bundle state){
super.onSaveInstanceState(state);
restorePositon = lastPositon;
MainPageSaveParcelable saveParcelable = new MainPageSaveParcelable(itemList,firstChunk,config,restorePositon);
state.putParcelable("save",saveParcelable);
}


}

Pr0MainPageFragment

package com.pr0.pr0grammreloaded.fragment;

import android.app.Fragment;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.pr0.pr0grammreloaded.MainActivity;
import com.pr0.pr0grammreloaded.R;
import com.pr0.pr0grammreloaded.api.Api;
import com.pr0.pr0grammreloaded.api.Feed;
import com.pr0.pr0grammreloaded.api.InstantDeserializer;
import com.pr0.pr0grammreloaded.config.FilterConfig;
import com.squareup.picasso.Picasso;

import org.joda.time.Instant;

import java.util.ArrayList;
import java.util.List;

import retrofit.RestAdapter;
import retrofit.converter.GsonConverter;
import rx.functions.Action1;
import uk.co.senab.actionbarpulltorefresh.extras.actionbarsherlock.PullToRefreshLayout;

import static rx.android.observables.AndroidObservable.bindActivity;

/**
* Created by Dominik on 22.02.2015.
*/
public class Pr0MainPageFragment extends Fragment {

protected ItemAdapter adapter;
protected boolean firstChunk = true;
protected List<Feed.Item> itemList;
protected FilterConfig config;
private boolean blockLoading = false;
protected PullToRefreshLayout mPullToRefreshLayout;
protected int restorePositon = 0;
protected int lastPositon = 0;
protected RecyclerView recyclerView;
protected boolean isRestore = false;

/**
* Loads the feed from pr0gramm. This should be put into some kind of service
* that is injected into our activities.
*/
protected void loadFeed() {
if(!blockLoading) {
blockLoading = true;
Log.e("Pr0","Blocked loading!");
Gson gson = new GsonBuilder()
.registerTypeAdapter(Instant.class, new InstantDeserializer())
.create();

Api api = new RestAdapter.Builder()
.setEndpoint("http://pr0gramm.com")
.setConverter(new GsonConverter(gson))
.setLogLevel(RestAdapter.LogLevel.BASIC)
.build()
.create(Api.class);

// perform api request in the background and call
// back to the main thread on finish

if (firstChunk) {
bindActivity(MainActivity.getActivity(), api.itemsGet(config.getFlag(), 1)).subscribe(new Action1<Feed>() {
@Override
public void call(Feed feed) {
// we are now back in the main thread
firstChunk = false;
handleFeedResponse(feed);
}
});
} else {
//Log.e("Pr0", "Loading after ID : " + itemList.get(0).getId());
for(int x = 0; x < itemList.size();x ++){
Log.e("Pr0", "POS: " + x + ", ID : " + itemList.get(x).getId());
}
bindActivity(MainActivity.getActivity(), api.olderGet(itemList.get(itemList.size() - 1).getPromoted(), config.getFlag(), 1)).subscribe(new Action1<Feed>() {
@Override
public void call(Feed feed) {
// we are now back in the main thread
handleFeedResponse(feed);
}
});
}
}
}

/**
* Display the elements from the feed
*
* @param feed The feed to display
*/
private void handleFeedResponse(Feed feed) {
// display feed now.
//Log.i("MainActivity", "Number of items: " + feed.getItems().size());
adapter.addItems(feed.getItems());
mPullToRefreshLayout.setRefreshComplete();
restorePostion();
}


protected class ItemAdapter extends RecyclerView.Adapter<ItemView> {


ItemAdapter() {
setHasStableIds(true);
}

@Override
public ItemView onCreateViewHolder(ViewGroup viewGroup, int i) {
LayoutInflater inflater = LayoutInflater.from(MainActivity.getActivity());
View view = inflater.inflate(R.layout.item_view, viewGroup, false);
return new ItemView(view);
}

@Override
public void onBindViewHolder(ItemView itemView, int i) {
// Log.e("Pr0","load id : " + i);
//Log.e("Pr0",String.valueOf(itemList.get(i).getId()));
String url = "http://thumb.pr0gramm.com/" + itemList.get(i).getThumb();
Picasso.with(getActivity())
.setIndicatorsEnabled(true);
Picasso.with(getActivity())
.load(url)
.into(itemView.image);
lastPositon = i;
Log.w("Pr0","last positon : " + i);
if(i > itemList.size() - 5){
//Log.e("Pr0","SIZE : " + itemList.size());
//Log.e("Pr0","End Reached Load After ID : " + itemList.get(0).getId());
loadFeed();
}
}

@Override
public int getItemCount() {
return itemList.size();
}

public void addItems(List<Feed.Item> itemsToAdd) {

int oldCount = itemList.size();
itemList.addAll(itemsToAdd);
notifyItemRangeInserted(oldCount, itemList.size());
/*
for(Feed.Item item : itemsToAdd) {
//Log.e("Pr0","Added image ID : " + item.getId());
int oldCount = itemList.size();
itemList.add(item);
notifyItemRangeInserted(oldCount, itemList.size());
}
*/
blockLoading = false;
Log.e("Pr0","Unblocked Loading");
//
}

@Override
public long getItemId(int position) {
return itemList.get(position).getId();
}
}

/**
* View holder for a view in the list of items
*/
private class ItemView extends RecyclerView.ViewHolder {
final ImageView image;

public ItemView(View itemView) {
super(itemView);
image = (ImageView) itemView.findViewById(R.id.image);
}
}

public boolean isBlocked(){
return this.blockLoading;
}

public void reset(){
itemList.clear();
firstChunk = true;
}

public void restorePostion(){
Log.w("Pr0", "Restore : " + restorePositon);
recyclerView.scrollToPosition(restorePositon);
}
}

这是我的包裹

package com.pr0.pr0grammreloaded.util;

import android.os.Parcel;
import android.os.Parcelable;

import com.pr0.pr0grammreloaded.account.User;
import com.pr0.pr0grammreloaded.api.Feed;
import com.pr0.pr0grammreloaded.config.FilterConfig;

import java.util.List;

/**
* Created by Dominik on 27.02.2015.
*/
public class MainPageSaveParcelable implements Parcelable{

public boolean firstChunk;
public List<Feed.Item> itemList;
public FilterConfig config;
public int position;

public MainPageSaveParcelable(List<Feed.Item> itemList, boolean firstChunk, FilterConfig config, int position){
this.firstChunk = firstChunk;
this.itemList = itemList;
this.config = config;
this.position = position;
}

@Override
public int describeContents() {
return 0;
}

@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeList(itemList);
dest.writeValue(config);
dest.writeValue(firstChunk);
dest.writeInt(position);
}

/** Static field used to regenerate object, individually or as arrays */
public static final Parcelable.Creator<MainPageSaveParcelable> CREATOR = new Parcelable.Creator<MainPageSaveParcelable>() {
public MainPageSaveParcelable createFromParcel(Parcel pc) {
return new MainPageSaveParcelable(pc);
}
public MainPageSaveParcelable[] newArray(int size) {
return new MainPageSaveParcelable[size];
}
};

/**Ctor from Parcel, reads back fields IN THE ORDER they were written */
public MainPageSaveParcelable(Parcel pc){
pc.readList(itemList,List.class.getClassLoader());
config = (FilterConfig) pc.readValue(FilterConfig.class.getClassLoader());
firstChunk = (boolean) pc.readValue(Boolean.class.getClassLoader());
position = pc.readInt();
}
}

最佳答案

您可以使用滚动监听器并在 SharedPreference 或任何您喜欢的滚动时保存第一个项目或 RecyclerView 状态

在您的 Activity 或 fragment 中将这些变量定义为私有(private)变量

    int firstCompleteVisibleItemPosition;
int firstVisibleItemPosition;
Parcelable recyclerViewState;

在滚动监听器上使用 recyclerview

  recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
}

@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);


firstCompleteVisibleItemPosition = recyclerView.getLayoutManager().findFirstCompletelyVisibleItemPosition();
firstVisibleItemPosition = recyclerView.getLayoutManager().findFirstVisibleItemPosition();
recyclerViewState = recyclerView.getLayoutManager().onSaveInstanceState();


}
});

如果方向发生变化,您可以通过此方法保存的最后位置开始您的回收 View

linearLayoutManager.scrollToPositionWithOffset(firstVisibleItemPosition, 0);

或者通过recyclerview的最后状态

rv.getLayoutManager().onRestoreInstanceState(recyclerViewState);

关于android - RecyclerView 在设备方向更改时保存位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28775860/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com