我创建了一个带右侧抽屉的DrawerLayout。到现在为止还挺好。现在,有一个菜单项,当点击时打开一个带有5个不同选项的弹出菜单(见截图)。当单击其中一个选项时,主菜单中的图标应交换为我刚刚单击的图标,然后主菜单应该关闭。但是,我无法创建该行为。目前,当我尝试单击弹出菜单中的一个选项时,会发生以下情况: 1.主菜单(抽屉)关闭。 2.只有当我再次单击所需选项 时才会交换主菜单中的图标。 据我所知,这是DrawerView中抽屉的默认行为,一旦我点击屏幕中的某个地方就会被关闭。我试图通过设置锁定模式解决它:
myDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_OPEN, Gravity.END)
......但没有运气。一旦我尝试单击弹出窗口中的一个项目,抽屉就会关闭。 甚至可以在DrawerLayout中实现我想要的东西吗?
这是我的代码:
activity_main.xml中
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="net.videosc2.activities.VideOSCMainActivity">
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/camera_preview"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ImageView
android:id="@+id/camera_downscaled"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:antialias="false"
android:contentDescription="@string/preview_image_content_description"
android:scaleType="fitXY"/>
</FrameLayout>
<!-- The navigation drawer that comes from the right (layout_gravity:end) -->
<ListView
android:id="@+id/drawer"
android:layout_width="50dp"
android:layout_height="match_parent"
android:layout_gravity="center_vertical|end"
android:background="#99000000"
android:choiceMode="singleChoice"
android:divider="@android:color/transparent"
android:dividerHeight="10dp"
app:itemTextColor="@android:color/white"/>
</android.support.v4.widget.DrawerLayout>
drawer_item.xml
<?xml version="1.0" encoding="utf-8"?>
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/tool"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:attr/activatedBackgroundIndicator"
android:contentDescription="@string/a_tools_menu_item"
android:gravity="center_vertical"
android:paddingBottom="8dp"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:paddingTop="8dp"/>
color_mode_panel.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/color_mode_panel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:layout_marginEnd="60dp"
android:layout_marginRight="60dp"
android:layout_marginTop="100dp"
android:background="#99000000"
android:clickable="true"
android:orientation="horizontal">
<ImageButton
android:id="@+id/mode_rgb"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#00000000"
android:contentDescription="@string/color_mode_rgb"
android:padding="8dp"
android:src="@drawable/rgb"/>
<ImageButton
android:id="@+id/mode_rgb_inv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#00000000"
android:clickable="true"
android:contentDescription="@string/color_mode_rgb_neg"
android:padding="8dp"
android:src="@drawable/rgb_inv"/>
<ImageButton
android:id="@+id/mode_r"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#00000000"
android:contentDescription="@string/color_mode_r"
android:padding="8dp"
android:src="@drawable/r"/>
<ImageButton
android:id="@+id/mode_g"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#00000000"
android:contentDescription="@string/color_mode_g"
android:padding="8dp"
android:src="@drawable/g"/>
<ImageButton
android:id="@+id/mode_b"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#00000000"
android:contentDescription="@string/color_mode_b"
android:padding="8dp"
android:src="@drawable/b"/>
</LinearLayout>
MainActivity.java
public class MainActivity extends AppCompatActivity {
static final String TAG = "MainActivity";
View camView;
public static Point dimensions;
private DrawerLayout toolsDrawerLayout;
private FrameLayout mainFrame;
private ActionBarDrawerToggle drawerToggle;
protected ArrayList<View> uiElements = new ArrayList<>();
// is device currently sending OSC?
public boolean isPlaying = false;
// is flashlight on?
public boolean isTorchOn = false;
// don't create more than one color mode panel
private boolean isColorModePanelOpen = false;
public Fragment cameraPreview;
Camera camera;
/**
* Fragment managing the behaviors, interactions and presentation of the navigation drawer.
*/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_main);
final FragmentManager fragmentManager = getFragmentManager();
if (findViewById(R.id.camera_preview) != null) {
camView = findViewById(R.id.camera_preview);
if (savedInstanceState != null) return;
cameraPreview = new VideOSCCameraFragment();
fragmentManager.beginTransaction()
.replace(R.id.camera_preview, cameraPreview, "CamPreview")
.commit();
}
TypedArray tools = getResources().obtainTypedArray(drawer_icons_id);
toolsDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
toolsDrawerLayout.setScrimColor(Color.TRANSPARENT);
// FIXME: touches seem to get swallowed by the DrawerLayout first
final ListView toolsDrawerList = (ListView) findViewById(R.id.drawer);
List<BitmapDrawable> toolsList = new ArrayList<>();
for (int i = 0; i < tools.length(); i++) {
toolsList.add((BitmapDrawable) tools.getDrawable(i));
}
// set the drawer menu in a custom Adapter
toolsDrawerList.setAdapter(new ToolsMenuAdapter(this, R.layout.drawer_item, R.id.tool, toolsList));
tools.recycle();
toolsDrawerList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
BitmapDrawable img;
final ImageView imgView = (ImageView) view.findViewById(R.id.tool);
Context context = getApplicationContext();
// we can not use 'cameraPreview' to retrieve the 'mCamera' object
VideOSCCameraFragment camPreview = (VideOSCCameraFragment) fragmentManager.findFragmentByTag("CamPreview");
camera = camPreview.mCamera;
LayoutInflater inflater = getLayoutInflater();
switch (i) {
// ... other cases...
case 2:
if (!isColorModePanelOpen) {
int y = (int) view.getY();
// create pop-out
final View modePanel = inflater.inflate(R.layout.color_mode_panel, (FrameLayout) camView, true);
isColorModePanelOpen = true;
// try to lock the main menu drawer - didn't work for me
toolsDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_OPEN, toolsDrawerList);
final View modePanelInner = modePanel.findViewById(R.id.color_mode_panel);
// set the vertical position of the pop-out
ActivityHelpers.setMargins(modePanelInner, 0, y, 0, 0);
// set actions for each item in the pop-out
for (int k = 0; k < ((ViewGroup) modePanelInner).getChildCount(); k++) {
final Context iContext = context;
View button = ((ViewGroup) modePanelInner).getChildAt(k);
button.setOnClickListener(new View.OnClickListener() {
@Override
// FIXME: touches seem to get swallowed by the DrawerLayout first
public void onClick(View view) {
switch (view.getId()) {
case R.id.mode_rgb:
Log.d(TAG, "rgb");
imgView.setImageDrawable(ContextCompat.getDrawable(iContext, R.drawable.rgb));
break;
case R.id.mode_rgb_inv:
Log.d(TAG, "rgb inverted");
imgView.setImageDrawable(ContextCompat.getDrawable(iContext, R.drawable.rgb_inv));
break;
case R.id.mode_r:
Log.d(TAG, "red");
imgView.setImageDrawable(ContextCompat.getDrawable(iContext, R.drawable.r));
break;
case R.id.mode_g:
Log.d(TAG, "green");
imgView.setImageDrawable(ContextCompat.getDrawable(iContext, R.drawable.g));
break;
case R.id.mode_b:
Log.d(TAG, "blue");
imgView.setImageDrawable(ContextCompat.getDrawable(iContext, R.drawable.b));
break;
default:
imgView.setImageDrawable(ContextCompat.getDrawable(iContext, R.drawable.rgb));
}
// remove the pop-out
((ViewGroup) modePanelInner.getParent()).removeView(modePanelInner);
isColorModePanelOpen = false;
// unlock the drawer again
toolsDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED, Gravity.END);
// now the drawer should finally get closed
toolsDrawerLayout.closeDrawer(Gravity.END);
}
});
}
}
break;
// ... other cases ...
}
});
// open drawer on application start
toolsDrawerLayout.openDrawer(Gravity.END);
}
}
}
编辑:
我发现this post为我提供了一种简单的方法,可以通过在MainActivity.java中添加以下内容来阻止弹出窗口被关闭:
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
// We only want to intercept MotionEvent.ACTION_UP if the pop-out is present
return !(isColorModePanelOpen && event.getAction() == MotionEvent.ACTION_UP) && super.dispatchTouchEvent(event);
}
当试图单击弹出窗口中的一个按钮时,抽屉没有立即关闭。不幸的是,按钮不接受点击(分别用事件动作MotionEvent.ACTION_DOWN触摸)。看来,只要抽屉没有再次关闭,整个屏幕就会被阻止任何用户交互。
任何人都可以证实我的怀疑吗? (或证明我错了)
谢谢
答案 0 :(得分:0)
在您的活动的onResume()
中试用此代码
if(condition)
{
mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_OPEN);
}
else
{
mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
}