SwipeRefreshLayout setRefreshing()最初没有显示指标

thu*_*nja 141 android swiperefreshlayout

我有一个非常简单的布局,但是当我打电话setRefreshing(true)onActivityCreated()我的片段,将其最初不显示.

它只显示我何时刷新.任何想法为什么它最初没有出现?

片段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>
Run Code Online (Sandbox Code Playgroud)

片段代码:

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
    }
}
Run Code Online (Sandbox Code Playgroud)

小智 304

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

mSwipeRefreshLayout.post(new Runnable() {
    @Override
    public void run() {
        mSwipeRefreshLayout.setRefreshing(true);
    }
});
Run Code Online (Sandbox Code Playgroud)

  • 一段时间它仍然显示何时使用异步任务 (4认同)
  • 它可能看起来最简单,但实际上并不好.@ niks.stack解决方案[下面](http://stackoverflow.com/a/28692493/1235698)更好,因为不需要使用它的代码进行任何更改,所以当最终在支持lib中修复此错误时,您只需切换回到支持lib SwipeRefreshLayout (2认同)

Ahm*_*azy 100

请参阅Volodymyr Baydalka的回答.

这些是旧的解决方法.

曾经在早期版本上运行android.support.v4,但从版本21.0.0开始,它不起作用,并且仍然存在android.support.v4:21.0.32014年12月10日至12日发布,这就是原因.

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

解决方法:

调用setProgressViewOffset()SwipeRefreshLayout是invalidtes布局造成的圈子视图SwipeRefreshLayout.onMeasure()立即调用.

mSwipeRefreshLayout.setProgressViewOffset(false, 0,
                (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 24, getResources().getDisplayMetrics()));
mSwipeRefreshLayout.setRefreshing(true);
Run Code Online (Sandbox Code Playgroud)

更新更好的解决方法

因为当方向更改或您手动设置了操作栏大小时,操作栏可能会变薄.我们设置了此视图顶部的偏移量(以像素为单位),在成功滑动手势到当前操作栏大小后,进度微调器应该重置.

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));
Run Code Online (Sandbox Code Playgroud)

更新2014年11月20日

如果视图启动后,您的应用程序显示SwipeRefreshLayout并不是非常重要.您可以使用处理程序或任何您想要的东西将它发布到将来的某个时间.

举个例子.

handler.postDelayed(new Runnable() {

    @Override
    public void run() {
        mSwipeRefreshLayout.setRefreshing(true);
    }
}, 1000);
Run Code Online (Sandbox Code Playgroud)

或者作为Volodymyr Baydalka的回答提到.

这里是问题在Android问题跟踪.请用它来表示我们需要修复它.

  • 没有必要发布延迟.你可以发帖.毫不拖延地发布只是意味着"一旦你完成了你现在正在做的事情就做这件事".而它现在正在做的是测量和布局你的用户界面. (3认同)

nik*_*kin 46

我的解决方案是覆盖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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 我喜欢这个解决方案,因为这意味着调用SwipeRefreshLayout的代码可以完全按照我们的期望,没有任何复杂性.它基本上修复了SwipeRefreshLayout中的错误.SwipeRefreshLayout真的应该以这种方式实现. (5认同)
  • 您的解决方案的优点是保持视图偏移不变!这样我们就会继续遵循此处指定的设计模式:http://www.google.com/design/spec/patterns/swipe-to-refresh.html#swipe-to-refresh-swipe-to-refresh.谢谢! (3认同)

bao*_*oyz 20

mRefreshLayout.getViewTreeObserver()
                .addOnGlobalLayoutListener(
                        new ViewTreeObserver.OnGlobalLayoutListener() {
                            @Override
                            public void onGlobalLayout() {
                                mRefreshLayout
                                        .getViewTreeObserver()
                                        .removeGlobalOnLayoutListener(this);
                                mRefreshLayout.setRefreshing(true);
                            }
                        });
Run Code Online (Sandbox Code Playgroud)

  • 这个答案是唯一一个不是黑客的答案,所以应该被接受 (3认同)