[android] SwipeRefreshLayout setRefreshing ()이 처음에 표시기를 표시하지 않음

나는 아주 간단한 레이아웃을 가지고 있지만 내가 전화 할 때 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>

조각 코드 :

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
    }
}



답변

같은 문제에 직면했다. 내 솔루션-

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


답변

Volodymyr Baydalka의 답변을 대신 참조하십시오.

이것들은 오래된 해결책입니다.

이전 버전의에서는 작동 android.support.v4했지만 버전 21.0.0부터는 작동하지 않으며 2014 년 12 월 10-12 일에android.support.v4:21.0.3 릴리스 된 상태로 여전히 존재합니다 .

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);

더 나은 해결 방법 업데이트

방향이 변경되거나 작업 표시 줄 크기를 수동으로 설정하면 작업 표시 줄이 얇아 질 수 있기 때문입니다. 이보기 상단에서 오프셋을 픽셀 단위로 설정했습니다. 여기에서 스 와이프 동작이 성공한 후 진행률 스피너가 현재 작업 표시 줄 크기로 재설정됩니다.

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의 답변이 언급했듯이.

여기입니다 문제 안드로이드 이슈 트래커한다. 수정이 필요하다는 것을 보여주기 위해 투표하십시오.


답변

내 해결책은 다음을 무시하는 것입니다 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;
        }
    }
}


답변

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


답변

Android 지원 라이브러리 24.2.0으로 문제가 해결되었습니다!
https://developer.android.com/topic/libraries/support-library/revisions.html#24-2-0-bugfixes


답변

를 기반으로 볼로디미르 Baydalka의 대답은 , 이것은 당신이 코드를 깨끗하게 유지하는 데 도움이 될 것입니다 단지 작은 생각입니다. 버그가 수정되면 게시에서 직접 메서드 호출로 쉽게 동작을 되돌릴 수 있습니다.

다음과 같은 유틸리티 클래스를 작성하십시오.

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);
            }
        });
    }
}

코드 대체 mSwipeContainer.setRefreshing(isRefreshing)에서 Utils.setRefreshing(mSwipeContainer, isRefreshing): 이제 버그가 수정되면 코드의 한 지점 만 변경하면 Utils됩니다. 이 방법은 인라인 된 다음에서 제거 할 수도 있습니다 Utils.

눈에 띄는 시각적 차이는 없습니다. 보류중인 새로 고침은 뷰 계층 구조를 Activity유지하면서 기존 인스턴스를 계속 유지할 수 SwipeRefreshLayout있습니다. 이것이 우려되는 경우 WeakReferences 를 사용하도록 메소드를 조정 하지만 일반적으로 UI 스레드를 차단하지 않으므로 gc를 몇 밀리 초만 지연시킵니다.


답변

setRefreshing 전에이 메소드를 호출 할 수도 있습니다.

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

그것은 나를 위해 작동합니다.