diff --git a/app/src/main/java/io/github/muntashirakon/AppManager/runningapps/RunningAppsActivity.java b/app/src/main/java/io/github/muntashirakon/AppManager/runningapps/RunningAppsActivity.java index ca262f13650..a78086241b6 100644 --- a/app/src/main/java/io/github/muntashirakon/AppManager/runningapps/RunningAppsActivity.java +++ b/app/src/main/java/io/github/muntashirakon/AppManager/runningapps/RunningAppsActivity.java @@ -7,29 +7,21 @@ import android.content.Intent; import android.content.IntentFilter; import android.os.Bundle; -import android.text.Spannable; import android.text.TextUtils; -import android.text.format.Formatter; -import android.text.style.ForegroundColorSpan; import android.view.Menu; import android.view.MenuItem; import android.view.View; -import android.view.ViewGroup; -import android.widget.TextView; -import androidx.annotation.AttrRes; import androidx.annotation.IntDef; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.ActionBar; -import androidx.appcompat.widget.LinearLayoutCompat; import androidx.appcompat.widget.SearchView; import androidx.core.content.ContextCompat; import androidx.lifecycle.ViewModelProvider; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; -import com.google.android.material.color.MaterialColors; import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.android.material.progressindicator.LinearProgressIndicator; @@ -43,7 +35,6 @@ import io.github.muntashirakon.AppManager.batchops.BatchOpsManager; import io.github.muntashirakon.AppManager.batchops.BatchOpsService; import io.github.muntashirakon.AppManager.imagecache.ImageLoader; -import io.github.muntashirakon.AppManager.ipc.ps.DeviceMemoryInfo; import io.github.muntashirakon.AppManager.logcat.LogViewerActivity; import io.github.muntashirakon.AppManager.logcat.struct.SearchCriteria; import io.github.muntashirakon.AppManager.scanner.vt.VtFileReport; @@ -110,15 +101,6 @@ public class RunningAppsActivity extends BaseActivity implements MultiSelectionV private MultiSelectionView mMultiSelectionView; @Nullable private Menu mSelectionMenu; - private TextView mMemoryShortInfoView; - private TextView mMemoryInfoView; - private View[] mMemoryInfoChartChildren; - private LinearLayoutCompat mMemoryInfoChart; - private TextView mSwapShortInfoView; - private TextView mSwapInfoView; - private View[] mSwapInfoChartChildren; - private LinearLayoutCompat mSwapInfoChart; - private DeviceMemoryInfo mDeviceMemoryInfo; // TODO: Move to ViewModel private boolean mIsAdbMode; private final BroadcastReceiver mBatchOpsBroadCastReceiver = new BroadcastReceiver() { @@ -142,8 +124,7 @@ protected void onAuthenticated(Bundle savedInstanceState) { mProgressIndicator.setVisibilityAfterHide(View.GONE); mSwipeRefresh = findViewById(R.id.swipe_refresh); mSwipeRefresh.setOnRefreshListener(this); - RecyclerView recyclerView = findViewById(R.id.list_item); - recyclerView.setHasFixedSize(true); + RecyclerView recyclerView = findViewById(R.id.scrollView); recyclerView.setLayoutManager(new LinearLayoutManager(this)); mAdapter = new RunningAppsAdapter(this); recyclerView.setAdapter(mAdapter); @@ -157,24 +138,6 @@ protected void onAuthenticated(Bundle savedInstanceState) { mSelectionMenu = mMultiSelectionView.getMenu(); mSelectionMenu.findItem(R.id.action_scan_vt).setVisible(false); enableKillForSystem = AppPref.getBoolean(AppPref.PrefKey.PREF_ENABLE_KILL_FOR_SYSTEM_BOOL); - // Memory - mMemoryShortInfoView = findViewById(R.id.memory_usage); - mMemoryInfoView = findViewById(R.id.memory_usage_info); - mMemoryInfoChart = findViewById(R.id.memory_usage_chart); - int childCount = mMemoryInfoChart.getChildCount(); - mMemoryInfoChartChildren = new View[childCount]; - for (int i = 0; i < childCount; ++i) { - mMemoryInfoChartChildren[i] = mMemoryInfoChart.getChildAt(i); - } - mSwapShortInfoView = findViewById(R.id.swap_usage); - mSwapInfoView = findViewById(R.id.swap_usage_info); - mSwapInfoChart = findViewById(R.id.swap_usage_chart); - childCount = mSwapInfoChart.getChildCount(); - mSwapInfoChartChildren = new View[childCount]; - for (int i = 0; i < childCount; ++i) { - mSwapInfoChartChildren[i] = mSwapInfoChart.getChildAt(i); - } - mDeviceMemoryInfo = new DeviceMemoryInfo(); // Set observers mModel.observeKillProcess().observe(this, processInfo -> { @@ -243,6 +206,19 @@ protected void onAuthenticated(Bundle savedInstanceState) { } // TODO: 7/1/22 Use a separate fragment }); + mModel.getProcessLiveData().observe(this, processList -> { + if (mProgressIndicator != null) { + mProgressIndicator.hide(); + } + if (mAdapter != null) { + mAdapter.setDefaultList(processList); + } + }); + mModel.getDeviceMemoryInfo().observe(this, deviceMemoryInfo -> { + if (mAdapter != null) { + mAdapter.setDeviceMemoryInfo(deviceMemoryInfo); + } + }); } @Override @@ -318,16 +294,6 @@ public boolean onOptionsItemSelected(@NonNull MenuItem item) { @Override protected void onStart() { super.onStart(); - if (mModel != null) { - mModel.getProcessLiveData().observe(this, processList -> { - if (mAdapter != null) { - mAdapter.setDefaultList(processList); - } - if (mProgressIndicator != null) { - mProgressIndicator.hide(); - } - }); - } mIsAdbMode = Ops.isAdb(); } @@ -453,78 +419,6 @@ void refresh() { if (mProgressIndicator == null || mModel == null) return; mProgressIndicator.show(); mModel.loadProcesses(); - updateMemoryInfo(); - } - - private void updateMemoryInfo() { - mDeviceMemoryInfo.reload(); - // Memory - long appMemory = mDeviceMemoryInfo.getApplicationMemory(); - long cachedMemory = mDeviceMemoryInfo.getCachedMemory(); - long buffers = mDeviceMemoryInfo.getBuffers(); - long freeMemory = mDeviceMemoryInfo.getFreeMemory(); - double total = appMemory + cachedMemory + buffers + freeMemory; - if (total == 0) { - // Error due to parsing failure, etc. - mMemoryInfoChart.setVisibility(View.GONE); - mMemoryShortInfoView.setVisibility(View.GONE); - mMemoryInfoView.setVisibility(View.GONE); - return; - } - mMemoryInfoChart.post(() -> { - int width = mMemoryInfoChart.getWidth(); - setLayoutWidth(mMemoryInfoChartChildren[0], (int) (width * appMemory / total)); - setLayoutWidth(mMemoryInfoChartChildren[1], (int) (width * cachedMemory / total)); - setLayoutWidth(mMemoryInfoChartChildren[2], (int) (width * buffers / total)); - }); - mMemoryShortInfoView.setText(UIUtils.getStyledKeyValue(this, R.string.memory, Formatter - .formatFileSize(this, mDeviceMemoryInfo.getUsedMemory()) + "/" + Formatter - .formatFileSize(this, mDeviceMemoryInfo.getTotalMemory()))); - // Set color info - Spannable memInfo = UIUtils.charSequenceToSpannable(getString(R.string.memory_chart_info, Formatter - .formatShortFileSize(this, appMemory), Formatter.formatShortFileSize(this, cachedMemory), - Formatter.formatShortFileSize(this, buffers), Formatter.formatShortFileSize(this, freeMemory))); - setColors(memInfo, new int[]{R.attr.colorOnSurface, R.attr.colorPrimary, R.attr.colorTertiary, - R.attr.colorSurfaceVariant}); - mMemoryInfoView.setText(memInfo); - - // Swap - long usedSwap = mDeviceMemoryInfo.getUsedSwap(); - long totalSwap = mDeviceMemoryInfo.getTotalSwap(); - if (totalSwap == 0) { - mSwapInfoChart.setVisibility(View.GONE); - mSwapShortInfoView.setVisibility(View.GONE); - mSwapInfoView.setVisibility(View.GONE); - // No swap - return; - } - mSwapInfoChart.post(() -> { - int width = mSwapInfoChart.getWidth(); - setLayoutWidth(mSwapInfoChartChildren[0], (int) (width * usedSwap / totalSwap)); - }); - mSwapShortInfoView.setText(UIUtils.getStyledKeyValue(this, R.string.swap, Formatter - .formatFileSize(this, usedSwap) + "/" + Formatter.formatFileSize(this, totalSwap))); - // Set color and size info - Spannable swapInfo = UIUtils.charSequenceToSpannable(getString(R.string.swap_chart_info, Formatter - .formatShortFileSize(this, usedSwap), Formatter.formatShortFileSize(this, totalSwap - usedSwap))); - setColors(swapInfo, new int[]{R.attr.colorOnSurface, R.attr.colorSurfaceVariant}); - mSwapInfoView.setText(swapInfo); - } - - private void setColors(@NonNull Spannable text, @AttrRes int[] colors) { - int idx = 0; - for (int color : colors) { - idx = text.toString().indexOf('●', idx); - if (idx == -1) break; - text.setSpan(new ForegroundColorSpan(MaterialColors.getColor(this, color, TAG)), idx, idx + 1, - Spannable.SPAN_INCLUSIVE_EXCLUSIVE); - ++idx; - } - } - - private static void setLayoutWidth(@NonNull View view, int width) { - ViewGroup.LayoutParams lp = view.getLayoutParams(); - lp.width = width; - view.setLayoutParams(lp); + mModel.loadMemoryInfo(); } } diff --git a/app/src/main/java/io/github/muntashirakon/AppManager/runningapps/RunningAppsAdapter.java b/app/src/main/java/io/github/muntashirakon/AppManager/runningapps/RunningAppsAdapter.java index e841d905264..c7753c1c35e 100644 --- a/app/src/main/java/io/github/muntashirakon/AppManager/runningapps/RunningAppsAdapter.java +++ b/app/src/main/java/io/github/muntashirakon/AppManager/runningapps/RunningAppsAdapter.java @@ -2,10 +2,13 @@ package io.github.muntashirakon.AppManager.runningapps; +import android.content.Context; import android.content.Intent; import android.content.pm.ApplicationInfo; +import android.text.Spannable; import android.text.TextUtils; import android.text.format.Formatter; +import android.text.style.ForegroundColorSpan; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; @@ -14,8 +17,10 @@ import android.widget.ImageView; import android.widget.TextView; +import androidx.annotation.AttrRes; import androidx.annotation.ColorInt; import androidx.annotation.NonNull; +import androidx.appcompat.widget.LinearLayoutCompat; import androidx.appcompat.widget.PopupMenu; import com.google.android.material.button.MaterialButton; @@ -24,10 +29,12 @@ import com.google.android.material.divider.MaterialDivider; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Locale; import io.github.muntashirakon.AppManager.R; +import io.github.muntashirakon.AppManager.ipc.ps.DeviceMemoryInfo; import io.github.muntashirakon.AppManager.logcat.LogViewerActivity; import io.github.muntashirakon.AppManager.logcat.struct.SearchCriteria; import io.github.muntashirakon.AppManager.main.MainRecyclerAdapter; @@ -39,11 +46,18 @@ import io.github.muntashirakon.io.Paths; import io.github.muntashirakon.widget.MultiSelectionView; -public class RunningAppsAdapter extends MultiSelectionView.Adapter { +public class RunningAppsAdapter extends MultiSelectionView.Adapter { + private static final int VIEW_TYPE_MEMORY_INFO = 1; + private static final int VIEW_TYPE_PROCESS_INFO = 2; + private final RunningAppsActivity mActivity; private final RunningAppsViewModel mModel; private final int mQueryStringHighlightColor; - private final ArrayList mProcessItems = new ArrayList<>(); + private final Object mLock = new Object(); + @NonNull + private List mProcessItems = Collections.emptyList(); + private DeviceMemoryInfo mDeviceMemoryInfo; + private final int mColorSurface; @ColorInt private final int mHighlightColor; @@ -57,32 +71,113 @@ public class RunningAppsAdapter extends MultiSelectionView.Adapter processItems) { - synchronized (mProcessItems) { - this.mProcessItems.clear(); // We do not clear any selections - this.mProcessItems.addAll(processItems); + void setDefaultList(@NonNull List processItems) { + synchronized (mLock) { + mProcessItems = processItems; } notifyDataSetChanged(); notifySelectionChange(); } + public void setDeviceMemoryInfo(DeviceMemoryInfo deviceMemoryInfo) { + mDeviceMemoryInfo = deviceMemoryInfo; + notifyItemChanged(0); + } + @Override public int getHighlightColor() { return mHighlightColor; } + @Override + public int getItemViewType(int position) { + if (position == 0) return VIEW_TYPE_MEMORY_INFO; + return VIEW_TYPE_PROCESS_INFO; + } + @NonNull @Override - public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - final View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_running_app, parent, false); - return new ViewHolder(view); + public MultiSelectionView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + if (viewType == VIEW_TYPE_MEMORY_INFO) { + View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.header_running_apps_memory_info, parent, false); + return new HeaderViewHolder(view); + } + View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_running_app, parent, false); + return new BodyViewHolder(view); } @Override - public void onBindViewHolder(@NonNull ViewHolder holder, int position) { + public void onBindViewHolder(@NonNull MultiSelectionView.ViewHolder holder, int position) { + if (position == 0) { + onBindViewHolder((HeaderViewHolder) holder); + } else { + onBindViewHolder((BodyViewHolder) holder, position); + super.onBindViewHolder(holder, position); + } + } + + public void onBindViewHolder(@NonNull HeaderViewHolder holder) { + if (mDeviceMemoryInfo == null) { + return; + } + Context context = holder.itemView.getContext(); + // Memory + long appMemory = mDeviceMemoryInfo.getApplicationMemory(); + long cachedMemory = mDeviceMemoryInfo.getCachedMemory(); + long buffers = mDeviceMemoryInfo.getBuffers(); + long freeMemory = mDeviceMemoryInfo.getFreeMemory(); + double total = appMemory + cachedMemory + buffers + freeMemory; + if (total == 0) { + // Error due to parsing failure, etc. + holder.mMemoryInfoChart.setVisibility(View.GONE); + holder.mMemoryShortInfoView.setVisibility(View.GONE); + holder.mMemoryInfoView.setVisibility(View.GONE); + return; + } + holder.mMemoryInfoChart.post(() -> { + int width = holder.mMemoryInfoChart.getWidth(); + setLayoutWidth(holder.mMemoryInfoChartChildren[0], (int) (width * appMemory / total)); + setLayoutWidth(holder.mMemoryInfoChartChildren[1], (int) (width * cachedMemory / total)); + setLayoutWidth(holder.mMemoryInfoChartChildren[2], (int) (width * buffers / total)); + }); + holder.mMemoryShortInfoView.setText(UIUtils.getStyledKeyValue(context, R.string.memory, Formatter + .formatFileSize(context, mDeviceMemoryInfo.getUsedMemory()) + "/" + Formatter + .formatFileSize(context, mDeviceMemoryInfo.getTotalMemory()))); + // Set color info + Spannable memInfo = UIUtils.charSequenceToSpannable(context.getString(R.string.memory_chart_info, Formatter + .formatShortFileSize(context, appMemory), Formatter.formatShortFileSize(context, cachedMemory), + Formatter.formatShortFileSize(context, buffers), Formatter.formatShortFileSize(context, freeMemory))); + setColors(holder.itemView, memInfo, new int[]{R.attr.colorOnSurface, R.attr.colorPrimary, R.attr.colorTertiary, + R.attr.colorSurfaceVariant}); + holder.mMemoryInfoView.setText(memInfo); + + // Swap + long usedSwap = mDeviceMemoryInfo.getUsedSwap(); + long totalSwap = mDeviceMemoryInfo.getTotalSwap(); + if (totalSwap == 0) { + holder.mSwapInfoChart.setVisibility(View.GONE); + holder.mSwapShortInfoView.setVisibility(View.GONE); + holder.mSwapInfoView.setVisibility(View.GONE); + // No swap + return; + } + holder.mSwapInfoChart.post(() -> { + int width = holder.mSwapInfoChart.getWidth(); + setLayoutWidth(holder.mSwapInfoChartChildren[0], (int) (width * usedSwap / totalSwap)); + }); + holder.mSwapShortInfoView.setText(UIUtils.getStyledKeyValue(context, R.string.swap, Formatter + .formatFileSize(context, usedSwap) + "/" + Formatter.formatFileSize(context, totalSwap))); + // Set color and size info + Spannable swapInfo = UIUtils.charSequenceToSpannable(context.getString(R.string.swap_chart_info, Formatter + .formatShortFileSize(context, usedSwap), Formatter.formatShortFileSize(context, totalSwap - usedSwap))); + setColors(holder.itemView, swapInfo, new int[]{R.attr.colorOnSurface, R.attr.colorSurfaceVariant}); + holder.mSwapInfoView.setText(swapInfo); + } + + public void onBindViewHolder(@NonNull BodyViewHolder holder, int position) { ProcessItem processItem; - synchronized (mProcessItems) { - processItem = mProcessItems.get(position); + synchronized (mLock) { + processItem = mProcessItems.get(position - 1); } ApplicationInfo applicationInfo; if (processItem instanceof AppProcessItem) { @@ -191,34 +286,45 @@ public void onBindViewHolder(@NonNull ViewHolder holder, int position) { mModel.requestDisplayProcessDetails(processItem); } }); - super.onBindViewHolder(holder, position); } @Override public long getItemId(int position) { - synchronized (mProcessItems) { - return mProcessItems.get(position).hashCode(); + if (position == 0) { + return mDeviceMemoryInfo != null ? mDeviceMemoryInfo.hashCode() : View.NO_ID; + } + synchronized (mLock) { + return mProcessItems.get(position - 1).hashCode(); } } @Override protected void select(int position) { - synchronized (mProcessItems) { - mModel.select(mProcessItems.get(position)); + if (position == 0) { + return; + } + synchronized (mLock) { + mModel.select(mProcessItems.get(position - 1)); } } @Override protected void deselect(int position) { - synchronized (mProcessItems) { - mModel.deselect(mProcessItems.get(position)); + if (position == 0) { + return; + } + synchronized (mLock) { + mModel.deselect(mProcessItems.get(position - 1)); } } @Override protected boolean isSelected(int position) { - synchronized (mProcessItems) { - return mModel.isSelected(mProcessItems.get(position)); + if (position == 0) { + return false; + } + synchronized (mLock) { + return mModel.isSelected(mProcessItems.get(position - 1)); } } @@ -245,12 +351,60 @@ protected int getTotalItemCount() { @Override public int getItemCount() { - synchronized (mProcessItems) { - return mProcessItems.size(); + synchronized (mLock) { + return mProcessItems.size() + 1; + } + } + + private static void setColors(@NonNull View v, @NonNull Spannable text, @NonNull @AttrRes int[] colors) { + int idx = 0; + for (int color : colors) { + idx = text.toString().indexOf('●', idx); + if (idx == -1) break; + text.setSpan(new ForegroundColorSpan(MaterialColors.getColor(v, color)), idx, idx + 1, + Spannable.SPAN_INCLUSIVE_EXCLUSIVE); + ++idx; + } + } + + private static void setLayoutWidth(@NonNull View view, int width) { + ViewGroup.LayoutParams lp = view.getLayoutParams(); + lp.width = width; + view.setLayoutParams(lp); + } + + static class HeaderViewHolder extends MultiSelectionView.ViewHolder { + private final TextView mMemoryShortInfoView; + private final TextView mMemoryInfoView; + private final View[] mMemoryInfoChartChildren; + private final LinearLayoutCompat mMemoryInfoChart; + private final TextView mSwapShortInfoView; + private final TextView mSwapInfoView; + private final View[] mSwapInfoChartChildren; + private final LinearLayoutCompat mSwapInfoChart; + + public HeaderViewHolder(@NonNull View itemView) { + super(itemView); + mMemoryShortInfoView = itemView.findViewById(R.id.memory_usage); + mMemoryInfoView = itemView.findViewById(R.id.memory_usage_info); + mMemoryInfoChart = itemView.findViewById(R.id.memory_usage_chart); + int childCount = mMemoryInfoChart.getChildCount(); + mMemoryInfoChartChildren = new View[childCount]; + for (int i = 0; i < childCount; ++i) { + mMemoryInfoChartChildren[i] = mMemoryInfoChart.getChildAt(i); + } + mSwapShortInfoView = itemView.findViewById(R.id.swap_usage); + mSwapInfoView = itemView.findViewById(R.id.swap_usage_info); + mSwapInfoChart = itemView.findViewById(R.id.swap_usage_chart); + childCount = mSwapInfoChart.getChildCount(); + mSwapInfoChartChildren = new View[childCount]; + for (int i = 0; i < childCount; ++i) { + mSwapInfoChartChildren[i] = mSwapInfoChart.getChildAt(i); + } } } - static class ViewHolder extends MultiSelectionView.ViewHolder { + static class BodyViewHolder extends MultiSelectionView.ViewHolder { MaterialCardView itemView; ImageView icon; MaterialButton more; @@ -262,7 +416,7 @@ static class ViewHolder extends MultiSelectionView.ViewHolder { TextView selinuxContext; MaterialDivider divider; - public ViewHolder(@NonNull View itemView) { + public BodyViewHolder(@NonNull View itemView) { super(itemView); this.itemView = (MaterialCardView) itemView; icon = itemView.findViewById(R.id.icon); diff --git a/app/src/main/java/io/github/muntashirakon/AppManager/runningapps/RunningAppsViewModel.java b/app/src/main/java/io/github/muntashirakon/AppManager/runningapps/RunningAppsViewModel.java index 4f7d17d0c90..d2998e1d826 100644 --- a/app/src/main/java/io/github/muntashirakon/AppManager/runningapps/RunningAppsViewModel.java +++ b/app/src/main/java/io/github/muntashirakon/AppManager/runningapps/RunningAppsViewModel.java @@ -33,6 +33,7 @@ import io.github.muntashirakon.AppManager.appops.AppOpsManager; import io.github.muntashirakon.AppManager.appops.AppOpsService; import io.github.muntashirakon.AppManager.compat.PackageManagerCompat; +import io.github.muntashirakon.AppManager.ipc.ps.DeviceMemoryInfo; import io.github.muntashirakon.AppManager.runner.Runner; import io.github.muntashirakon.AppManager.scanner.vt.VirusTotal; import io.github.muntashirakon.AppManager.scanner.vt.VtFileReport; @@ -136,18 +137,18 @@ public void onReportReceived(@NonNull VtFileReport report) { }); } - private MutableLiveData> mProcessLiveData; + @NonNull + private final MutableLiveData> mProcessLiveData = new MutableLiveData<>(); + @NonNull public LiveData> getProcessLiveData() { - if (mProcessLiveData == null) { - mProcessLiveData = new MutableLiveData<>(); - } return mProcessLiveData; } - + @NonNull private final MutableLiveData mProcessItemLiveData = new MutableLiveData<>(); + @NonNull public LiveData observeProcessDetails() { return mProcessItemLiveData; } @@ -173,6 +174,26 @@ public void loadProcesses() { }); } + @NonNull + private final MutableLiveData mDeviceMemoryInfo = new MutableLiveData<>(); + + @NonNull + public MutableLiveData getDeviceMemoryInfo() { + return mDeviceMemoryInfo; + } + + @AnyThread + public void loadMemoryInfo() { + mExecutor.submit(() -> { + DeviceMemoryInfo deviceMemoryInfo = mDeviceMemoryInfo.getValue(); + if (deviceMemoryInfo == null) { + deviceMemoryInfo = new DeviceMemoryInfo(); + } + deviceMemoryInfo.reload(); + mDeviceMemoryInfo.postValue(deviceMemoryInfo); + }); + } + private final MutableLiveData> mKillProcessResult = new MutableLiveData<>(); private final MutableLiveData> mKillSelectedProcessesResult = new MutableLiveData<>(); diff --git a/app/src/main/res/layout/activity_running_apps.xml b/app/src/main/res/layout/activity_running_apps.xml index 1fac921d88f..aad39cb1128 100644 --- a/app/src/main/res/layout/activity_running_apps.xml +++ b/app/src/main/res/layout/activity_running_apps.xml @@ -15,141 +15,15 @@ android:focusable="false" app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior"> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + app:fastScrollerEnabled="true" + tools:listitem="@layout/item_running_app" /> diff --git a/app/src/main/res/layout/header_running_apps_memory_info.xml b/app/src/main/res/layout/header_running_apps_memory_info.xml new file mode 100644 index 00000000000..2e4f7bded7b --- /dev/null +++ b/app/src/main/res/layout/header_running_apps_memory_info.xml @@ -0,0 +1,116 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +