【发布时间】:2016-03-18 14:44:14
【问题描述】:
考虑一个 Android Activity,它是android.support.v4.app.FragmentActivity 的子类。它包含几个由FragmentStatePagerAdapter 管理的apges。每个页面都包含一个由android.support.v4.widget.SwipeRefreshLayout 包裹的ListView。以下屏幕截图显示了此活动的初始状态。
现在,我向下滑动刷新第 0 页的列表。出现刷新动画。现在,让我们在第 2 页向右滑动,然后再回到第 0 页。
刷新动画仍然可见。这对我来说似乎很奇怪,因为第 0 页被破坏并再次创建。此外,如果我向上滑动(尝试滚动到第 0 页上的列表末尾),页面上会呈现一些奇怪的图层,该图层似乎包含页面被销毁时的旧状态。
我不知道为什么会发生这种情况以及如何解决它。感谢您的帮助。
这是一个由 3 个布局文件、一个活动类、一个片段类、一个清单文件和一个构建脚本组成的最小应用程序的源代码。
swipeandroid/src/main/res/layout/service_schedule_activity.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.view.ViewPager
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/servicePager"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.view.PagerTabStrip
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"/>
</android.support.v4.view.ViewPager>
swipeandroid/src/main/res/layout/service_schedule_tab_fragment.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.SwipeRefreshLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/serviceRefreshLayout"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="@+id/timeSlots"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</android.support.v4.widget.SwipeRefreshLayout>
swipeandroid/src/main/res/layout/service_schedule_row.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/time"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"/>
</RelativeLayout>
swipeandroid/src/main/java/com/swipetest/ServiceScheduleActivity.java
package com.swipetest;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.ViewPager;
public class ServiceScheduleActivity extends FragmentActivity {
@Override
protected void onCreate(final Bundle inState) {
// call super class
super.onCreate(inState);
// set content
setContentView(R.layout.service_schedule_activity);
// set up service pager
((ViewPager) findViewById(R.id.servicePager)).setAdapter(new ServiceFragmentPagerAdapter());
}
private class ServiceFragmentPagerAdapter extends FragmentStatePagerAdapter {
public ServiceFragmentPagerAdapter() {
super(getSupportFragmentManager());
}
@Override
public int getCount() {
return 5;
}
@Override
public Fragment getItem(final int position) {
return ServiceScheduleTabFragment.newInstance(position);
}
@Override
public CharSequence getPageTitle(final int position) {
return String.format("page %d", position);
}
}
}
swipeandroid/src/main/java/com/swipetest/ServiceScheduleTabFragment.java
package com.swipetest;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;
public class ServiceScheduleTabFragment extends Fragment {
private static final String TAB_POSITION_ARGUMENT = "tabPosition";
public static ServiceScheduleTabFragment newInstance(final int tabPosition) {
// prepare arguments
final Bundle arguments = new Bundle();
arguments.putInt(TAB_POSITION_ARGUMENT, tabPosition);
// create fragment
final ServiceScheduleTabFragment fragment = new ServiceScheduleTabFragment();
fragment.setArguments(arguments);
return fragment;
}
@Override
public View onCreateView(final LayoutInflater layoutInflater, final ViewGroup parent, final Bundle inState) {
// create fragment root view
final View rootView = layoutInflater.inflate(R.layout.service_schedule_tab_fragment, parent, false);
// initialize time slot list view
final ListView timeSlotListView = (ListView) rootView.findViewById(R.id.timeSlots);
timeSlotListView.setAdapter(new TimeSlotListAdapter());
// return fragment root view
return rootView;
}
private int getTabPosition() {
return getArguments().getInt(TAB_POSITION_ARGUMENT);
}
private static class TimeSlotRowViewHolder {
private final TextView timeView;
public TimeSlotRowViewHolder(final View rowView) {
timeView = (TextView) rowView.findViewById(R.id.time);
}
public TextView getTimeView() {
return timeView;
}
}
private class TimeSlotListAdapter extends BaseAdapter {
@Override
public int getCount() {
return 80;
}
@Override
public Object getItem(final int position) {
return position;
}
@Override
public long getItemId(final int position) {
return position;
}
@Override
public View getView(final int position, final View convertView, final ViewGroup parent) {
// reuse or create row view
final View rowView;
if (convertView != null) {
rowView = convertView;
} else {
rowView = LayoutInflater.from(getContext()).inflate(R.layout.service_schedule_row, parent, false);
rowView.setTag(new TimeSlotRowViewHolder(rowView));
}
// fill data
final TimeSlotRowViewHolder rowViewHolder = (TimeSlotRowViewHolder) rowView.getTag();
rowViewHolder.getTimeView().setText(String.format("tab %d, row %d", getTabPosition(), position));
return rowView;
}
}
}
swipeandroid/src/main/AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.swipetest"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="16" android:targetSdkVersion="23"/>
<application
android:name="android.app.Application"
android:label="Swipe Test"
android:allowBackup="false">
<activity
android:name="com.swipetest.ServiceScheduleActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>
swipeandroid/build.gradle
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.5.0'
}
}
apply plugin: 'com.android.application'
repositories {
mavenCentral()
}
dependencies {
compile "com.android.support:support-v4:23.1.1"
}
android {
compileSdkVersion 23
buildToolsVersion "23.0.2"
buildTypes {
debug {
debuggable true
minifyEnabled false
}
}
}
【问题讨论】:
-
你在哪里初始化 SwipeToRefresh 布局
-
@Veeresh Charantimath 在这个最小的应用程序中,没有监听器被添加到 SwipeRefreshLayout。在我真正的更大的应用程序中,当然有这样的监听器,但无论如何都会发生错误。
-
当需要停止滑动刷新时可以设置'swiperefreshLayout.setRefreshing(false)'。
-
@Ragu Swaminathan 调用
swipeRefreshLayout.setRefreshing(false)很好,如果真正的刷新操作(比如对服务器的 HTTP 请求)在用户滑动到下一页(比如从第 0 页到第 1 页)之前完成.但是,如果操作仍在进行中,我不应该致电swipeRefreshLayout.setRefreshing(false)。如果用户在操作完成之前滑动到第 1 页,那么随后对swipeRefreshLayout.setRefreshing(false)的调用将不会阻止该错误。 -
尝试清除列表,然后在滑动刷新时加载新数据
标签: android listview android-fragments android-viewpager swiperefreshlayout