BottomSheetDialog
は既にそうしていることは知っていますが、通常のBottomSheet
とBottomSheetBehavior.from()
から生成された動作を使用する必要があります。このBottomSheet
は背景を暗くせず、外側をタッチしても閉じません。 BottomSheet
が表示されているときに背景を暗くする方法はありますか?そして、外に触れたときに、おそらく却下します。基本的にはBottomSheetDialog
と同様の動作ですが、BottomSheet
BottomSheetBehavior
を直接使用する必要があります。
ありがとう!
このコードを使用できます 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);
}
}
下部にレイアウト(bottomSheetのようなもの)が付加されたカスタムフラグメントを作成し、背景にtransparent_black
&を付けると、そのBGに触れるとそのフラグメントが削除されます。例:
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>
Bottom_top/animationでそのフラグメントを追加するには、次のリンクをたどることができます。 Android Fragments and animation
位置中心の背景をぼかしたアラートダイアログ で使用したい場合は、私のコンセプトを使用できます
私のアプローチ
ここに、ビットマップとして背景の画像を取得するためのクラスがあります
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;
}
}
おめでとうございます、あなたはあなたの背景と同じ暗く/薄暗い画像を持っています
その後、あなたの要件は、私のようにぼやけないように暗くすることですので、このビットマップを以下のメソッドに渡すことができます、
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;
}
次に、ウィンドウを取得するためだけに、背景/コンテンツなしの偽のダイアログ/ダイアログを使用します(理解できる質問の実装を確認してください)
Window window = fakeDialogUseToGetWindowForBlurEffect.getWindow();
window.setBackgroundDrawable(draw); // draw is bitmap that you created
この後、実際のビューを表示できます。私の場合、アラートを表示します。ビューを表示し、実際のビューが画面から消えたときにそのアラートを削除/削除することを忘れないでください!
Quick out put:(背景は暗いだけでなく、必要に応じてカスタマイズできます)
このスタイルを使用して、ダイアログに適用します。
PS:このスタイルは、Android 6.0、6.1、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>
そして次のように使用します:
final Dialog mBottomSheetDialog = new Dialog(mActivity, R.style.MaterialDialogSheet);
ありがとう。