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 BottomSheet
BottomSheetBehavior
directement.
Merci!
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>
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);
}
}
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
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
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)
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.