在我的应用程序中,我有一个与适配器连接的RecyclerView,但每当我的设备从横向更改为纵向或其他内容时,视图将重新加载,我将再次登顶。我想将滚动位置保存到我看到的最后一个项目。
以下是我的尝试:
我有一个片段,它从另一个片段扩展,状态应该保存在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);
}
}
这是我的Parcelable
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();
}
}
答案 0 :(得分:2)
您可以使用滚动侦听器并在滚动SharedPreference或您喜欢的任何内容时保存第一项或RecyclerView状态
将这些变量定义为活动或片段中的私有变量
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();
}
});
如果方向发生变化,您可以通过此方法保存的上一个位置开始您的回收站视图
linearLayoutManager.scrollToPositionWithOffset(firstVisibleItemPosition, 0);
或按照recyclerview的最后状态
rv.getLayoutManager().onRestoreInstanceState(recyclerViewState);