我尝试创建一个包含持久性底部工作表和提供主要内容的NestedScrollView的布局。不幸的是,当扩展底部工作表时,它会模糊NestedScrollView,并且无法访问它的底部项目。 ?
调整主NestedScroll大小以适应展开的底部工作表的最佳方法是什么?
举个例子:
<android.support.design.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<!-- I want this view resized dependent on bottom sheet expansion -->
<android.support.v4.widget.NestedScrollView
android:id="@+id/layout_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<!-- content goes here -->
</android.support.v4.widget.NestedScrollView>
<android.support.v4.widget.NestedScrollView
android:id="@+id/layout_bottomsheet"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="android.support.design.widget.BottomSheetBehavior">
<!-- bottom sheet content goes here -->
</android.support.v4.widget.NestedScrollView>
</android.support.design.widget.CoordinatorLayout>
答案 0 :(得分:0)
有一种方法可以获得您需要的东西,避免遮挡底部工作表背后的视图并处理它的触摸。
您需要延长BottomSheetDialogFragment
。
public class MyBottomSheetDialogFragment extends BottomSheetDialogFragment {
@Override
public void onStart() {
super.onStart();
if(getDialog() != null && getDialog().getWindow() != null) {
getDialog().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
}
在onStart()中,你可以删除背景暗淡,这样你就可以清楚地看到你的背后视图。
@Override
public void setupDialog(Dialog dialog, int style) {
super.setupDialog(dialog, style);
View rootView = View.inflate(getContext(), R.layout.your_bottom_sheet_layout, null);
dialog.setContentView(rootView);
dialog.setCanceledOnTouchOutside(false);
// set your children views
dialog.setOnShowListener(new DialogInterface.OnShowListener() {
@Override
public void onShow(DialogInterface dialogInterface) {
// Do stuff when the dialog is visible on screen
Window window = getDialog().getWindow();
if(window != null) {
window.setCallback(windowCallback);
}
}
});
}
在setupDialog()中夸大你的布局并避免通过设置一个窗口回调来解决你可以处理的外部触摸对话框,如下所示:
private Window.Callback windowCallback = new Window.Callback() {
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
onBackPressed();
}
return false;
}
@Override
public boolean dispatchKeyShortcutEvent(KeyEvent event) {
return false;
}
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
return onDispatchTouchEvent(event);
}
@Override
public boolean dispatchTrackballEvent(MotionEvent event) {
return false;
}
@Override
public boolean dispatchGenericMotionEvent(MotionEvent event) {
return false;
}
@Override
public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
return false;
}
@Nullable
@Override
public View onCreatePanelView(int featureId) {
return null;
}
@Override
public boolean onCreatePanelMenu(int featureId, Menu menu) {
return false;
}
@Override
public boolean onPreparePanel(int featureId, View view, Menu menu) {
return false;
}
@Override
public boolean onMenuOpened(int featureId, Menu menu) {
return false;
}
@Override
public boolean onMenuItemSelected(int featureId, MenuItem item) {
return false;
}
@Override
public void onWindowAttributesChanged(WindowManager.LayoutParams attrs) {
}
@Override
public void onContentChanged() {
}
@Override
public void onWindowFocusChanged(boolean hasFocus) {
}
@Override
public void onAttachedToWindow() {
}
@Override
public void onDetachedFromWindow() {
}
@Override
public void onPanelClosed(int featureId, Menu menu) {
}
@Override
public boolean onSearchRequested() {
return false;
}
@Override
public boolean onSearchRequested(SearchEvent searchEvent) {
return false;
}
@Nullable
@Override
public ActionMode onWindowStartingActionMode(ActionMode.Callback callback) {
return null;
}
@Nullable
@Override
public ActionMode onWindowStartingActionMode(ActionMode.Callback callback, int type) {
return null;
}
@Override
public void onActionModeStarted(ActionMode mode) {
}
@Override
public void onActionModeFinished(ActionMode mode) {
}
};
通过设置此回调,您需要管理每一次触摸。这有点棘手,但你可以获得目标。 onDispatchTouchEvent(事件)必须是这样的:
@Override
protected boolean onDispatchTouchEvent(MotionEvent event) {
// check if the dialog is being touched
float eventX = event.getRawX();
float eventY = event.getRawY();
int location[] = new int[2];
yourDialogRootView.getLocationOnScreen(location);
boolean isDialogBeingTouched = eventX > (location[0] - leftPaddingX)
&& eventX < (location[0] + view.getWidth())
&& eventY > (location[1])
&& eventY < (location[1] + view.getHeight());
if (isDialogBeingTouched) {
checkForAClick(event);
}
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
if (isDialogBeingTouched) {
// the dialog is touched so handle its touch
return true;
}
}
// dialog not touched so let the activity handle the touch normally
return getActivity().dispatchTouchEvent(event);
}
checkForAClick(事件)应该是这样的:
protected boolean checkForAClick(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
startX = event.getX();
startY = event.getY();
break;
case MotionEvent.ACTION_UP:
float endX = event.getX();
float endY = event.getY();
if (isAClick(startX, endX, startY, endY)) {
// handle click on your dialog as you prefer
onBottomSheetClick(event);
}
break;
}
return false;
}
private static int CLICK_ACTION_THRESHOLD = 50;
public boolean isAClick(float startX, float endX, float startY, float endY) {
float differenceX = Math.abs(startX - endX);
float differenceY = Math.abs(startY - endY);
if (differenceX > CLICK_ACTION_THRESHOLD || differenceY > CLICK_ACTION_THRESHOLD) {
return false;
}
return true;
}
我知道这有点长的解释,但我希望它可以提供帮助。