Reputation: 163
I am using Volley for requests and want to add shimmer while data is loading. I can perform it with Handler but I don't know when data will come and can't set exact time.
Here is code in my Fragment. I want to set value false
to variable isShimmer
and it makes so fast so my shimmer is not running:
String url = "my_url";
JsonArrayRequest getArticleOfTheDayRequest = new JsonArrayRequest(Request.Method.GET, url, null,
response -> {
try {
for(int i = 0; i < response.length(); i++){
JSONObject articleObject = response.getJSONObject(i);
int article_id = articleObject.getInt("article_id");
String title = articleObject.getString("title");
String text = articleObject.getString("text");
ArticleOfTheWeek articleOfTheWeek = new ArticleOfTheWeek(article_id, title, text);
articleOfTheWeekList.add(articleOfTheWeek);
}
articleOfTheWeekAdapter = new ArticleOfTheWeekAdapter(getContext(), articleOfTheWeekList);
recyclerView.setAdapter(articleOfTheWeekAdapter);
articleOfTheWeekAdapter.isShimmer = false;
articleOfTheWeekAdapter.notifyDataSetChanged();
} catch (JSONException e) {
e.printStackTrace();
}
},
error -> Log.d("Error.Response", error.getMessage() + " ")
);
Here code in my adapter:
public boolean isShimmer = true;
int shimmerNumber = 2;
@Override
public void onBindViewHolder(@NonNull final ArticleOfTheWeekViewHolder holder, int position) {
final ArticleOfTheWeek articleOfTheWeek = articleOfTheWeekList.get(position);
if(isShimmer)
{
holder.shimmerFrameLayout.startShimmer();
}else
{
holder.shimmerFrameLayout.stopShimmer();
holder.shimmerFrameLayout.setShimmer(null);
holder.textViewTitle.setBackground(null);
holder.textViewTitle.setText(articleOfTheWeek.getTitle());
holder.textViewDesc.setBackground(null);
holder.textViewDesc.setText(Html.fromHtml(articleOfTheWeek.getText()));
}
}
As you see if I set isShimmer
true, shimmer runs infinite. So I can't get a period when all data is loaded to change value of isShimmer
Upvotes: 1
Views: 1642
Reputation: 338
I've used this library for show shimmer effect while fetching data. First set visibility true to your shimmer layout in your xml file then start shimmer on the start of the activity shimmerViewContainer.startShimmer()
.
Set shimmerViewContainer.stopShimmer()
in your volley method after set data to your adapter in activity file.
As well as stop shimmer on onPause()
and onDestroy()
Upvotes: 3
Reputation: 134
May be it would be easier for you to maintain the shimmer state if you put the shimmer in the parent layout rather than within the adapter layout. I would prefer below approach:
1. Inside the layout of Activity/Fragment
<RelativeLayout>
<RecyclerView/>
<FrameLayout
android:id="@+id/shimmer_container">
<!-- show hide this FrameLayout container depend on state of data loading/loaded -->
<include layout="@layout/list_shimmer"/>
</FrameLayout>
</RelativeLayout>
The list_shimmer may be looks like:
<com.facebook.shimmer.ShimmerFrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:shimmer_auto_start="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include layout="@layout/just_like_adapter_item_layout" />
<include layout="@layout/just_like_adapter_item_layout" />
<!-- repeat until it's enough to fill the screen -->
</LinearLayout>
</com.facebook.shimmer.ShimmerFrameLayout>
The important property:
app:shimmer_auto_start="true"
So you don't need to start the shimmer programmatically.
2. Activity/Fragment
void initList(List<Data> items) {
adapter.setItems(items);
shimmer_container.setVisibility(View.GONE);
}
Upvotes: 0