Loading res/layout/manage_applications_apps.xml +33 −35 Original line number Diff line number Diff line Loading @@ -14,7 +14,7 @@ limitations under the License. --> <FrameLayout <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:settings="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" Loading @@ -24,40 +24,38 @@ android:id="@+id/pinned_header" android:layout_width="match_parent" android:layout_height="wrap_content" android:elevation="2dp"/> <FrameLayout android:id="@+id/list_container" android:layout_width="match_parent" android:layout_height="match_parent" android:visibility="gone"> android:elevation="2dp" settings:layout_constraintTop_toTopOf="parent"/> <androidx.recyclerview.widget.RecyclerView android:id="@+id/apps_list" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_height="wrap_content" android:clipToPadding="false" android:scrollbars="none" android:visibility="invisible" settings:fastScrollEnabled="true" settings:fastScrollHorizontalThumbDrawable="@drawable/thumb_drawable" settings:fastScrollHorizontalTrackDrawable="@drawable/line_drawable" settings:fastScrollVerticalThumbDrawable="@drawable/thumb_drawable" settings:fastScrollVerticalTrackDrawable="@drawable/line_drawable"/> settings:fastScrollVerticalTrackDrawable="@drawable/line_drawable" settings:layout_constraintTop_toBottomOf="@id/pinned_header"/> <TextView android:id="@android:id/empty" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="bottom|center_horizontal" android:layout_gravity="center" android:layout_height="0dp" android:gravity="center" android:textAlignment="gravity" android:text="@string/no_applications" android:textAppearance="?android:attr/textAppearanceLarge" android:visibility="invisible"/> </FrameLayout> <include layout="@layout/loading_container"/> android:visibility="invisible" settings:layout_constraintTop_toBottomOf="@id/pinned_header" settings:layout_constraintBottom_toBottomOf="parent"/> </FrameLayout> <include layout="@layout/loading_container" settings:layout_constraintTop_toBottomOf="@id/pinned_header" settings:layout_constraintBottom_toBottomOf="parent"/> </androidx.constraintlayout.widget.ConstraintLayout> res/values/dimens.xml +0 −2 Original line number Diff line number Diff line Loading @@ -149,8 +149,6 @@ <dimen name="wifi_assistant_height">182dp</dimen> <dimen name="wifi_assistant_image_top">32dp</dimen> <dimen name="wifi_assistant_image_start">24dp</dimen> <!-- appbar height is equal search bar height (48dp) plus search bar top and bottom margin --> <dimen name="app_bar_height">80dp</dimen> <!-- CryptKeeper top margin for password/pin screen --> <dimen name="crypt_keeper_password_top_margin">88dip</dimen> Loading src/com/android/settings/applications/RunningServices.java +5 −1 Original line number Diff line number Diff line Loading @@ -72,7 +72,11 @@ public class RunningServices extends SettingsPreferenceFragment { public void onResume() { super.onResume(); boolean haveData = mRunningProcessesView.doResume(this, mRunningProcessesAvail); mLoadingViewController.handleLoadingContainer(haveData /* done */, false /* animate */); if (haveData) { mLoadingViewController.showContent(false /* animate */); } else { mLoadingViewController.showLoadingView(); } } @Override Loading src/com/android/settings/applications/manageapplications/ManageApplications.java +17 −35 Original line number Diff line number Diff line Loading @@ -208,7 +208,6 @@ public class ManageApplications extends InstrumentedFragment private ApplicationsAdapter mApplications; private View mLoadingContainer; private View mListContainer; private SearchView mSearchView; // Size resource used for packages whose size computation failed for some reason Loading Loading @@ -402,10 +401,8 @@ public class ManageApplications extends InstrumentedFragment mRootView = inflater.inflate(R.layout.manage_applications_apps, null); mLoadingContainer = mRootView.findViewById(R.id.loading_container); mListContainer = mRootView.findViewById(R.id.list_container); if (mListContainer != null) { // Create adapter and list view here mEmptyView = mListContainer.findViewById(android.R.id.empty); mEmptyView = mRootView.findViewById(android.R.id.empty); mRecyclerView = mRootView.findViewById(R.id.apps_list); mApplications = new ApplicationsAdapter(mApplicationsState, this, mFilter, savedInstanceState); Loading @@ -415,12 +412,10 @@ public class ManageApplications extends InstrumentedFragment mApplications.mHasReceivedBridgeCallback = savedInstanceState.getBoolean(EXTRA_HAS_BRIDGE, false); } mRecyclerView = mListContainer.findViewById(R.id.apps_list); mRecyclerView.setItemAnimator(null); mRecyclerView.setLayoutManager(new LinearLayoutManager( getContext(), RecyclerView.VERTICAL, false /* reverseLayout */)); mRecyclerView.setAdapter(mApplications); } // We have to do this now because PreferenceFrameLayout looks at it // only when the view is added. Loading Loading @@ -985,16 +980,8 @@ public class ManageApplications extends InstrumentedFragment // overlapped by floating filter. if (hasFilter) { mManageApplications.mSpinnerHeader.setVisibility(View.VISIBLE); mManageApplications.mRecyclerView.setPadding(0 /* left */, mContext.getResources().getDimensionPixelSize( R.dimen.app_bar_height) /* top */, 0 /* right */, 0 /* bottom */); } else { mManageApplications.mSpinnerHeader.setVisibility(View.GONE); mManageApplications.mRecyclerView.setPadding(0 /* left */, 0 /* top */, 0 /* right */, 0 /* bottom */); } } } Loading Loading @@ -1044,7 +1031,8 @@ public class ManageApplications extends InstrumentedFragment mManageApplications = manageApplications; mLoadingViewController = new LoadingViewController( mManageApplications.mLoadingContainer, mManageApplications.mListContainer mManageApplications.mRecyclerView, mManageApplications.mEmptyView ); mContext = manageApplications.getActivity(); mIconDrawableFactory = IconDrawableFactory.newInstance(mContext); Loading Loading @@ -1303,11 +1291,9 @@ public class ManageApplications extends InstrumentedFragment mOriginalEntries = entries; notifyDataSetChanged(); if (getItemCount() == 0) { mManageApplications.mRecyclerView.setVisibility(View.GONE); mManageApplications.mEmptyView.setVisibility(View.VISIBLE); mLoadingViewController.showEmpty(false /* animate */); } else { mManageApplications.mEmptyView.setVisibility(View.GONE); mManageApplications.mRecyclerView.setVisibility(View.VISIBLE); mLoadingViewController.showContent(false /* animate */); if (mManageApplications.mSearchView != null && mManageApplications.mSearchView.isVisibleToUser()) { Loading @@ -1324,10 +1310,6 @@ public class ManageApplications extends InstrumentedFragment mLastIndex = -1; } if (mSession.getAllApps().size() != 0 && mManageApplications.mListContainer.getVisibility() != View.VISIBLE) { mLoadingViewController.showContent(true /* animate */); } if (mManageApplications.mListType == LIST_TYPE_USAGE_ACCESS) { // No enabled or disabled filters for usage access. return; Loading src/com/android/settings/widget/LoadingViewController.java +60 −8 Original line number Diff line number Diff line Loading @@ -22,34 +22,66 @@ import android.view.View; import android.view.animation.Animation; import android.view.animation.AnimationUtils; import androidx.annotation.Nullable; /** * A helper class that manages show/hide loading spinner. * A helper class that manages show/hide loading spinner, content view and empty view (optional). */ public class LoadingViewController { private static final long DELAY_SHOW_LOADING_CONTAINER_THRESHOLD_MS = 100L; public final Handler mFgHandler; public final View mLoadingView; public final View mContentView; private final Handler mFgHandler; private final View mLoadingView; private final View mContentView; private final View mEmptyView; public LoadingViewController(View loadingView, View contentView) { this(loadingView, contentView, null /* emptyView*/); } public LoadingViewController(View loadingView, View contentView, @Nullable View emptyView) { mLoadingView = loadingView; mContentView = contentView; mEmptyView = emptyView; mFgHandler = new Handler(Looper.getMainLooper()); } private Runnable mShowLoadingContainerRunnable = new Runnable() { public void run() { handleLoadingContainer(false /* done */, false /* animate */); showLoadingView(); } }; /** * Shows content view and hides loading view & empty view. */ public void showContent(boolean animate) { // Cancel any pending task to show the loading animation and show the list of // apps directly. mFgHandler.removeCallbacks(mShowLoadingContainerRunnable); handleLoadingContainer(true /* show */, animate); handleLoadingContainer(true /* showContent */, false /* showEmpty*/, animate); } /** * Shows empty view and hides loading view & content view. */ public void showEmpty(boolean animate) { if (mEmptyView == null) { return; } // Cancel any pending task to show the loading animation and show the list of // apps directly. mFgHandler.removeCallbacks(mShowLoadingContainerRunnable); handleLoadingContainer(false /* showContent */, true /* showEmpty */, animate); } /** * Shows loading view and hides content view & empty view. */ public void showLoadingView() { handleLoadingContainer(false /* showContent */, false /* showEmpty */, false /* animate */); } public void showLoadingViewDelayed() { Loading @@ -57,8 +89,9 @@ public class LoadingViewController { mShowLoadingContainerRunnable, DELAY_SHOW_LOADING_CONTAINER_THRESHOLD_MS); } public void handleLoadingContainer(boolean done, boolean animate) { handleLoadingContainer(mLoadingView, mContentView, done, animate); private void handleLoadingContainer(boolean showContent, boolean showEmpty, boolean animate) { handleLoadingContainer(mLoadingView, mContentView, mEmptyView, showContent, showEmpty, animate); } /** Loading @@ -75,6 +108,25 @@ public class LoadingViewController { setViewShown(content, done, animate); } /** * Show/hide loading view and content view and empty view. * * @param loading The loading spinner view * @param content The content view * @param empty The empty view shows no item summary to users. * @param showContent If true, content is set visible and loading is set invisible. * @param showEmpty If true, empty is set visible and loading is set invisible. * @param animate Whether or not content/loading views should animate in/out. */ public static void handleLoadingContainer(View loading, View content, View empty, boolean showContent, boolean showEmpty, boolean animate) { if (empty != null) { setViewShown(empty, showEmpty, animate); } setViewShown(content, showContent, animate); setViewShown(loading, !showContent && !showEmpty, animate); } private static void setViewShown(final View view, boolean shown, boolean animate) { if (animate) { Animation animation = AnimationUtils.loadAnimation(view.getContext(), Loading Loading
res/layout/manage_applications_apps.xml +33 −35 Original line number Diff line number Diff line Loading @@ -14,7 +14,7 @@ limitations under the License. --> <FrameLayout <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:settings="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" Loading @@ -24,40 +24,38 @@ android:id="@+id/pinned_header" android:layout_width="match_parent" android:layout_height="wrap_content" android:elevation="2dp"/> <FrameLayout android:id="@+id/list_container" android:layout_width="match_parent" android:layout_height="match_parent" android:visibility="gone"> android:elevation="2dp" settings:layout_constraintTop_toTopOf="parent"/> <androidx.recyclerview.widget.RecyclerView android:id="@+id/apps_list" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_height="wrap_content" android:clipToPadding="false" android:scrollbars="none" android:visibility="invisible" settings:fastScrollEnabled="true" settings:fastScrollHorizontalThumbDrawable="@drawable/thumb_drawable" settings:fastScrollHorizontalTrackDrawable="@drawable/line_drawable" settings:fastScrollVerticalThumbDrawable="@drawable/thumb_drawable" settings:fastScrollVerticalTrackDrawable="@drawable/line_drawable"/> settings:fastScrollVerticalTrackDrawable="@drawable/line_drawable" settings:layout_constraintTop_toBottomOf="@id/pinned_header"/> <TextView android:id="@android:id/empty" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="bottom|center_horizontal" android:layout_gravity="center" android:layout_height="0dp" android:gravity="center" android:textAlignment="gravity" android:text="@string/no_applications" android:textAppearance="?android:attr/textAppearanceLarge" android:visibility="invisible"/> </FrameLayout> <include layout="@layout/loading_container"/> android:visibility="invisible" settings:layout_constraintTop_toBottomOf="@id/pinned_header" settings:layout_constraintBottom_toBottomOf="parent"/> </FrameLayout> <include layout="@layout/loading_container" settings:layout_constraintTop_toBottomOf="@id/pinned_header" settings:layout_constraintBottom_toBottomOf="parent"/> </androidx.constraintlayout.widget.ConstraintLayout>
res/values/dimens.xml +0 −2 Original line number Diff line number Diff line Loading @@ -149,8 +149,6 @@ <dimen name="wifi_assistant_height">182dp</dimen> <dimen name="wifi_assistant_image_top">32dp</dimen> <dimen name="wifi_assistant_image_start">24dp</dimen> <!-- appbar height is equal search bar height (48dp) plus search bar top and bottom margin --> <dimen name="app_bar_height">80dp</dimen> <!-- CryptKeeper top margin for password/pin screen --> <dimen name="crypt_keeper_password_top_margin">88dip</dimen> Loading
src/com/android/settings/applications/RunningServices.java +5 −1 Original line number Diff line number Diff line Loading @@ -72,7 +72,11 @@ public class RunningServices extends SettingsPreferenceFragment { public void onResume() { super.onResume(); boolean haveData = mRunningProcessesView.doResume(this, mRunningProcessesAvail); mLoadingViewController.handleLoadingContainer(haveData /* done */, false /* animate */); if (haveData) { mLoadingViewController.showContent(false /* animate */); } else { mLoadingViewController.showLoadingView(); } } @Override Loading
src/com/android/settings/applications/manageapplications/ManageApplications.java +17 −35 Original line number Diff line number Diff line Loading @@ -208,7 +208,6 @@ public class ManageApplications extends InstrumentedFragment private ApplicationsAdapter mApplications; private View mLoadingContainer; private View mListContainer; private SearchView mSearchView; // Size resource used for packages whose size computation failed for some reason Loading Loading @@ -402,10 +401,8 @@ public class ManageApplications extends InstrumentedFragment mRootView = inflater.inflate(R.layout.manage_applications_apps, null); mLoadingContainer = mRootView.findViewById(R.id.loading_container); mListContainer = mRootView.findViewById(R.id.list_container); if (mListContainer != null) { // Create adapter and list view here mEmptyView = mListContainer.findViewById(android.R.id.empty); mEmptyView = mRootView.findViewById(android.R.id.empty); mRecyclerView = mRootView.findViewById(R.id.apps_list); mApplications = new ApplicationsAdapter(mApplicationsState, this, mFilter, savedInstanceState); Loading @@ -415,12 +412,10 @@ public class ManageApplications extends InstrumentedFragment mApplications.mHasReceivedBridgeCallback = savedInstanceState.getBoolean(EXTRA_HAS_BRIDGE, false); } mRecyclerView = mListContainer.findViewById(R.id.apps_list); mRecyclerView.setItemAnimator(null); mRecyclerView.setLayoutManager(new LinearLayoutManager( getContext(), RecyclerView.VERTICAL, false /* reverseLayout */)); mRecyclerView.setAdapter(mApplications); } // We have to do this now because PreferenceFrameLayout looks at it // only when the view is added. Loading Loading @@ -985,16 +980,8 @@ public class ManageApplications extends InstrumentedFragment // overlapped by floating filter. if (hasFilter) { mManageApplications.mSpinnerHeader.setVisibility(View.VISIBLE); mManageApplications.mRecyclerView.setPadding(0 /* left */, mContext.getResources().getDimensionPixelSize( R.dimen.app_bar_height) /* top */, 0 /* right */, 0 /* bottom */); } else { mManageApplications.mSpinnerHeader.setVisibility(View.GONE); mManageApplications.mRecyclerView.setPadding(0 /* left */, 0 /* top */, 0 /* right */, 0 /* bottom */); } } } Loading Loading @@ -1044,7 +1031,8 @@ public class ManageApplications extends InstrumentedFragment mManageApplications = manageApplications; mLoadingViewController = new LoadingViewController( mManageApplications.mLoadingContainer, mManageApplications.mListContainer mManageApplications.mRecyclerView, mManageApplications.mEmptyView ); mContext = manageApplications.getActivity(); mIconDrawableFactory = IconDrawableFactory.newInstance(mContext); Loading Loading @@ -1303,11 +1291,9 @@ public class ManageApplications extends InstrumentedFragment mOriginalEntries = entries; notifyDataSetChanged(); if (getItemCount() == 0) { mManageApplications.mRecyclerView.setVisibility(View.GONE); mManageApplications.mEmptyView.setVisibility(View.VISIBLE); mLoadingViewController.showEmpty(false /* animate */); } else { mManageApplications.mEmptyView.setVisibility(View.GONE); mManageApplications.mRecyclerView.setVisibility(View.VISIBLE); mLoadingViewController.showContent(false /* animate */); if (mManageApplications.mSearchView != null && mManageApplications.mSearchView.isVisibleToUser()) { Loading @@ -1324,10 +1310,6 @@ public class ManageApplications extends InstrumentedFragment mLastIndex = -1; } if (mSession.getAllApps().size() != 0 && mManageApplications.mListContainer.getVisibility() != View.VISIBLE) { mLoadingViewController.showContent(true /* animate */); } if (mManageApplications.mListType == LIST_TYPE_USAGE_ACCESS) { // No enabled or disabled filters for usage access. return; Loading
src/com/android/settings/widget/LoadingViewController.java +60 −8 Original line number Diff line number Diff line Loading @@ -22,34 +22,66 @@ import android.view.View; import android.view.animation.Animation; import android.view.animation.AnimationUtils; import androidx.annotation.Nullable; /** * A helper class that manages show/hide loading spinner. * A helper class that manages show/hide loading spinner, content view and empty view (optional). */ public class LoadingViewController { private static final long DELAY_SHOW_LOADING_CONTAINER_THRESHOLD_MS = 100L; public final Handler mFgHandler; public final View mLoadingView; public final View mContentView; private final Handler mFgHandler; private final View mLoadingView; private final View mContentView; private final View mEmptyView; public LoadingViewController(View loadingView, View contentView) { this(loadingView, contentView, null /* emptyView*/); } public LoadingViewController(View loadingView, View contentView, @Nullable View emptyView) { mLoadingView = loadingView; mContentView = contentView; mEmptyView = emptyView; mFgHandler = new Handler(Looper.getMainLooper()); } private Runnable mShowLoadingContainerRunnable = new Runnable() { public void run() { handleLoadingContainer(false /* done */, false /* animate */); showLoadingView(); } }; /** * Shows content view and hides loading view & empty view. */ public void showContent(boolean animate) { // Cancel any pending task to show the loading animation and show the list of // apps directly. mFgHandler.removeCallbacks(mShowLoadingContainerRunnable); handleLoadingContainer(true /* show */, animate); handleLoadingContainer(true /* showContent */, false /* showEmpty*/, animate); } /** * Shows empty view and hides loading view & content view. */ public void showEmpty(boolean animate) { if (mEmptyView == null) { return; } // Cancel any pending task to show the loading animation and show the list of // apps directly. mFgHandler.removeCallbacks(mShowLoadingContainerRunnable); handleLoadingContainer(false /* showContent */, true /* showEmpty */, animate); } /** * Shows loading view and hides content view & empty view. */ public void showLoadingView() { handleLoadingContainer(false /* showContent */, false /* showEmpty */, false /* animate */); } public void showLoadingViewDelayed() { Loading @@ -57,8 +89,9 @@ public class LoadingViewController { mShowLoadingContainerRunnable, DELAY_SHOW_LOADING_CONTAINER_THRESHOLD_MS); } public void handleLoadingContainer(boolean done, boolean animate) { handleLoadingContainer(mLoadingView, mContentView, done, animate); private void handleLoadingContainer(boolean showContent, boolean showEmpty, boolean animate) { handleLoadingContainer(mLoadingView, mContentView, mEmptyView, showContent, showEmpty, animate); } /** Loading @@ -75,6 +108,25 @@ public class LoadingViewController { setViewShown(content, done, animate); } /** * Show/hide loading view and content view and empty view. * * @param loading The loading spinner view * @param content The content view * @param empty The empty view shows no item summary to users. * @param showContent If true, content is set visible and loading is set invisible. * @param showEmpty If true, empty is set visible and loading is set invisible. * @param animate Whether or not content/loading views should animate in/out. */ public static void handleLoadingContainer(View loading, View content, View empty, boolean showContent, boolean showEmpty, boolean animate) { if (empty != null) { setViewShown(empty, showEmpty, animate); } setViewShown(content, showContent, animate); setViewShown(loading, !showContent && !showEmpty, animate); } private static void setViewShown(final View view, boolean shown, boolean animate) { if (animate) { Animation animation = AnimationUtils.loadAnimation(view.getContext(), Loading