レイアウトは非常に単純ですが、フラグメントの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);
}
});
これらは古い回避策です。
以前はAndroid.support.v4
の以前のバージョンで動作していましたが、バージョン21.0.0以降は動作せず、2014年12月10-12日でリリースされたAndroid.support.v4:21.0.3
とともに存在します。これが理由です。
setRefreshing(true)
がSwipeRefreshLayout.onMeasure()
の前に呼び出された場合、SwipeRefreshLayoutインジケーターは表示されません。
回避策:
呼び出し setProgressViewOffset()
レイアウトの円表示を無効にするSwipeRefreshLayout
で、SwipeRefreshLayout.onMeasure()
がすぐに呼び出されます。
mSwipeRefreshLayout.setProgressViewOffset(false, 0,
(int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 24, getResources().getDisplayMetrics()));
mSwipeRefreshLayout.setRefreshing(true);
PDATE Better Workaround
方向が変わるとアクションバーが薄くなるか、アクションバーのサイズを手動で設定したためです。スワイプジェスチャが成功して現在のアクションバーのサイズになった後、プログレススピナーがリセットされるこのビューの上部からのオフセットをピクセル単位で設定します。
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の答えが述べたように。
Android課題トラッカーの issue は次のとおりです。修正する必要があることを示してください。
私の解決策は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
Volodymyr 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)
に置き換えます。バグが修正されたら、コード内の1つのポイントのみを変更する必要があります(Utils
クラス)。メソッドをインライン化することもできます(そしてUtils
から削除できます)。
通常、目立った視覚的な違いはありません。ただし、保留中の更新により、ビューの階層でActivity
を保持したまま、古いSwipeRefreshLayout
インスタンスを存続させることができることに注意してください。それが懸念される場合は、メソッドを調整してWeakReference
sを使用しますが、通常はUIスレッドをブロックしないため、gcを数ミリ秒だけ遅延させます。
また、setRefreshingの前にこのメソッドを呼び出すこともできます。
swipeRefreshLayout.measure(View.MEASURED_SIZE_MASK,View.MEASURED_HEIGHT_STATE_SHIFT);
swipeRefreshLayout.setRefreshing(true);
それは私のために働きます。
@ niks.stack彼の答えに応えて、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;
}
}
Volodymyr Baydalkaに加えて、次のコードも使用します。
swipeContainer.post(new Runnable() {
@Override
public void run() {
swipeContainer.setRefreshing(false);
}
});
説明 Volodymyr Baydalkaが提供するソリューションを(フラグメントを使用して)実装しましたが、swipeRefereshの開始後、swipeContainer.setRefreshing(false);
を呼び出しても消えることはなかったため、上記のコードを実装して問題を解決しました。これがなぜ起こるのか、これ以上のアイデアは大歓迎です。
よろしく、
'com.Android.support:appcompat-v7:22.2.1'
AppCompatライブラリ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>
「com.Android.support:appcompat-v7:23.1.1」を使用している
swipeRefreshLayout.post(new Runnable() {
@Override
public void run() {
swipeRefreshLayout.setRefreshing(true);
getData();
}
});
以前はswipeRefreshLayout.setRefreshing(true);
メソッド内でgetData()
を使用していたため、機能していませんでした。メソッド内で動作しない理由はわかりません。
swipeRefreshLayout.setRefreshing(true);
はFragmentで一度だけ使用しましたが。
私のソリューション(サポート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);
これを試して
mSwipeRefreshLayout.setNestedScrollingEnabled(true);