emergentes - tipos de dialogos en android studio
¿Cómo puedo atenuar el fondo cuando se muestra la hoja inferior, sin usar Diálogo? (4)
Puede crear un fragmento personalizado que tenga un diseño (tipo de parte inferior) adjunto al fondo y hacer que el fondo transparent_black
& al tocar en esa BG elimine ese fragmento. 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>
Para agregar ese fragmento con bottom_top / animation ... puedes seguir este enlace: Fragmentos de Android y animación
Sé que BottomSheetDialog
ya lo hace, pero necesito usar el BottomSheet
regular y el comportamiento generado desde BottomSheetBehavior.from()
. Esta BottomSheet
no atenúa el fondo y, además, al tocar el exterior no se cierra. ¿Hay alguna forma de atenuar el fondo cuando se muestra BottomSheet
? y tal vez despedirlo cuando toque afuera. Básicamente, el comportamiento es como BottomSheetDialog
pero debo usar BottomSheet
BottomSheetBehavior
directamente.
¡Gracias!
Puede usar mi concepto si desea que usé en AlertDialog con fondo de desenfoque en el centro de la posición
Mi acercamiento
- Tomar una captura de pantalla
- Animar programáticamente la captura de pantalla tenue / borrosa
- Obtener ventana de grosella usando un diálogo que no tiene ningún contenido
- Adjuntar captura de pantalla con efecto.
- Mostrar vista real que quería mostrar
Aquí tengo una clase para tomar una imagen del fondo como un mapa de bits
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;
}
}
Felicidades ahora tienes una imagen oscura / oscura igual que tu fondo
Entonces, su requisito es atenuar, no difuminar como el mío, de modo que pueda pasar este mapa de bits al siguiente método.
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;
}
Ahora use un diálogo / diálogo falso con Salir de un fondo / contenido solo para obtener la ventana (verifique la implementación de mis preguntas, puede entender eso)
Window window = fakeDialogUseToGetWindowForBlurEffect.getWindow();
window.setBackgroundDrawable(draw); // draw is bitmap that you created
después de esto, puede mostrar su vista real. En mi caso, muestro una alerta que puede mostrar cualquiera que sea su vista y recuerde eliminar / desaparecer esa alerta cuando su vista real salga de la pantalla.
Salida rápida : (el fondo se puede personalizar como desee, no solo tenue)
Utiliza este estilo y aplícalo a tu diálogo.
PD: este estilo también funciona perfectamente en Android 6.0, 6.1 y 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>
Y usar como:
final Dialog mBottomSheetDialog = new Dialog(mActivity, R.style.MaterialDialogSheet);
Gracias.
Puedes usar este código 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; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); bottomSheet = findViewById(R.id.bottom_sheet); Button button1 = (Button) findViewById(R.id.button_1); button1.setOnClickListener(this); findViewById(R.id.bg).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) findViewById(R.id.bg).setVisibility(View.GONE); } @Override public void onSlide(@NonNull View bottomSheet, float slideOffset) { Log.d(TAG, "onSlide: slideOffset" + slideOffset + ""); findViewById(R.id.bg).setVisibility(View.VISIBLE); findViewById(R.id.bg).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); } }