- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
在我的应用程序中,我有一个与适配器连接的 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/
我正在使用 MapBox 绘制兴趣点,这些兴趣点是通过基于 Rails 构建的用户生成表单提交的。当前,用户输入一个地址,然后该地址通过 gem(地理编码器)计算出 Lat 和 Lng。从那里我通过
我正在纵向平板电脑上开发应用程序。 但是,当平板电脑转到横向模式时,应用程序也会转动,并且所有对齐方式都将被取消。那么有什么方法可以将我的 WPF 应用程序锁定到一个方向? 谢谢! 最佳答案 我必须同
我在我的应用程序中的 mkmapview 上显示了两点之间的路线,但我想显示这两点的方向。点的纬度和经度存储在 NSArray 中。 最佳答案 这可能为时已晚,您可能已经解决了它,但这是我已经测试过并
我正在处理一个小型 Unity3D 项目,我需要从另一个工具导入一些数据。该工具通过两个向量为我提供了对象方向,我需要将其移植到 Unity。 例如,我有这两个向量; x = Vector( 0.70
有没有办法以编程方式设置 UIActionSheet 的方向?我的 iPhone 方向是纵向,但 UIActionSheet 需要是横向。这可以吗? 编辑: 所以我的问题是我不想将 rootviewc
如何在 Python 中根据 2 个 GPS 坐标计算速度、距离和方向(度)?每个点都有纬度、经度和时间。 我在这篇文章中找到了半正矢距离计算: Calculate distance between
需要一个代码来更改 div 的属性,具体取决于 iPhone 设备的位置。在这段代码工作之前现在停止这样做了吗? @media all and (orientation:portrait) { .
在“View Did Load”中,我试图确定 View 的大小,以便我可以适本地调整 subview 的大小。我希望它始终围绕屏幕的长度和宽度拉伸(stretch),而不管方向如何。 quest *
如何根据对象的方向移动对象?我的意思是,我有一个处于某个位置的立方体,我想绕 Y 轴旋转并根据它们的方向移动。然后再次移动和旋转以改变方向。像这样的事情: 最佳答案 在 JS 中你可以尝试这样的事情:
我目前有一个处于横向模式的 SurfaceView。 目前我正在尝试使用添加操作栏/菜单栏 /*Action Bar */ //this.setRequestedOrientation(Activit
我正在使用 cocos2d,我想播放电影。为此,我创建了 MPMoviePlayerViewController 并将其作为 [[CCDirector sharedDirector] openGLVi
我在 cocos2d 中创建了一个游戏,因为我想使用我找到的一些 UIKit 元素 kobold2d。 我移植了游戏,但问题是我的 iPhone 刺激器旋转了, 但不是显示的节点。 必须使用: bac
我可以在 iOS 中的 UITabBarController 中更改方向吗?我有这样的东西: UITableViewController-> Team Tab -> UINavigationContr
我有 UINavigationController 和几个 View Controller 。这是他们的名单:主->相册->图片 现在,在第一个和第二个(主要和专辑)中,我希望 UINavigatio
人们普遍认为,在过去几年中,标准显示器的最佳网站宽度已从 800 像素增加到 1024+ 像素(网站通常为 960 像素宽),但随着移动设备的兴起,哪些分辨率被认为是“关键”迎合? 例如,this
我正在做一个 GTK+ 项目,我需要一个像这样的垂直 GtkLevelBar: 但我不知道如何从默认的水平 GtkLevelBar 翻转它: 这是我的 GtkLevelBar 代码。 GtkWidge
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
我的 collectionView 以横向模式显示 20 个项目。在纵向模式下,我只想展示 8 个可重复使用的项目。我怎样才能做到这一点? collectionView 何时在数据源上调用 colle
可以在 list 文件中设置 Activity 的方向。 但是否也可以通过代码来实现?如果是,怎么办? 谢谢! 最佳答案 setRequestedOrientation(ActivityInfo.SC
我希望在纬度、经度和用户当前位置之间集成方向。我希望通过点击按钮将用户定向到已安装的 Google map /其他应用程序并显示方向。 我搜索了 SO 和谷歌,但找不到好的来源,因此我发布了这个问题。
我是一名优秀的程序员,十分优秀!