Ik weet dat BottomSheetDialog
dit al doet, maar ik moet de normale BottomSheet
en het gedrag dat is gegenereerd uit BottomSheetBehavior.from()
gebruiken. Deze BottomSheet
verduistert de achtergrond niet en ook aanraken buiten zou hem niet sluiten. Is er een manier om de achtergrond te dimmen wanneer BottomSheet
wordt weergegeven? en misschien afwijzen wanneer u buiten aanraakt. In principe is het gedrag hetzelfde als BottomSheetDialog
, maar ik moet BottomSheet
BottomSheetBehavior
rechtstreeks gebruiken.
Antwoord 1, autoriteit 100%
U kunt deze code gebruiken
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); } }
Antwoord 2, autoriteit 4%
U kunt een aangepast fragment maken met een lay-out (soort bottomSheet) aan de onderkant en de achtergrond transparent_black
& wanneer u die BG aanraakt, verwijder dat fragment. Vb:
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>
Om dat fragment toe te voegen met bottom_top/animation.. kun je deze link volgen: Android-fragmenten en animatie
Antwoord 3, autoriteit 2%
Met behulp van de interface – onSlide die als parameter slideOffSet van het type float , kan worden gebruikt om de achtergrond te dimmen. De nieuwe offset van dit onderblad binnen [-1,1] bereik. De offset neemt toe naarmate dit ondervel naar boven beweegt. Van 0 tot 1 bevindt het blad zich tussen samengevouwen en uitgevouwen toestanden en van -1 tot 0 bevindt het zich tussen verborgen en samengevouwen toestanden.
if ( slideOffSet>=0 && slideOffSet<=1 ) {
mainActivityLayoutView.setAlpha( 1f - slideOffSet );
}
waarbij mainActivityLayoutView de id is voor NestedScrollView , die de hoofdinhoud van de activiteit bevat.
Antwoord 4
Je kunt mijn concept gebruiken als je wilt dat ik heb gebruikt in AlertDialog with Blur background in possition center
Mijn aanpak
- Een screenshot maken
- Programma’s animaties maken van gedimde/vervaagde schermafbeeldingen
- Krijg een besvenster met behulp van een dialoogvenster dat geen inhoud heeft
- Screenshot met effect bijvoegen
- Geef de echte weergave weer die ik wilde weergeven
Hier heb ik een les om een afbeelding van de achtergrond als bitmap te maken
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;
}
}
Gefeliciteerd, je hebt nu een donkerder/gedimde afbeelding die hetzelfde is als je achtergrond
U moet dan dimmen en niet vervagen zoals de mijne, zodat u deze bitmap kunt doorgeven aan de onderstaande methode,
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;
}
Gebruik nu een nep-dialoog/dialoogvenster zonder achtergrond/inhoud alleen om het venster te krijgen (controleer de implementatie van mijn vragen, u kunt dat begrijpen)
Window window = fakeDialogUseToGetWindowForBlurEffect.getWindow();
window.setBackgroundDrawable(draw); // draw is bitmap that you created
hierna kunt u uw echte weergave laten zien. In mijn geval geef ik een waarschuwing weer, u kunt alles weergeven wat uw weergave is en vergeet niet om die waarschuwing te verwijderen/verdwijnen wanneer uw echte weergave van het scherm verdwijnt!
Snelle uitvoer: (achtergrond kan naar wens worden aangepast, niet alleen donker)
Antwoord 5
Gebruik deze stijl en pas deze toe op uw dialoog.
PS: deze stijl werkt ook perfect in Android 6.0, 6.1 en 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>
En gebruik als:
final Dialog mBottomSheetDialog = new Dialog(mActivity, R.style.MaterialDialogSheet);
Bedankt.
Antwoord 6
In het geval dat de weergave die het BottomSheetBehavior
implementeert zich binnen een afzonderlijke activiteit bevindt, kunt u de volgende oplossing gebruiken
Om de achtergrond van je activiteit transparant + gedimd te maken, voeg je de volgende stijl toe aan je activiteit
<style name="Your.Transparent.Style">
<!-- Found no solution for setting the status bar color to fully transparent
from within the style. Had to resort to programmatically setting -->
<item name="android:windowBackground">@color/transparent</item>
<item name="android:backgroundDimEnabled">true</item>
</style>
Stel in uw AndroidManifest.xml het activiteitsthema in
<activity
android:name="your.activity"
android:theme="@style/Your.Transparent.Style" />
De kleur van de statusbalk instellen op volledig transparant (werkt alleen voor API >= 21)
// Inside your activity's onCreate
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setStatusBarTransparent(window)
fun setStatusBarTransparent(window: Window) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
window.statusBarColor = Color.TRANSPARENT
}
}
En tot slot voor het verbergen van het onderste blad wanneer u buiten de bladinhoud klikt, verlengt u het BottomSheetBehavior
class AutoCloseBottomSheetBehavior<V : View>(
context: Context,
attrs: AttributeSet
) : BottomSheetBehavior<V>(context, attrs) {
@SuppressLint("ClickableViewAccessibility")
override fun onLayoutChild(parent: CoordinatorLayout, child: V, layoutDirection: Int): Boolean {
parent.setOnTouchListener { _, event ->
if (event.action == MotionEvent.ACTION_DOWN) {
val outRect = Rect()
child.getGlobalVisibleRect(outRect)
if (!outRect.contains(event.rawX.toInt(), event.rawY.toInt())) {
state = STATE_HIDDEN
[email protected] true
}
}
[email protected] false
}
return super.onLayoutChild(parent, child, layoutDirection)
}
}
En stel het in op het gedrag van uw weergave
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<Your.View.Acting.As.BottomSheet
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior=".your.path.AutoCloseBottomSheetBehavior" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>