Search code examples
javaandroidandroid-layoutnavigation-drawermaterialcardview

MaterialCardView is in front of NavigationView. How can I send it behind? [Android Studio]


I added in my activity_main.xml a MaterialCardView button com.google.android.material.card.MaterialCardView & navigation drawer com.google.android.material.navigation.NavigationView.

How can I send MaterialCardView (@+id/cleanButton) behind the NavigationView (@+id/navigation_view)?

Here is how it looks

[This is full activity_main.xml]

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/main_layout"
    tools:context="com.d4rk.cleaner.MainActivity">
    <androidx.appcompat.widget.AppCompatImageView
        android:id="@+id/clean"
        android:layout_width="90dp"
        android:layout_height="64dp"
        app:srcCompat="@drawable/ic_clean"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintRight_toRightOf="parent"/>
    <ScrollView
        android:id="@+id/fileScrollView"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginStart="24dp"
        android:layout_marginTop="16dp"
        android:focusable="false"
        android:background="@drawable/card"
        android:layout_marginEnd="24dp"
        android:layout_marginBottom="16dp"
        app:layout_constraintBottom_toTopOf="@+id/cleanButton"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/scanProgress">
        <LinearLayout
            android:id="@+id/fileListView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginStart="0dp"
            android:orientation="vertical"/>
    </ScrollView>
    <com.google.android.material.card.MaterialCardView
        android:id="@+id/cleanButton"
        android:layout_width="152dp"
        android:layout_height="50dp"
        android:layout_marginBottom="5dp"
        android:onClick="clean"
        app:cardCornerRadius="8dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/scanProgress"
        app:layout_constraintVertical_bias="0.045"
        tools:ignore="UsingOnClickInXml">
        <androidx.appcompat.widget.AppCompatImageView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:srcCompat="@drawable/ic_text_clean" />
    </com.google.android.material.card.MaterialCardView>
    <androidx.core.widget.ContentLoadingProgressBar
        android:id="@+id/scanProgress"
        android:layout_width="150dp"
        android:layout_height="144dp"
        android:indeterminate="false"
        android:progressDrawable="@drawable/circular"
        app:layout_constraintBottom_toBottomOf="@+id/ScanTextView"
        app:layout_constraintEnd_toEndOf="@+id/ScanTextView"
        app:layout_constraintStart_toStartOf="@+id/ScanTextView"
        app:layout_constraintTop_toTopOf="@+id/ScanTextView"/>
    <com.google.android.material.textview.MaterialTextView
        android:id="@+id/ScanTextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="100dp"
        android:layout_marginBottom="32dp"
        android:text="@string/main_progress"
        android:textColor="@color/colorGoogleGreen"
        android:textSize="30sp"
        app:layout_constraintBottom_toBottomOf="@+id/statusTextView"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="@+id/statusTextView"
        app:layout_constraintVertical_bias="0.0" />
    <com.google.android.material.textview.MaterialTextView
        android:id="@+id/statusTextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/main_status"
        android:textColor="@color/colorAccent"
        android:textSize="36sp"
        android:gravity="center"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.36"/>
    <androidx.drawerlayout.widget.DrawerLayout
        android:id="@+id/drawerLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fitsSystemWindows="true"
        android:clipToPadding="false"
        android:minWidth="15dp">
        <ScrollView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content">
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical">
                <androidx.appcompat.widget.Toolbar
                    android:id="@+id/toolbar"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content">
                    <TextView
                        android:layout_width="30dp"
                        android:layout_height="30dp"
                        android:autoLink="all"
                        android:clickable="true"
                        android:focusable="true"
                        android:text="@string/adfly"
                        android:textColor="#2E7D32"
                        android:textColorHighlight="@color/colorPrimary"
                        android:textColorHint="@color/colorPrimary"
                        android:textColorLink="@color/colorPrimary"
                        android:textIsSelectable="false"
                        app:drawableStartCompat="@drawable/ic_face"
                        tools:ignore="TextContrastCheck,TouchTargetSizeCheck" />
                    <androidx.appcompat.widget.AppCompatImageView
                        android:layout_width="40dp"
                        android:layout_height="36dp"
                        android:layout_gravity="center"
                        android:src="@drawable/ic_toolbar_d4rk"/>
                    <androidx.appcompat.widget.AppCompatImageView
                        android:layout_width="80dp"
                        android:layout_height="wrap_content"
                        android:layout_gravity="center"
                        app:srcCompat="@drawable/ic_cleaner"/>
                </androidx.appcompat.widget.Toolbar>
                <androidx.appcompat.widget.AppCompatImageView
                    android:id="@+id/imageView"
                    android:layout_width="match_parent"
                    android:layout_height="4dp"
                    android:layout_marginEnd="20dp"
                    android:layout_marginStart="20dp"
                    app:srcCompat="@drawable/ic_line"
                    tools:ignore="MissingConstraints"/>
            </LinearLayout>
        </ScrollView>
        <com.google.android.material.navigation.NavigationView
            android:id="@+id/navigation_view"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_gravity="start"
            app:headerLayout="@layout/header"
            app:menu="@menu/drawer_menu">
        </com.google.android.material.navigation.NavigationView>
    </androidx.drawerlayout.widget.DrawerLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

Here is my ActivityMain.java

public class MainActivity extends AppCompatActivity {
    final ConstraintSet constraintSet = new ConstraintSet();
    static boolean running = false;
    SharedPreferences prefs;
    LinearLayout fileListView;
    ScrollView fileScrollView;
    DrawerLayout drawerLayout;
    ActionBarDrawerToggle actionBarDrawerToggle;
    NavigationView navigationView;
    ProgressBar scanPBar;
    TextView progressText;
    TextView statusText;
    ConstraintLayout layout;
    @SuppressLint("NonConstantResourceId")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        fileListView = findViewById(R.id.fileListView);
        fileScrollView = findViewById(R.id.fileScrollView);
        scanPBar = findViewById(R.id.scanProgress);
        progressText = findViewById(R.id.ScanTextView);
        statusText = findViewById(R.id.statusTextView);
        layout = findViewById(R.id.main_layout);
        prefs = PreferenceManager.getDefaultSharedPreferences(this);
        constraintSet.clone(layout);
        setUpToolbar();
        navigationView = findViewById(R.id.navigation_view);
        navigationView.setNavigationItemSelectedListener(menuItem -> {
            switch (menuItem.getItemId())
            {
                case  R.id.nav_home:
                    Intent intent = new Intent(MainActivity.this, MainActivity.class);
                    startActivity(intent);
                    break;
                case R.id.nav_drawer_settings:
                    intent = new Intent (MainActivity.this, SettingsActivity.class);
                    startActivity(intent);
                    break;
                case R.id.nav_drawer_changelog:
                    intent = new Intent (MainActivity.this, ChangelogActivity.class);
                    startActivity(intent);
                    break;
                case R.id.nav_drawer_whitelist:
                    intent = new Intent (MainActivity.this, WhitelistActivity.class);
                    startActivity(intent);
                    break;
                case R.id.nav_drawer_clipboard_cleaner:
                    intent = new Intent (MainActivity.this, ClipboardActivity.class);
                    startActivity(intent);
                    break;
                case R.id.nav_drawer_about:
                    intent = new Intent (MainActivity.this, AboutActivity.class);
                    startActivity(intent);
                    break;
                case  R.id.nav_share:{
                    Intent sharingIntent = new Intent(Intent.ACTION_SEND);
                    sharingIntent.setType("text/plain");
                    String shareBody =  "https://play.google.com/store/apps/details?id=com.d4rk.cleaner";
                    String shareSub = "Try now";
                    sharingIntent.putExtra(Intent.EXTRA_SUBJECT, shareSub);
                    sharingIntent.putExtra(Intent.EXTRA_TEXT, shareBody);
                    startActivity(Intent.createChooser(sharingIntent, "Share using"));
                }
                break;
            }
            return false;
        });
    }
    public void setUpToolbar() {
        drawerLayout = findViewById(R.id.drawerLayout);
        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        Objects.requireNonNull(getSupportActionBar()).setTitle(null);
        actionBarDrawerToggle = new ActionBarDrawerToggle(this, drawerLayout, toolbar, R.string.app_name, R.string.app_name);
        drawerLayout.addDrawerListener(actionBarDrawerToggle);
        actionBarDrawerToggle.syncState();
    }
    public final void clean(View view) {
        requestWriteExternalPermission();
        if (!running) {
            if (!prefs.getBoolean("one_click", false))
                new AlertDialog.Builder(this,R.style.MyAlertDialogTheme)
                        .setTitle(R.string.main_select_task)
                        .setMessage(R.string.main_select_task_description)
                        .setPositiveButton(R.string.main_clean, (dialog, whichButton) -> new Thread(()-> scan(true)).start())
                        .setNegativeButton(R.string.main_analyze, (dialog, whichButton) -> new Thread(()-> scan(false)).start()).show();
            else new Thread(()-> scan(true)).start();
        }
    }
    public void animateBtn() {
        TransitionManager.beginDelayedTransition(layout);
        constraintSet.clear(R.id.cleanButton,ConstraintSet.TOP);
        constraintSet.clear(R.id.statusTextView,ConstraintSet.BOTTOM);
        constraintSet.setMargin(R.id.statusTextView,ConstraintSet.TOP,50);
        constraintSet.applyTo(layout);
    }
    @SuppressLint("SetTextI18n")
    private void scan(boolean delete) {
        Looper.prepare();
        running = true;
        reset();
        File path = Environment.getExternalStorageDirectory();
        FileScanner fs = new FileScanner(path);
        fs.setEmptyDir(prefs.getBoolean("empty", false));
        fs.setAutoWhite(prefs.getBoolean("auto_white", true));
        fs.setDelete(delete);
        fs.setCorpse(prefs.getBoolean("corpse", false));
        fs.setGUI(this);
        fs.setUpFilters(prefs.getBoolean("generic", true),
                prefs.getBoolean("aggressive", false),
                prefs.getBoolean("apk", false));
        if (path.listFiles() == null) {
            TextView textView = printTextView(printTextView(), Color.RED);
            runOnUiThread(() -> fileListView.addView(textView));
        }
        runOnUiThread(() -> {
            animateBtn();
            statusText.setText(getString(R.string.main_status_running));
        });
        long kilobytesTotal = fs.startScan();
        runOnUiThread(() -> {
            scanPBar.setProgress(scanPBar.getMax());
            progressText.setText("100%");
        });
        runOnUiThread(() -> {
            if (delete) {
                statusText.setText(getString(R.string.main_freed) + " " + convertSize(kilobytesTotal));
            } else {
                statusText.setText(getString(R.string.main_found) + " " + convertSize(kilobytesTotal));
            }
        });
        fileScrollView.post(() -> fileScrollView.fullScroll(ScrollView.FOCUS_DOWN));
        running = false;
        Looper.loop();
    }
    private String printTextView() {
        return null;
    }
    private synchronized TextView printTextView(String text, int color) {
        TextView textView = new TextView(MainActivity.this);
        textView.setTextColor(color);
        textView.setText(text);
        textView.setPadding(3,3,3,3);
        return textView;
    }
    private String convertSize(long length) {
        final DecimalFormat format = new DecimalFormat("#.##");
        final long MiB = 1024 * 1024;
        final long KiB = 1024;
        if (length > MiB) {
            return format.format(length / MiB) + " MB";
        }
        if (length > KiB) {
            return format.format(length / KiB) + " KB";
        }
        return format.format(length) + " B";
    }
    synchronized TextView displayPath(File file) {
        TextView textView = printTextView(file.getAbsolutePath(), getResources().getColor(R.color.colorAccent));
        runOnUiThread(() -> fileListView.addView(textView));
        fileScrollView.post(() -> fileScrollView.fullScroll(ScrollView.FOCUS_DOWN));
        return textView;
    }
    private synchronized void reset() {
        prefs = PreferenceManager.getDefaultSharedPreferences(this);
        runOnUiThread(() -> {
            fileListView.removeAllViews();
            scanPBar.setProgress(0);
            scanPBar.setMax(1);
        });
    }
    public synchronized void requestWriteExternalPermission() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,
                            Manifest.permission.READ_EXTERNAL_STORAGE,
                            Manifest.permission.MANAGE_EXTERNAL_STORAGE},
                    1);
            if (!Environment.isExternalStorageManager()) {
                Toast.makeText(this, "Permission needed!", Toast.LENGTH_LONG).show();
                Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
                Uri uri = Uri.fromParts("package", getPackageName(), null);
                intent.setData(uri);
                startActivity(intent);
            }
        } else {
            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,
                            Manifest.permission.READ_EXTERNAL_STORAGE},
                    1);
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == 1 &&
                grantResults.length > 0 &&
                grantResults[0] != PackageManager.PERMISSION_GRANTED)
            prompt();
    }
    public final void prompt() {
        Intent intent = new Intent(this, PromptActivity.class);
        startActivity(intent);
    }
}

Solution

  • The root layout should be DrawerLayout, and you need to move the current ConstraintLayout within the DrawerLayout

    The skeleton of the layout should be something like:

    <?xml version="1.0" encoding="utf-8"?>
    <androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/drawer_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <!--  Main screen layout   -->
        <androidx.constraintlayout.widget.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">
    
            <androidx.appcompat.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:theme="@style/ThemeOverlay.AppCompat.Dark"
                app:layout_constraintTop_toTopOf="parent" />
    
        </androidx.constraintlayout.widget.ConstraintLayout>
    
    
        <!--  Drawer layout   -->
        <com.google.android.material.navigation.NavigationView
            android:id="@+id/nav_view"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_gravity="start"
            app:headerLayout="@layout/navigation_header_layout"
            app:menu="@menu/navigation_menu" />
    
    </androidx.drawerlayout.widget.DrawerLayout>
    

    And you can build views on the main screen within the ConstraintLayout