我正在尝试解决此问题,但是我已经陷入困境。 当页面滚动到底部时,我要使从服务器读取的数据连续不断。但是我得到的是重复显示的数据。
此代码有时会按预期显示,但有时却不会。 如果我缓慢滚动并等待下一次提取,它将按预期运行,但是如果执行得很快,它将使提取的数据翻倍。
我希望将此页面设置为instagram用户个人资料,例如滚动我们的帖子。
这是布局
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingBottom="@dimen/padding_10"
android:paddingLeft="@dimen/padding_20"
android:paddingRight="@dimen/padding_20"
android:paddingTop="@dimen/padding_10">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_weight="2"
android:orientation="vertical">
<de.hdodenhof.circleimageview.CircleImageView
android:id="@+id/civ_user_photo"
android:layout_width="match_parent"
android:layout_height="90dp"
android:src="@drawable/ic_pol_avatar"
app:civ_border_color="@color/casablanka"
app:civ_border_width="1dp" />
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/padding_20"
android:layout_weight="6"
android:orientation="vertical">
<LinearLayout
android:id="@+id/report_status"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<LinearLayout
android:id="@+id/ll_report"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="3"
android:orientation="vertical">
<TextView
android:id="@+id/tv_total_report"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:text="0"
android:textColor="@color/white"
android:textSize="20sp" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:text="@string/status_report"
android:textColor="@color/white" />
</LinearLayout>
<LinearLayout
android:id="@+id/ll_wait"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="3"
android:orientation="vertical">
<TextView
android:id="@+id/tv_total_wait"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:text="0"
android:textColor="@color/white"
android:textSize="20sp" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:text="@string/status_wait"
android:textColor="@color/white" />
</LinearLayout>
<LinearLayout
android:id="@+id/ll_complete"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="3"
android:orientation="vertical">
<TextView
android:id="@+id/tv_total_complete"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:text="0"
android:textColor="@color/white"
android:textSize="20sp" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:text="@string/status_complete"
android:textColor="@color/white" />
</LinearLayout>
</LinearLayout>
<RelativeLayout
android:id="@+id/btn_edit_profil"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/report_status"
android:layout_marginTop="@dimen/padding_14"
android:background="@drawable/button_edit_profile"
android:padding="@dimen/padding_8">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/edit_profile"
android:textAlignment="center"
android:textColor="@color/casablanka" />
</RelativeLayout>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingLeft="@dimen/padding_20"
android:paddingRight="@dimen/padding_20">
<TextView
android:id="@+id/tv_username"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/padding_4"
android:paddingBottom="@dimen/padding_2"
android:paddingTop="@dimen/padding_2"
android:text="-"
android:textColor="@color/white"
android:textStyle="bold" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<ImageView
android:id="@+id/ic_loc"
android:layout_width="@dimen/padding_20"
android:layout_height="@dimen/padding_20"
android:layout_gravity="top"
android:scaleType="fitCenter"
android:src="@drawable/ic_location"
android:tint="@color/gray183" />
<TextView
android:id="@+id/tv_user_location"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/padding_2"
android:gravity="center_vertical"
android:text="-"
android:textColor="@color/text_gray" />
</LinearLayout>
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginTop="@dimen/padding_10"
android:background="@color/gray183" />
<TextView
android:id="@+id/tv_report_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="@dimen/padding_10"
android:paddingLeft="@dimen/padding_20"
android:paddingRight="@dimen/padding_20"
android:paddingTop="@dimen/padding_10"
android:text="@string/status_report"
android:textColor="@color/white"
android:textSize="@dimen/text_16"
android:textStyle="bold" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ProgressBar
android:id="@+id/progress_bar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="@dimen/padding_6"
android:visibility="visible" />
<LinearLayout
android:id="@+id/ll_empty_post"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/padding_6"
android:orientation="vertical"
android:visibility="gone">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="@string/no_data_available"
android:textColor="@color/white" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<android.support.v7.widget.RecyclerView
android:id="@+id/rv_report"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<ProgressBar
android:id="@+id/pb_load_more"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal|bottom"
android:visibility="gone" />
</LinearLayout>
</FrameLayout>
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
这是Java文件
public class ProfileFragment extends RxFragment implements ReportAdapter.ItemClickListener {
@Inject
QuackApiService quackApiService;
@BindView(R.id.rv_report)
RecyclerView rvReport;
@BindView(R.id.civ_user_photo)
CircleImageView civUserPhoto;
@BindView(R.id.tv_username)
TextView tvUsername;
@BindView(R.id.tv_user_location)
TextView tvLocation;
@BindView(R.id.tv_total_report)
TextView tvTotalReport;
@BindView(R.id.tv_total_wait)
TextView tvTotalWait;
@BindView(R.id.tv_total_complete)
TextView tvTotalComplete;
@BindView(R.id.ll_empty_post)
LinearLayout llEmptyPost;
@BindView(R.id.tv_report_title) TextView tvReportTitle;
String statusFilter = ProgressCons.ALL;
@BindView(R.id.progress_bar) ProgressBar progressBar;
@BindView(R.id.pb_load_more) ProgressBar pbLoadMore;
@BindView(R.id.nested_scroll_view) NestedScrollView nestedScrollView;
int numberColumnsGrid = 3;
ReportAdapter adapter;
int oldCount;
String token, userId, afterId;
Context context;
RequestOptions avatarDeft;
private boolean isLoading = false;
private int pastVisibleItems, visibleItemCount, totalItemCount = 0;
private int resultSize = 12;
private RecyclerView.LayoutManager layoutManager;
private int count=0;
public ProfileFragment() {
// Required empty public constructor
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
init();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_profile, container, false);
ButterKnife.bind(this, rootView);
setLayout();
loadData();
loadReportStatus();
loadReport(statusFilter);
return rootView;
}
private void setLayout(){
layoutManager = new GridLayoutManager(getActivity(), numberColumnsGrid);
rvReport.setLayoutManager(layoutManager);
rvReport.setNestedScrollingEnabled(false);
/*
rvReport.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
if (newState == AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL){
isLoading = true;
}
}
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
visibleItemCount = layoutManager.getChildCount();
totalItemCount = layoutManager.getItemCount();
pastVisibleItems = ((GridLayoutManager) recyclerView.getLayoutManager()).findFirstVisibleItemPosition();
if (isLoading && (visibleItemCount + pastVisibleItems == totalItemCount)){
loadReportMore(afterId, statusFilter);
isLoading = false;
}
}
});
*/
}
private void onScrolled(){
nestedScrollView.setOnScrollChangeListener((NestedScrollView.OnScrollChangeListener) (v, scrollX, scrollY, oldScrollX, oldScrollY) -> {
if(v.getChildAt(v.getChildCount() - 1) != null) {
if ((scrollY >= (v.getChildAt(v.getChildCount() - 1).getMeasuredHeight() - v.getMeasuredHeight())) &&
scrollY > oldScrollY) {
isLoading = true;
visibleItemCount = layoutManager.getChildCount();
totalItemCount = layoutManager.getItemCount();
pastVisibleItems = ((GridLayoutManager) rvReport.getLayoutManager()).findFirstVisibleItemPosition();
if (isLoading && (visibleItemCount + pastVisibleItems == totalItemCount) && visibleItemCount >= ((count++)*resultSize)){
loadReportMore(afterId, statusFilter);
isLoading = false;
}
}
}
});
}
@Override
public void onResume() {
super.onResume();
loadData();
/*
try {
if (adapter.getItemCount() != oldCount) {
loadReportStatus();
loadReport(statusFilter);
}
} catch (Exception e){
}
*/
}
private void init() {
context = getActivity();
DaggerInit.networkComponent(context).inject(this);
token = "Bearer " + Preferences.getToken().getAccessToken();
userId = Preferences.getProfile().getId();
avatarDeft = new RequestOptions();
avatarDeft.placeholder(R.drawable.ic_pol_avatar);
avatarDeft.error(R.drawable.ic_pol_avatar);
}
@OnClick({R.id.btn_edit_profil, R.id.civ_user_photo})
public void editProfil() {
EditProfilActivity.start(getActivity(), userId);
}
private void loadData() {
User user = Preferences.getProfile();
if (userId.equalsIgnoreCase(user.getId())){
Glide.with(getActivity())
.setDefaultRequestOptions(avatarDeft)
.load(user.getPictureUrl())
.into(civUserPhoto);
if (!user.getUsername().isEmpty()) {
tvUsername.setText(user.getUsername());
} else {
tvUsername.setText(R.string.username_not_set);
}
if (!user.getAddress().isEmpty()) {
tvLocation.setText(user.getAddress());
} else {
tvLocation.setText(R.string.loc_not_set);
}
} else {
quackApiService.getUserProfile(userId)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object -> {
if (object.getStatus().equalsIgnoreCase(ResponseCons.SUCCESS)){
User userProfile = object.getData();
Preferences.setProfile(userProfile);
Glide.with(getActivity())
.setDefaultRequestOptions(avatarDeft)
.load(userProfile.getPictureUrl())
.into(civUserPhoto);
if (!userProfile.getUsername().isEmpty()) {
tvUsername.setText(userProfile.getUsername());
} else {
tvUsername.setText(R.string.username_not_set);
}
if (!userProfile.getAddress().isEmpty()) {
tvLocation.setText(userProfile.getAddress());
} else {
tvLocation.setText(R.string.loc_not_set);
}
} else {
civUserPhoto.setImageDrawable(getResources().getDrawable(R.drawable.ic_pol_avatar));
tvUsername.setText(R.string.username_not_set);
tvLocation.setText(R.string.loc_not_set);
}
}, error -> {
ErrorHelper.thrown(error);
});
}
}
private void loadReportStatus(){
User user = Preferences.getProfile();
quackApiService.getUserProfile(userId)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object -> {
if (object.getStatus().equalsIgnoreCase(ResponseCons.SUCCESS)){
User userProfile = object.getData();
Preferences.setProfile(userProfile);
tvTotalReport.setText(String.valueOf(userProfile.getReportCount().getAllCount()));
tvTotalComplete.setText(String.valueOf(userProfile.getReportCount().getCompleteCount()));
tvTotalWait.setText(String.valueOf(userProfile.getReportCount().getWaitCount() + userProfile.getReportCount().getProcessCount()));
} else {
tvTotalReport.setText(String.valueOf(user.getReportCount().getAllCount()));
tvTotalComplete.setText(String.valueOf(user.getReportCount().getCompleteCount()));
tvTotalWait.setText(String.valueOf(user.getReportCount().getWaitCount()));
}
}, error -> {
ErrorHelper.thrown(error);
});
}
@OnClick(R.id.ll_report) public void getAllReport(){
statusFilter = ProgressCons.ALL;
loadReport(statusFilter);
tvReportTitle.setText(getString(R.string.report));
}
@OnClick(R.id.ll_wait) public void getWaitReport(){
statusFilter = ProgressCons.WAIT;
loadReport(statusFilter);
tvReportTitle.setText(String.format("%s %s", getString(R.string.report), getString(R.string.status_wait)));
}
@OnClick(R.id.ll_complete) public void getCompleteReport(){
statusFilter = ProgressCons.COMPLETE;
loadReport(statusFilter);
tvReportTitle.setText(String.format("%s %s", getString(R.string.report), getString(R.string.status_complete)));
}
private void loadReport(String filter){
progressBar.setVisibility(View.VISIBLE);
quackApiService.getFilterPosts(userId, resultSize, filter)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object -> {
if (object.getStatus().equalsIgnoreCase(ResponseCons.SUCCESS)){
progressBar.setVisibility(View.GONE);
List<Report> posts = object.getData();
adapter = new ReportAdapter(posts, this);
rvReport.setAdapter(adapter);
oldCount = adapter.getItemCount();
if (adapter.getItemCount() > 0){
llEmptyPost.setVisibility(View.GONE);
int count = object.getData().size() - 1;
afterId = object.getData().get(count).getId();
onScrolled();
} else {
llEmptyPost.setVisibility(View.VISIBLE);
}
} else {
progressBar.setVisibility(View.GONE);
llEmptyPost.setVisibility(View.VISIBLE);
}
}, error -> {
progressBar.setVisibility(View.GONE);
ErrorHelper.thrown(error);
});
}
private void loadReportMore(String nextId, String filter){
pbLoadMore.setVisibility(View.VISIBLE);
quackApiService.getFilterPostMore(userId, nextId, resultSize, filter)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object -> {
if (object.getStatus().equalsIgnoreCase(ResponseCons.SUCCESS)){
pbLoadMore.setVisibility(View.GONE);
List<Report> posts = object.getData();
adapter.addReports(posts);
int count = object.getData().size() - 1;
afterId = object.getData().get(count).getId();
}
}, error -> {
pbLoadMore.setVisibility(View.GONE);
ErrorHelper.thrown(error);
});
}
@Override
public void onReportItemClickListener(Report report) {
DetailActivity.start(getActivity(), report);
}
}
有人想解决这个问题吗?
谢谢。