Android skeleton loading examples 2023
Hi Android developer in this android blog we are learn about the Android skeleton loading example. like your can show animation on ui till now API not getting response like Facebook, Instagram, LinkedIn etc more Apps using like these type of progress loading.
android skeleton View design till the view gets loaded
Table of Contents
How to create this type of layout while loading content? So lets learn about this like in your App you have using any API call for getting date for to server. there so many type of progress bar using in different different App as requirement.
In this android skeleton loading I am using a dependencies name AGSkeletonLoading add below dependencies in your app build.gradle and sync your project. AG Skeleton Loading is a library to provide a easy way to include skeleton loading.
implementation 'com.github.AgnaldoNP:AGSkeletonLoading:1.2'
You can use android skeleton loading by replace an view and view group layout for it correspondent on this library. let’s make an example by using a SkeletonRelativeLayout souce code for your XML file.
<aglibs.loading.skeleton.layout.SkeletonRelativeLayout android:id="@+id/skeletonLayout" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="20dp" app:clipToText="false"> <ImageView android:id="@+id/img001" android:layout_width="50dp" android:layout_height="50dp" android:src="@drawable/ic_email" /> <TextView android:id="@+id/text001" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentEnd="true" android:layout_marginStart="8dp" android:layout_marginTop="2dp" android:layout_toEndOf="@+id/img001" android:text="Lorem Ipsum is simply dummy text" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="8dp" android:layout_marginTop="8dp" android:layout_below="@+id/text001" android:layout_toEndOf="@+id/img001" android:text="Lorem Ipsum Text" /> </aglibs.loading.skeleton.layout.SkeletonRelativeLayout>
After adding Above code in your xml file add below code to your java call to run the animation,
SkeletonRelativeLayout skeletonLayout; On Create
skeletonLayout =rootView.findViewById(R.id.skeletonLayout); skeletonLayout.isLoading();
Add whare you can start loading skeletonLayout.startLoading();
Add whare you can Stop loading skeletonLayout.stopLoading();
splitSkeletonTextByLines
- If the layout or some inner layout is an EditText, it defines if the skeleton considers each line to be drawn or if its drawn as only one rectangle
<aglibs.loading.skeleton.view.SkeletonTextView android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="20dp" android:lineSpacingExtra="4dp" android:text="Lorem Ipsum is simply dummy text of the printing and typesetting industry." app:splitSkeletonTextByLines="true" /> <aglibs.loading.skeleton.view.SkeletonTextView android:layout_width="match_parent" android:layout_height="wrap_content" android:lineSpacingExtra="4dp" android:text="Lorem Ipsum is simply dummy text of the printing and typesetting industry." app:splitSkeletonTextByLines="false" />
SkeletonListView and SkeletonRecyclerView
If you want to build a list using ListView or RecyclerView with a skeleton loading you need to create a layout that represents the item list. Once the layout is created need to reference it by adding skeletonViewHolderItem property, as you can see int the snippet bellow.
list_item.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingStart="2dp" android:paddingTop="10dp" android:paddingEnd="2dp" android:paddingBottom="10dp" tools:context=".MainActivity"> <ImageView android:id="@+id/img017" android:layout_width="50dp" android:layout_height="50dp" android:src="@drawable/ic_email" /> <TextView android:id="@+id/text016" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentEnd="true" android:layout_marginStart="8dp" android:layout_marginTop="2dp" android:layout_toEndOf="@+id/img017" android:text="Lorem Ipsum is simply dummy text" /> <TextView android:id="@+id/text015" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/text016" android:layout_marginStart="8dp" android:layout_marginTop="8dp" android:layout_toEndOf="@+id/img017" android:text="Lorem Ipsum Text" /> </RelativeLayout>
Add list item into layout.
<aglibs.loading.skeleton.layout.SkeletonListView android:layout_width="match_parent" android:layout_height="match_parent" app:skeletonViewHolderItem="@layout/item_list"/> <aglibs.loading.skeleton.layout.SkeletonRecyclerView android:layout_width="match_parent" android:layout_height="match_parent" app:skeletonViewHolderItem="@layout/item_list"/>
Android skeleton loading examples
Create an activity and fragments for making a profile screen and add below source code. With Call Rest API to get the profile date and showing date on UI. Mange Android skeleton loading start and stop.
activity_profile.xml
<?xml version="1.0" encoding="utf-8"?> <ScrollView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".fragments.home.ProfileFragment"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <LinearLayout android:id="@+id/profile_layout" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:paddingTop="30dp" android:paddingBottom="@dimen/text_size20" android:orientation="vertical" android:background="@drawable/profile_back"> <TextView android:id="@+id/ProfileText" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Profile" android:layout_centerHorizontal="true" android:textColor="@color/white" android:textSize="@dimen/body_text" android:textStyle="bold" android:gravity="center"/> <aglibs.loading.skeleton.layout.SkeletonRelativeLayout android:id="@+id/skeletonLayout" android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingLeft="50dp" android:paddingRight="50dp" app:clipToText="false"> <androidx.cardview.widget.CardView android:id="@+id/ImageViewCard" android:layout_width="80dp" android:layout_height="80dp" android:layout_centerHorizontal="true" android:layout_below="@+id/ProfileText" android:layout_gravity="center" android:layout_marginTop="@dimen/text_size20" app:cardCornerRadius="40dp"> <ImageView android:id="@+id/user_image" android:layout_width="70dp" android:layout_height="70dp" android:padding="5dp" android:layout_gravity="center" android:src="@drawable/person_icons" /> </androidx.cardview.widget.CardView> <TextView android:id="@+id/tv_user_name" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="" android:layout_centerHorizontal="true" android:layout_below="@+id/ImageViewCard" android:layout_marginTop="10dp" android:textColor="@color/white" android:textSize="@dimen/body_text" android:gravity="center"/> <TextView android:id="@+id/tv_user_mobile" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="" android:layout_centerHorizontal="true" android:layout_below="@+id/tv_user_name" android:layout_marginTop="10dp" android:textColor="@color/white" android:textSize="@dimen/body_text" android:gravity="center"/> <ProgressBar android:id="@+id/progressBar1" style="?android:attr/progressBarStyleHorizontal" android:progressDrawable="@drawable/custom_progressbar" android:layout_width="220dp" android:layout_gravity="center" android:layout_centerHorizontal="true" android:layout_below="@+id/tv_user_mobile" android:layout_marginTop="20dp" android:layout_height="10dp" android:progress="40" android:max="100"/> <TextView android:id="@+id/tv_progress_bar_text" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="40% Profile Complate" android:layout_marginTop="10dp" android:layout_centerHorizontal="true" android:layout_below="@+id/progressBar1" android:textColor="@color/white" android:textSize="@dimen/body_text" android:gravity="center"/> </aglibs.loading.skeleton.layout.SkeletonRelativeLayout> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/white" android:paddingBottom="40dp" android:orientation="vertical"> <LinearLayout android:id="@+id/ll_user_profile" android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingTop="15dp" android:paddingLeft="40dp" android:paddingRight="40dp" android:paddingBottom="15dp" android:gravity="center_vertical" android:layout_marginTop="40dp" android:orientation="horizontal"> <androidx.cardview.widget.CardView android:layout_width="40dp" android:layout_height="40dp" android:layout_gravity="center" android:backgroundTint="@color/grey" app:cardCornerRadius="40dp"> <ImageView android:layout_width="40dp" android:layout_height="40dp" android:padding="5dp" android:layout_gravity="center" android:src="@drawable/person_icons" /> </androidx.cardview.widget.CardView> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="User Profile" android:textStyle="bold" android:layout_weight="1" android:paddingLeft="25sp" android:textColor="@color/black" android:textSize="@dimen/body_text" android:gravity="left"/> <ImageView android:layout_width="30dp" android:layout_height="30dp" android:src="@drawable/navigate_next" app:tint="@color/blue" /> </LinearLayout> <View android:layout_width="match_parent" android:layout_height="1dp" android:background="@color/grey"/> <LinearLayout android:id="@+id/ll_help_support" android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingTop="15dp" android:paddingLeft="40dp" android:paddingBottom="15dp" android:paddingRight="40dp" android:gravity="center_vertical" android:orientation="horizontal"> <androidx.cardview.widget.CardView android:layout_width="40dp" android:layout_height="40dp" android:layout_gravity="center" android:backgroundTint="@color/grey" app:cardCornerRadius="40dp"> <ImageView android:layout_width="40dp" android:layout_height="40dp" android:padding="5dp" android:layout_gravity="center" android:src="@drawable/support_agent_icon" /> </androidx.cardview.widget.CardView> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Help and Support" android:layout_weight="1" android:textStyle="bold" android:paddingLeft="25sp" android:textColor="@color/black" android:textSize="@dimen/body_text" android:gravity="left"/> <ImageView android:layout_width="30dp" android:layout_height="30dp" android:src="@drawable/navigate_next" app:tint="@color/blue" /> </LinearLayout> <View android:layout_width="match_parent" android:layout_height="1dp" android:background="@color/grey"/> <LinearLayout android:id="@+id/ll_setting" android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingTop="15dp" android:paddingRight="40dp" android:paddingLeft="40dp" android:paddingBottom="15dp" android:gravity="center_vertical" android:orientation="horizontal"> <androidx.cardview.widget.CardView android:layout_width="40dp" android:layout_height="40dp" android:layout_gravity="center" android:backgroundTint="@color/grey" app:cardCornerRadius="40dp"> <ImageView android:layout_width="40dp" android:layout_height="40dp" android:padding="5dp" android:layout_gravity="center" android:src="@drawable/settings_icon" /> </androidx.cardview.widget.CardView> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Setting" android:layout_weight="1" android:textStyle="bold" android:paddingLeft="25sp" android:textColor="@color/black" android:textSize="@dimen/body_text" android:gravity="left"/> <ImageView android:layout_width="30dp" android:layout_height="30dp" android:src="@drawable/navigate_next" app:tint="@color/blue" /> </LinearLayout> <View android:layout_width="match_parent" android:layout_height="1dp" android:background="@color/grey"/> <TextView android:id="@+id/LogoutBtn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Logout " android:layout_marginTop="30dp" android:textColor="@color/black" android:textStyle="bold" android:layout_gravity="center" android:drawableTint="@color/black" android:padding="10dp" android:drawablePadding="10dp" android:drawableLeft="@drawable/logout_icons" android:textSize="@dimen/body_text" android:gravity="center"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Version 0.0.1" android:layout_marginTop="5dp" android:layout_gravity="center" android:textColor="@color/black" android:textSize="@dimen/text_size12" android:gravity="center"/> </LinearLayout> </LinearLayout> </ScrollView>
ProfileScreen.java class
public class ProfileFragment extends Fragment { private LinearLayout llUserProfile,llHelpSupport,llSetting; private HomeViewModel homeViewModel; private ImageView userImage; private TextView userName,progressBarText,userMobile; TextView LogoutBtn; private String mParam1; private String mParam2; SkeletonRelativeLayout skeletonLayout; ShimmerFrameLayout container; public ProfileFragment() { // Required empty public constructor } public static ProfileFragment newInstance(String param1, String param2) { ProfileFragment fragment = new ProfileFragment(); Bundle args = new Bundle(); fragment.setArguments(args); return fragment; } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (getArguments() != null) { } homeViewModel = new ViewModelProvider(requireActivity()).get(HomeViewModel.class); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment View rootView = inflater.inflate(R.layout.fragment_profile, container, false); setUpUi(rootView); return rootView; } private void setUpUi(View rootView) { // container = (ShimmerFrameLayout) rootView.findViewById(R.id.shimmer_view_container); // container.startShimmer(); userMobile = rootView.findViewById(R.id.tv_user_mobile); userName = rootView.findViewById(R.id.tv_user_name); progressBarText = rootView.findViewById(R.id.tv_progress_bar_text); userImage = rootView.findViewById(R.id.user_image); LogoutBtn = rootView.findViewById(R.id.LogoutBtn); skeletonLayout =rootView.findViewById(R.id.skeletonLayout); skeletonLayout.isLoading(); llUserProfile = rootView.findViewById(R.id.ll_user_profile); llHelpSupport = rootView.findViewById(R.id.ll_help_support); llSetting = rootView.findViewById(R.id.ll_setting); llUserProfile.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { openFragment(EditProfileFragment.newInstance()); } }); String XUserid = new SessionManagement().getXUserId(requireActivity()); String Token = new SessionManagement().getAuthToken(requireActivity()); Log.d("XUserid....",XUserid); Log.d("Token....",Token); getUserProfile(XUserid,XUserid,Token); LogoutBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { SessionManagement sessionManagement = new SessionManagement(); sessionManagement.Logout(requireActivity()); } }); } private void getUserProfile( String userId,String XUserId,String token) { skeletonLayout.startLoading(); homeViewModel.getUserResponseLiveData(userId,XUserId,token).observe(requireActivity(), userProfileResponse -> { if (userProfileResponse != null) { // container.stopShimmer(); skeletonLayout.stopLoading(); Toast.makeText(requireActivity(),"Success ", Toast.LENGTH_LONG).show(); updateUi(userProfileResponse); }else { // container.stopShimmer(); skeletonLayout.stopLoading(); Toast.makeText(requireActivity(),"Something went wrong please try again" , Toast.LENGTH_LONG).show(); } }); } private void updateUi(UserProfileResponse userProfileResponse) { if (userProfileResponse.getData().getName() != null && userName != null) { userName.setText(userProfileResponse.getData().getName()); } if (userProfileResponse.getData().getPhone() != null && userMobile != null) { userMobile.setText(userProfileResponse.getData().getPhone()); } progressBarText.setText("40% Profile Complate"); Picasso.with(requireActivity()) .load(String.valueOf(userProfileResponse.getData().getUserImage() != null)) .resize(70, 70) .centerCrop() .into(userImage); } public void openFragment(Fragment fragment) { FragmentTransaction transaction = requireActivity().getSupportFragmentManager().beginTransaction(); transaction.replace(R.id.flFragment, fragment); transaction.addToBackStack(null); transaction.commit(); } }
Read More Tutorial