web-dev-qa-db-fra.com

Comment puis-je atténuer l'arrière-plan lorsque la feuille de fond est affichée, sans utiliser la boîte de dialogue?

Je sais que BottomSheetDialog le fait déjà, mais je dois utiliser le BottomSheet et le comportement générés à partir de BottomSheetBehavior.from(). Ce BottomSheet n'obscurcit pas l'arrière-plan et le toucher à l'extérieur ne le ferme pas. Existe-t-il un moyen d'atténuer l'arrière-plan lorsque BottomSheet est affiché? et peut-être rejeter lorsque vous touchez l'extérieur. Fondamentalement, le comportement est similaire à BottomSheetDialog mais je dois utiliser BottomSheetBottomSheetBehavior directement.

Merci!

37
user1865027

Vous pouvez utiliser ce code 1. MainActivity.xml

<Android.support.design.widget.CoordinatorLayout
xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:app="http://schemas.Android.com/apk/res-auto"
Android:id="@+id/main_content"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:fitsSystemWindows="true">

<ScrollView
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior">

    <LinearLayout
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"
        Android:orientation="vertical"
        Android:paddingTop="24dp">

        <Button
            Android:id="@+id/button_1"
            Android:layout_width="match_parent"
            Android:layout_height="wrap_content"
            Android:text="Button 1"
            Android:padding="16dp"
            Android:layout_margin="8dp"
            Android:textColor="@Android:color/white"
            Android:background="@Android:color/holo_green_dark"/>

    </LinearLayout>

</ScrollView>

<View
    Android:visibility="gone"
    Android:id="@+id/bg"
    Android:background="#99000000"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"/>

<Android.support.v4.widget.NestedScrollView
    Android:id="@+id/bottom_sheet"
    Android:layout_width="match_parent"
    Android:layout_height="350dp"
    Android:clipToPadding="true"
    Android:background="@Android:color/holo_orange_light"
    app:layout_behavior="Android.support.design.widget.BottomSheetBehavior"
    >

    <TextView
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"
        Android:text="aefwea"
        Android:padding="16dp"
        Android:textSize="16sp"/>

</Android.support.v4.widget.NestedScrollView>

 </Android.support.design.widget.CoordinatorLayout>
  1. MAinActivity.Java

    public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    
    private static final String TAG = "MainActivity";
    private BottomSheetBehavior mBottomSheetBehavior;
    View bottomSheet;
    View mViewBg;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        bottomSheet = findViewById(R.id.bottom_sheet);
        mViewBg = findViewById(R.id.mViewBg);
        Button button1 = (Button) findViewById(R.id.button_1);
        button1.setOnClickListener(this);
        mViewBg.setOnClickListener(this);
        mBottomSheetBehavior = BottomSheetBehavior.from(bottomSheet);
        mBottomSheetBehavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
            @Override
            public void onStateChanged(@NonNull View bottomSheet, int newState) {
                if (newState == BottomSheetBehavior.STATE_COLLAPSED)
                    mViewBg.setVisibility(View.GONE);
            }
    
            @Override
            public void onSlide(@NonNull View bottomSheet, float slideOffset) {
                Log.d(TAG, "onSlide: slideOffset" + slideOffset + "");
               mViewBg.setVisibility(View.VISIBLE);
                mViewBg.setAlpha(slideOffset);
            }
        });
    
    }
    
    
    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.button_1: {
                mBottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
                break;
            }
            case R.id.bg: {
                mBottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
                break;
            }
        }
    }
    
    
    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            if (mBottomSheetBehavior.getState() == BottomSheetBehavior.STATE_EXPANDED) {
                Rect outRect = new Rect();
                bottomSheet.getGlobalVisibleRect(outRect);
                if (!outRect.contains((int) event.getRawX(), (int) event.getRawY())) {
                    mBottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
                    return true;
                }
    
            }
        }
        return super.dispatchTouchEvent(event);
    }
    
    }
    
25
Rahul Pareta

Vous pouvez créer un fragment personnalisé dont la disposition (sorte de bottomSheet) est attachée en bas et créer l'arrière-plan transparent_black & lorsque vous touchez ce BG, supprimez ce fragment. Ex:

activity_main.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:id="@+id/activity_main"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:background="#ff2020"
    Android:orientation="vertical"
    tools:context="com.example.jiffysoftwaresolutions.copypastesampleapp.MainActivity">

    <Button
        Android:id="@+id/show"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:text="Show" />

    <FrameLayout
        Android:id="@+id/bottom_sheet_fragment_container"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"></FrameLayout>

</RelativeLayout>

MainActivity.Java

public class MainActivity extends AppCompatActivity {

    private BottomSheetFragment bottomSheetFragment;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        findViewById(R.id.show).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                if (bottomSheetFragment == null) {
                    bottomSheetFragment = new BottomSheetFragment();
                }
                getSupportFragmentManager().beginTransaction().add(R.id.bottom_sheet_fragment_container, bottomSheetFragment).addToBackStack(null).commit();

            }
        });

    }


    public void removeBottomSheet() {
        try {
            getSupportFragmentManager().beginTransaction().remove(bottomSheetFragment).addToBackStack(null).commit();
        } catch (Exception e) {
        }
    }

}

BottomSheetFragment.Java

public class BottomSheetFragment extends Fragment {


    private View rootView;
    private LayoutInflater layoutInflater;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        layoutInflater = (LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);

    }


    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        rootView = inflater.inflate(R.layout.bottom_sheet_layout, container, false);
        rootView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // remove sheet on BG touch
                ((MainActivity) getActivity()).removeBottomSheet();
            }
        });
        return rootView;
    }

}

bottom_sheet_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:background="#6d000000"
    Android:gravity="bottom">

    <LinearLayout
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:background="#fff"
        Android:orientation="vertical"
        Android:padding="5dp">

        <Button
            Android:layout_width="match_parent"
            Android:layout_height="wrap_content"
            Android:text="Button1"
            Android:textColor="#000" />

        <Button
            Android:layout_width="match_parent"
            Android:layout_height="wrap_content"
            Android:text="Button2"
            Android:textColor="#000" />

    </LinearLayout>

</RelativeLayout>

Pour ajouter ce fragment avec bottom_top/animation .. vous pouvez suivre ce lien: Fragments et animation Android

2
NehaK

Vous pouvez utiliser mon concept si vous voulez que j'utilise dans AlertDialog avec arrière-plan flou dans le centre de possession

Mon approche

  1. Prendre une capture d'écran
  2. Animation par programme de capture d'écran de gradation/flou
  3. Obtenir la fenêtre de groseille en utilisant une boîte de dialogue qui n'a pas de contenu
  4. Joindre une capture d'écran avec effet
  5. Afficher la vue réelle que je voulais afficher

Ici, j'ai une classe pour prendre une image de l'arrière-plan sous forme de bitmap

public class AppUtils {

    public static Bitmap takeScreenShot(Activity activity) {
        View view = activity.getWindow().getDecorView();
        view.setDrawingCacheEnabled(true);
        view.buildDrawingCache();


        Bitmap b1 = view.getDrawingCache();
        Rect frame = new Rect();
        activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
        int statusBarHeight = frame.top;

        Display display = activity.getWindowManager().getDefaultDisplay();
        Point size = new Point();
        display.getSize(size);
        int width = size.x;
        int height = size.y;


        Bitmap b = Bitmap.createBitmap(b1, 0, statusBarHeight, width, height - statusBarHeight);
        view.destroyDrawingCache();
        return b;
    }
}

Félicitations, vous avez maintenant une image plus sombre/plus sombre que votre arrière-plan

Ensuite, votre exigence est de réduire le flou comme le mien afin que vous puissiez passer ce bitmap à la méthode ci-dessous

public static Bitmap changeBitmapContrastBrightness(Bitmap bmp, float contrast, float brightness) {
        ColorMatrix cm = new ColorMatrix(new float[]
                {
                        contrast, 0, 0, 0, brightness,
                        0, contrast, 0, 0, brightness,
                        0, 0, contrast, 0, brightness,
                        0, 0, 0, 1, 0
                });

        Bitmap ret = Bitmap.createBitmap(bmp.getWidth(), bmp.getHeight(), bmp.getConfig());

        Canvas canvas = new Canvas(ret);

        Paint paint = new Paint();
        Paint.setColorFilter(new ColorMatrixColorFilter(cm));
        canvas.drawBitmap(bmp, 0, 0, Paint);

        return ret;
    }

Utilisez maintenant une fausse boîte de dialogue/boîte de dialogue avec un arrière-plan/contenu uniquement pour obtenir la fenêtre (consultez la mise en œuvre de mes questions, vous pouvez le comprendre)

Window window = fakeDialogUseToGetWindowForBlurEffect.getWindow();
window.setBackgroundDrawable(draw);  // draw is bitmap that you created 

après cela, vous pouvez afficher votre vue réelle.Dans mon cas, j'affiche une alerte, vous pouvez afficher quelle que soit votre vue et n'oubliez pas de supprimer/disparaître cette alerte lorsque votre vue réelle disparaît de l'écran!

Sortie rapide : (l'arrière-plan peut être personnalisé comme vous le souhaitez, pas seulement sombre)

enter image description here

2
Charuක

Utilisez ce style et appliquez-le à votre boîte de dialogue.

PS: ce style fonctionne également parfaitement dans Android 6.0, 6.1 et 7.0.

<style name="MaterialDialogSheet" parent="@Android:style/Theme.Dialog">
        <item name="Android:windowIsTranslucent">true</item>
        <item name="Android:windowBackground">@Android:color/transparent</item>
        <item name="Android:windowContentOverlay">@null</item>
        <item name="Android:windowNoTitle">true</item>
        <item name="Android:backgroundDimEnabled">true</item>
        <item name="Android:windowIsFloating">false</item>
        <item name="Android:windowAnimationStyle">@style/MaterialDialogSheetAnimation</item>
    </style>
<style name="MaterialDialogSheetAnimation">
        <item name="Android:windowEnterAnimation">@anim/popup_show</item>
        <item name="Android:windowExitAnimation">@anim/popup_hide</item>
    </style>

Et utiliser comme:

final Dialog mBottomSheetDialog = new Dialog(mActivity, R.style.MaterialDialogSheet);

Merci.

0
Harsh Dalwadi