Android Nougat中ListView上下文菜单定位异常问题求助
Hey, sorry to hear you're stuck with the ContextMenu positioning issue on Android 7.x—especially since the common fixes you found aren't working for your app. Let's go through some tailored solutions based on your setup: minSdkVersion="9", targetSdkVersion="25", and a theme rooted in android:Theme.Light.
Switch to an AppCompat Theme
The stockandroid:Theme.Lighthas known compatibility quirks with Android 7.x. Switching to an AppCompat theme not only maintains backward compatibility for your minSdk 9 requirement but also fixes many high-version UI alignment bugs. Update yourstyles/styles.xmllike this:<resources> <style name="AppBaseTheme" parent="Theme.AppCompat.Light"> </style> <style name="AppTheme" parent="AppBaseTheme"> </style> </resources>Don't forget to make sure your Activities extend
AppCompatActivityinstead of the rawActivityclass—this is key for AppCompat to work properly.Manually Adjust ContextMenu Placement
If switching themes isn't feasible right now, you can override the context menu creation logic to manually correct its position. Here's how to calculate and set the right offset for Android Nougat+:@Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { super.onCreateContextMenu(menu, v, menuInfo); AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { int[] viewLocation = new int[2]; v.getLocationOnScreen(viewLocation); // Adjust the Y-offset to align with the tapped list item menu.setInitialOffset(viewLocation[1] + info.targetView.getHeight()); menu.setGravity(Gravity.TOP | Gravity.START); } // Inflate your menu items as usual getMenuInflater().inflate(R.menu.your_context_menu, menu); }Fix ListView Touch Event Handling
If this is happening with a ListView, Android 7.x changed how touch events are propagated for list items, which can throw off context menu positioning. Try a custom ListView that ensures proper selection on touch:public class FixedPositionListView extends ListView { public FixedPositionListView(Context context) { super(context); } public FixedPositionListView(Context context, AttributeSet attrs) { super(context, attrs); } @Override public boolean onTouchEvent(MotionEvent ev) { if (ev.getAction() == MotionEvent.ACTION_DOWN) { int tappedPosition = pointToPosition((int) ev.getX(), (int) ev.getY()); if (tappedPosition != INVALID_POSITION) { setSelection(tappedPosition); } } return super.onTouchEvent(ev); } }Replace your regular ListView with this custom one in your layouts to see if it resolves the positioning drift.
Disable Hardware Acceleration (Temporary Test)
In some cases, hardware acceleration can cause rendering glitches that affect menu positioning. You can test this by disabling it for the problematic Activity in yourAndroidManifest.xml:<activity android:name=".YourProblematicActivity" android:hardwareAccelerated="false"> </activity>Note: This is a temporary test—disabling hardware acceleration can hurt other UI performance, so only use it to confirm the root cause before moving to a better fix.
内容的提问来源于stack exchange,提问作者Walter

