最初没有显示指示器

我有一个非常简单的布局,但是当我在我的片段的 onActivityCreated()中调用 setRefreshing(true)时,它最初并没有显示。

它只在我刷新的时候显示,知道为什么一开始没有显示吗?

片段 xml:

<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/swipe_container"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">


<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">


<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">


</RelativeLayout>




</ScrollView>
</android.support.v4.widget.SwipeRefreshLayout>

碎片代码:

public static class LinkDetailsFragment extends BaseFragment implements SwipeRefreshLayout.OnRefreshListener {


@InjectView(R.id.swipe_container)
SwipeRefreshLayout mSwipeContainer;


public static LinkDetailsFragment newInstance(String subreddit, String linkId) {
Bundle args = new Bundle();
args.putString(EXTRA_SUBREDDIT, subreddit);
args.putString(EXTRA_LINK_ID, linkId);


LinkDetailsFragment fragment = new LinkDetailsFragment();
fragment.setArguments(args);


return fragment;
}


public LinkDetailsFragment() {
}


@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);


mSwipeContainer.setOnRefreshListener(this);
mSwipeContainer.setColorScheme(android.R.color.holo_blue_bright,
android.R.color.holo_green_light,
android.R.color.holo_orange_light,
android.R.color.holo_red_light);
mSwipeContainer.setRefreshing(true);
}


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final View rootView = inflater.inflate(R.layout.fragment_link_details, container, false);
ButterKnife.inject(this, rootView);
return rootView;
}


@Override
public void onRefresh() {
// refresh
}
}
58974 次浏览

请看 Volodymyr Baydalka 的回答。

这些都是老办法了。

这曾经在早期版本的 android.support.v4上工作,但从21.0.0版本正在进行,它不工作,仍然存在与 android.support.v4:21.0.32014年12月10日至12日发布,这就是原因。

SwipeRefreshLayout.onMeasure()之前调用 setRefreshing(true)时,不会出现 SwipeRefreshLayout 指示器

解决办法:

SwipeRefreshLayout上调用 setProgressViewOffset(),使布局的圆形视图无效,从而导致立即调用 SwipeRefreshLayout.onMeasure()

mSwipeRefreshLayout.setProgressViewOffset(false, 0,
(int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 24, getResources().getDisplayMetrics()));
mSwipeRefreshLayout.setRefreshing(true);

更新更好的解决方案

因为当方向改变或者手动设置操作条大小时,操作条会变薄。我们从这个视图的顶部以像素为单位设置偏移量,在成功地滑动手势到当前操作栏大小之后,进度旋转器应该在这个位置重置。

TypedValue typed_value = new TypedValue();
getActivity().getTheme().resolveAttribute(android.support.v7.appcompat.R.attr.actionBarSize, typed_value, true);
mSwipeRefreshLayout.setProgressViewOffset(false, 0, getResources().getDimensionPixelSize(typed_value.resourceId));

更新日期: 2014年11月20日

如果你的应用程序在视图启动后显示 SwipeRefreshLayout 对你来说不是很重要的话。 您可以通过使用处理程序或任何您想要的东西将其发布到将来的某个时间。

举个例子。

handler.postDelayed(new Runnable() {


@Override
public void run() {
mSwipeRefreshLayout.setRefreshing(true);
}
}, 1000);

或者正如 Volodymyr Baydalka 的回答所提到的。

这是机器人问题跟踪器中的 问题。请支持它,以显示他们,我们需要它得到修复。

面对同样的问题。我的解决方案-

mSwipeRefreshLayout.post(new Runnable() {
@Override
public void run() {
mSwipeRefreshLayout.setRefreshing(true);
}
});

我的解决方案(不支持 v7)-

TypedValue typed_value = new TypedValue();
getTheme().resolveAttribute(android.R.attr.actionBarSize, typed_value, true);
swipeLayout.setProgressViewOffset(false, 0, getResources().getDimensionPixelSize(typed_value.resourceId));


if(!swipeLayout.isEnabled())
swipeLayout.setEnabled(true);
swipeLayout.setRefreshing(true);

另一种解决方案是从 SwipeRefreshLayout 创建新控件和派生程序。如果刷新被激活,重写 OnScale 函数并再次切换刷新。我在 xamarin 项目中使用这个解决方案,它工作得很好。下面是一些示例 C #-代码:

class MySwipeRefreshLayout : SwipeRefreshLayout
{
/// <summary>
/// used to indentify, if measure was called for the first time
/// </summary>
private bool m_MeasureCalled;


public MvxSwipeRefreshLayout(Context context, IAttributeSet attrs)
: base(context, attrs)
{
}


public MvxSwipeRefreshLayout(Context context)
: base(context)
{
}


public override void OnMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
base.OnMeasure(widthMeasureSpec, heightMeasureSpec);


if (!m_MeasureCalled)
{
//change refreshing only one time
m_MeasureCalled = true;


if (Refreshing)
{
Refreshing = false;
Refreshing = true;
}
}
}
}
mRefreshLayout.getViewTreeObserver()
.addOnGlobalLayoutListener(
new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
mRefreshLayout
.getViewTreeObserver()
.removeGlobalOnLayoutListener(this);
mRefreshLayout.setRefreshing(true);
}
});

基于 弗拉基米尔 · 贝达尔卡的回答,这只是帮助您保持代码清洁的一个小想法。我相信这值得一写: 一旦 bug 得到修复,您将能够轻松地将这种行为从发布恢复为直接方法调用。

编写一个实用程序类,比如:

public class Utils
{
private Utils()
{
}


public static void setRefreshing(final SwipeRefreshLayout swipeRefreshLayout, final boolean isRefreshing)
{
// From Guava, or write your own checking code
checkNonNullArg(swipeRefreshLayout);
swipeRefreshLayout.post(new Runnable()
{
@Override
public void run()
{
swipeRefreshLayout.setRefreshing(isRefreshing);
}
});
}
}

在你的代码中用 Utils.setRefreshing(mSwipeContainer, isRefreshing)替换 mSwipeContainer.setRefreshing(isRefreshing): 现在只有一个点需要在修复错误后改变,那就是 Utils类。该方法也可以内联然后(并从 Utils删除)。

通常不会有明显的视觉差异。请记住,挂起的刷新可以让旧的 Activity实例保持活动状态,在它们的视图层次结构中保留 SwipeRefreshLayout。如果需要考虑这个问题,可以调整方法使用 WeakReference,但是通常不会阻塞 UI 线程,因此 gc 只会延迟几毫秒。

我使用了 AppCompat Library com.android.support:appcompat-v7:21.0.3,使用了与您相同的方法,并且它起作用了。

建议: RelativeLayout不支持定向,它是 LinearLayout的一个属性。

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
ViewGroup view = (ViewGroup) inflater.inflate(R.layout.license_fragment,
container, false);ButterKnife.inject(this, view);
// Setting up Pull to Refresh
swipeToRefreshLayout.setOnRefreshListener(this);
// Indicator colors for refresh
swipeToRefreshLayout.setColorSchemeResources(R.color.green,
R.color.light_green);
}

XML 布局:

<android.support.v4.widget.SwipeRefreshLayout>


<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_margin_vertical"
android:paddingTop="@dimen/activity_margin_vertical">


<!-- Content -->
</ScrollView>


</android.support.v4.widget.SwipeRefreshLayout>

我的解决方案是重写 SwipeRefreshLayout:

public class MySwipeRefreshLayout extends SwipeRefreshLayout {


private boolean mMeasured = false;
private boolean mPreMeasureRefreshing = false;


public MySwipeRefreshLayout(final Context context) {
super(context);
}


public MySwipeRefreshLayout(final Context context, final AttributeSet attrs) {
super(context, attrs);
}


@Override
public void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if (!mMeasured) {
mMeasured = true;
setRefreshing(mPreMeasureRefreshing);
}
}


@Override
public void setRefreshing(final boolean refreshing) {
if (mMeasured) {
super.setRefreshing(refreshing);
} else {
mPreMeasureRefreshing = refreshing;
}
}
}

除了 Volodymyr Baydalka 之外,还使用以下代码:

swipeContainer.post(new Runnable() {
@Override
public void run() {
swipeContainer.setRefreshing(false);
}
});

解释 我实现了 Volodymyr Baydalka 提供的解决方案(使用片段) ,但是在 wipeReferesh 启动后,它甚至在调用 swipeContainer.setRefreshing(false);时也没有消失 所以必须实现上面给出的代码来解决我的问题。 我们非常欢迎更多关于这种情况发生原因的想法。

问候,

‘ com.android.support: appcompat-v7:22.2.1’

我使用的是‘ com.android.support: appcompat-v7:23.1.1’

swipeRefreshLayout.post(new Runnable() {
@Override
public void run() {
swipeRefreshLayout.setRefreshing(true);
getData();
}
});

之前我在 getData()方法中使用 swipeRefreshLayout.setRefreshing(true);,所以它不工作。 我不知道为什么它不工作的内部方法。

虽然我在我的片段中只使用了一次 swipeRefreshLayout.setRefreshing(true);

也可以在 setRefresh 之前调用此方法。

    swipeRefreshLayout.measure(View.MEASURED_SIZE_MASK,View.MEASURED_HEIGHT_STATE_SHIFT);
swipeRefreshLayout.setRefreshing(true);

对我很有效。

@ niks.作为对他答案的回应,我会在 onLayout()完成之后显示进度轮。当我在 onMeasure()之后直接使用它时,它不会尊重一些偏移,但是在 onLayout()之后使用它。

@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
if (!mLaidOut) {
mLaidOut = true;
setRefreshing(mPreLayoutRefreshing);
}
}


@Override
public void setRefreshing(boolean refreshing) {
if (mLaidOut) {
super.setRefreshing(refreshing);
} else {
mPreLayoutRefreshing = refreshing;
}
}

试试这个

SetNestedScrollingEnable (true) ;