How to make horizontal contextmenu?

I did an Activity called Accounts and want to add the ContextMenu horizontal. It may look like cut, copy, and paste options. Is there any way to add this onLongClick horizontal custom menu to the list items?

That's what I got so far.

 @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { super.onCreateContextMenu(menu, v, menuInfo); LayoutInflater inflater = getLayoutInflater().from(this); View view = inflater.inflate(R.layout.custom_listview, null, false); menu.setHeaderView(view); menu.add("Delete"); menu.add("Edit"); } @Override public boolean onContextItemSelected(MenuItem item) { AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo(); int position = info.position; View v = listView.getChildAt(position); TextView typeTv = v.findViewById(R.id.custom_listview_type); TextView userTv = v.findViewById(R.id.custom_listview_user); TextView passTv = v.findViewById(R.id.custom_listview_password); if (item.getTitle().equals("Delete")) { db.execSQL("delete from user_added_accounts where accountType = '" + typeTv.getText().toString() + "' and username = '" + userTv.getText().toString() + "';"); recreate(); } if (item.getTitle().equals("Edit")) { update(typeTv.getText().toString(), userTv.getText().toString(), passTv.getText().toString()); } return true; } 

And the current interface is as follows.

Present working condition

Here is what I want

enter image description here

+9
java android contextmenu
source share
5 answers

You can simply achieve it using the QuickAction library.

https://github.com/piruin/quickaction
https://github.com/lorensiuswlt/NewQuickAction

enter image description here

Hope this helps you !!

+5
source share

I think you need PopupWindow . It is easier to implement and has its own layout settings. PopupWindow can be customized in a user position as you like, and the idea of ​​implementing a sample UI for copy / paste of which you are thinking can be implemented using the PopupWindow implementation.

I found this answer very informative if you want to realize your situation using PopupWindow instead of implementing it in the context menu.

In the answer above, which I mentioned and provided, I like PopupWindow , which only has a TextView . You can implement any user / complex interface, instead of a simple TextView , as shown in the figure.

Hope this helps.

Refresh

As indicated in the commentary, you can set the dynamic location of the locations of the PopupWindow position. I am referring to another link so that you can also check the implementation.

Here is the implementation of using PopupWindow in the list.

+4
source share

I used Dialog for this, still looking for a standard way. Please write the best way.

Test.java

 public void showOptionMenu(View view) { int x1 = (int) view.getX(); int y1 = (int) view.getY(); LayoutInflater inflater = LayoutInflater.from(MainActivity.this); View v = inflater.inflate(R.layout.popup_window , null); Dialog dialog = new Dialog(MainActivity.this); dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); WindowManager.LayoutParams wmlp = dialog.getWindow().getAttributes(); wmlp.gravity = Gravity.TOP | Gravity.LEFT; wmlp.x = x1; //x position wmlp.y = y1; //y position dialog.setContentView(v); dialog.show(); } 

activity_main.xml

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main_layout" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.example.shiva.testacitivity.MainActivity"> <Button android:text="Show Options" android:onClick="showOptionMenu" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="10dp"/> </LinearLayout> 

popup_windows.xml

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="center" android:background="#ECEFF1" android:padding="5dp" android:gravity="center" android:orientation="horizontal"> <TextView android:id="@+id/edit" android:layout_width="match_parent" android:layout_height="wrap_content" android:drawableLeft="@drawable/edit" android:layout_gravity="center" android:gravity="center" android:textColor="#000" android:text="Edit" /> <View android:layout_width="1dp" android:layout_height="match_parent"/> <TextView android:id="@+id/delete" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center" android:gravity="center" android:drawableLeft="@drawable/delete" android:text="Delete" android:textColor="#000" /> </LinearLayout> 

And the result

current user interface

0
source share

So, I wrote the code below a few years ago. First you need to make two classes: PopUp , and the second - TringleView .

PopUp: - Create a dialog box and open it in the immediate vicinity (where you want to open the dialog). You can change the color of the bg popup .

TringleView: - Make a tringle view or you can specify an arrow. You can change the color of the arrow bg .

 View contentView = ((FragmentActivity)v.getContext()).getLayoutInflater().inflate(R.layout.edit_delete_layout,getAttachedRecyclerView(),false); // this view denote where you click or you want to open dialog near PopUp.showPopupOnView(((FragmentActivity) v.getContext()).getSupportFragmentManager(),contentView,view,false); 

Popup.class

 public class PopUp extends DialogFragment { protected int targetX; protected int targetY; protected int targetWidth; protected int targetHeight; protected Bitmap targetViewImage; protected View contentView; private SmartWorksPopUpViewHolder fragmentViewHolder; private static int bgDrawable = R.drawable.round_corner_white_bg; protected static int ONE_DIP; private static int arrowBgColor = R.color.border_color; private static int arrowWidthMultiple = 25; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (ONE_DIP == 0) { ONE_DIP = (int) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, 1, getResources() .getDisplayMetrics()); } setStyle(DialogFragment.STYLE_NO_TITLE, android.R.style.Theme_Translucent); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { AbsoluteLayout parent = new AbsoluteLayout(getActivity()); parent.setId(R.id.parentLayout); return parent; } @Override public void onViewCreated(View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); this.fragmentViewHolder = createViewHolder(view); bindView(fragmentViewHolder); } protected SmartWorksPopUpViewHolder createViewHolder( View fragmentView) { return new SmartWorksPopUpViewHolder(fragmentView, contentView); } private void bindView(SmartWorksPopUpViewHolder vh) { if (fragmentViewHolder != null) { setupTargetDummyView(vh); boolean showOnTop = shouldShowOnTop(); setupArrow(vh, showOnTop); setupContent(vh, showOnTop); } } protected void setupContent(SmartWorksPopUpViewHolder vh, boolean showOnTop) { final int y; AbsoluteLayout.LayoutParams arrowParams = (android.widget.AbsoluteLayout.LayoutParams) vh.arrow .getLayoutParams(); int measureHeight = View.MeasureSpec.makeMeasureSpec( ViewGroup.LayoutParams.WRAP_CONTENT, View.MeasureSpec.UNSPECIFIED); int measureWidth = View.MeasureSpec.makeMeasureSpec( getActivity().getWindow().getDecorView().getWidth(), View.MeasureSpec.EXACTLY); vh.popupView.measure(measureWidth, measureHeight); if (showOnTop) { y = this.targetY - vh.popupView.getMeasuredHeight() + ONE_DIP; } else { y = arrowParams.y + arrowParams.height - ONE_DIP * 2; } updateAbsoluteLayoutParams( getActivity().getResources().getDimensionPixelOffset(R.dimen.sixty_dp), y, getActivity().getWindow().getDecorView().getWidth() - getActivity().getResources().getDimensionPixelOffset(R.dimen.seventy_dp), ViewGroup.LayoutParams.WRAP_CONTENT, vh.popupView); vh.parent.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { exit(); } }); } private void setupArrow(SmartWorksPopUpViewHolder vh, boolean showOnTop) { final int arrowHeight = 15 * ONE_DIP; final int arrowWidth = arrowWidthMultiple * ONE_DIP; vh.arrow.setDirectionAndColor(showOnTop ? "down" : "top", vh.popupView.getContext().getResources().getColor(arrowBgColor)); final int x = (int) (targetX + targetWidth / 3 - arrowWidth / 2); final int y = targetY + (showOnTop ? -arrowHeight : targetHeight); updateAbsoluteLayoutParams(x, y, arrowWidth, arrowHeight, vh.arrow); } private void setupTargetDummyView(SmartWorksPopUpViewHolder vh) { vh.targetViewDummy.setImageBitmap(targetViewImage); updateAbsoluteLayoutParams(targetX, targetY, targetWidth, targetHeight, vh.targetViewDummy); } protected void updateAbsoluteLayoutParams(int x, int y, int width, int height, View view) { AbsoluteLayout.LayoutParams layoutParams = (android.widget.AbsoluteLayout.LayoutParams) view.getLayoutParams(); layoutParams.x = x; layoutParams.y = y; layoutParams.height = height; layoutParams.width = width; view.setLayoutParams(layoutParams); } private boolean shouldShowOnTop() { int windowHeight = getActivity().getWindow().getDecorView().getHeight(); int windowMid = windowHeight / 4; return targetY > windowMid; } @Override public void onDestroyView() { this.fragmentViewHolder = null; super.onDestroyView(); } protected static class SmartWorksPopUpViewHolder { protected AbsoluteLayout parent; protected View popupView; protected TringleView arrow; protected AppCompatImageView targetViewDummy; protected SmartWorksPopUpViewHolder(View fragmentView, View content) { this.parent = (AbsoluteLayout) fragmentView; final Context mContext = fragmentView.getContext(); this.popupView = content; this.arrow = new TringleView(mContext); this.targetViewDummy = new SmartWorksAppCompactImageView(mContext); this.parent.addView(popupView); this.parent.addView(arrow); this.parent.addView(targetViewDummy); this.parent.setBackgroundColor(0x00000000); content.setBackgroundResource(bgDrawable); } } public static PopUp showPopupOnView(FragmentManager fm, View contentView, View targetView, boolean showTargetView) { int[] location = new int[2]; targetView.getLocationInWindow(location); PopUp fragment = new PopUp(); fragment.targetX = location[0]; fragment.targetY = (int) (location[1] - TypedValue .applyDimension(TypedValue.COMPLEX_UNIT_DIP, 25, targetView.getResources().getDisplayMetrics())); fragment.targetWidth = targetView.getMeasuredWidth(); fragment.targetHeight = targetView.getMeasuredHeight(); fragment.contentView = contentView; fragment.show(fm, "offer"); return fragment; } public void exit() { dismiss(); } public static void setArrowBackgroundColor(int color) { arrowBgColor = color; } public static void setArrowWidthMultiple(int arrowWidth) { arrowWidthMultiple = arrowWidth; } } 

Tringleview.class

 public class TringleView extends View { private String direction; private int color; public TringleView(Context context) { super(context); setDirectionAndColor("right", Color.RED); } public TringleView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); setDirectionAndColor(attrs.getAttributeValue(null, "direction"), Color.RED); } public TringleView(Context context, AttributeSet attrs) { super(context, attrs); setDirectionAndColor(attrs.getAttributeValue(null, "direction"), Color.RED); } public void setDirectionAndColor(String direction, int color) { if (direction != null && !direction.equals(this.direction) || this.color != color) { createTriangleDrawable(direction, color); } } private void createTriangleDrawable(String string, int color) { int width = MeasureSpec.makeMeasureSpec(30, MeasureSpec.UNSPECIFIED); int height = MeasureSpec.makeMeasureSpec(20, MeasureSpec.UNSPECIFIED); Path path = new Path(); if (string == null) { string = "right"; } if (string.equals("top")) { path.moveTo(0, height); path.lineTo(width / 2, 0); path.lineTo(width, height); } else if (string.equals("left")) { path.moveTo(width, 0); path.lineTo(0, height / 2); path.lineTo(width, height); } else if (string.equals("right")) { path.moveTo(0, 0); path.lineTo(width, height / 2); path.lineTo(0, height); } else if (string.equals("down")) { path.moveTo(0, 0); path.lineTo(width / 2, height); path.lineTo(width, 0); } path.close(); ShapeDrawable shapeDrawable = new ShapeDrawable(new PathShape(path, width, height)); shapeDrawable.getPaint().setColor(color); setBackground(shapeDrawable); this.color = color; this.direction = string; } } 

edit_delete_layout.xml

 <?xml version="1.0" encoding="utf-8"?> <android.support.v7.widget.CardView app:cardCornerRadius="@dimen/five_dp" android:layout_margin="@dimen/ten_dp" xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" app:layout_behavior="android.support.design.widget.BottomSheetBehavior" android:layout_width="match_parent" android:layout_height="wrap_content" > <LinearLayout app:layout_behavior="android.support.design.widget.BottomSheetBehavior" android:layout_width="match_parent" android:layout_height="wrap_content" android:weightSum="5" android:gravity="center" android:orientation="horizontal" xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <sis.com.smartworks.widget.SmartWorksTextView android:id="@+id/share" android:textSize="@dimen/smallest_text_size" android:textColor="@color/black" android:visibility="visible" android:gravity="center" android:paddingRight="@dimen/four_dp" android:paddingLeft="@dimen/four_dp" android:paddingTop="@dimen/ten_dp" android:paddingBottom="@dimen/ten_dp" android:text="Share" android:layout_weight="1" android:textStyle="bold" android:layout_width="0dp" android:layout_height="wrap_content" /> <View android:layout_width="1dp" android:background="@color/grey_unselect" android:layout_height="match_parent" /> <sis.com.smartworks.widget.SmartWorksTextView android:id="@+id/reportSpam" android:textSize="@dimen/smallest_text_size" android:textColor="@color/black" android:visibility="visible" android:gravity="center" android:paddingRight="@dimen/four_dp" android:paddingLeft="@dimen/four_dp" android:paddingTop="@dimen/ten_dp" android:paddingBottom="@dimen/ten_dp" android:text="Spam" android:layout_weight="1" android:textStyle="bold" android:layout_width="0dp" android:layout_height="wrap_content" /> <View android:layout_width="1dp" android:background="@color/grey_unselect" android:layout_height="match_parent" /> <!--<View--> <!--android:layout_width="match_parent"--> <!--android:layout_marginLeft="@dimen/three_dp"--> <!--android:layout_marginRight="@dimen/three_dp"--> <!--android:background="@color/white"--> <!--android:layout_height="@dimen/one_dp" />--> <sis.com.smartworks.widget.SmartWorksTextView android:id="@+id/edit" android:textSize="@dimen/smallest_text_size" android:textColor="@color/black" android:gravity="center" android:paddingRight="@dimen/four_dp" android:paddingLeft="@dimen/four_dp" android:paddingTop="@dimen/ten_dp" android:paddingBottom="@dimen/ten_dp" app:swFontName="robotoNormal" android:layout_weight="1" android:text="@string/edit" android:textStyle="bold" android:layout_width="0dp" android:layout_height="wrap_content" /> <View android:layout_width="1dp" android:background="@color/grey_unselect" android:layout_height="match_parent" /> <!--<View--> <!--android:layout_width="match_parent"--> <!--android:layout_marginLeft="@dimen/three_dp"--> <!--android:layout_marginRight="@dimen/three_dp"--> <!--android:background="@color/white"--> <!--android:layout_height="@dimen/one_dp" />--> <sis.com.smartworks.widget.SmartWorksTextView android:id="@+id/delete" android:textSize="@dimen/smallest_text_size" android:textColor="@color/black" android:gravity="center" android:paddingRight="@dimen/four_dp" android:paddingLeft="@dimen/four_dp" android:paddingTop="@dimen/ten_dp" android:paddingBottom="@dimen/ten_dp" android:layout_weight="1" android:text="@string/delete" android:textStyle="bold" android:layout_width="0dp" android:layout_height="wrap_content" /> <View android:layout_width="1dp" android:background="@color/grey_unselect" android:layout_height="match_parent" /> <sis.com.smartworks.widget.SmartWorksTextView android:id="@+id/cancel" android:textSize="@dimen/smallest_text_size" android:textColor="@color/black" android:gravity="center" android:layout_weight="1" android:visibility="visible" android:paddingRight="@dimen/four_dp" android:paddingLeft="@dimen/four_dp" android:paddingTop="@dimen/ten_dp" android:paddingBottom="@dimen/ten_dp" android:textStyle="bold" android:text="@string/select_cancel" android:layout_width="0dp" android:layout_height="wrap_content" /> </LinearLayout> </android.support.v7.widget.CardView> 

Result

! [enter image description here

So, if you want to make the view horizontal, you need to make the horizontal layout according to your requirement. So you can complete this task to change your edit_delete_layout.xml that you put in the contentView , then go to the Popup class method .

Note. - You can customize the popup class according to your requirement, and I know that this code has so much outdated representation that you can update yourself.

0
source share

To show a compact context menu, you need to create an ActionMode for the Menu , let me show you how:

Suppose your XML action menu has delete, copy, and forward actions:

 <?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <item android:id="@+id/action_copy" android:icon="@drawable/ic_vector_menu_copy" android:title="Copy" app:showAsAction="always" /> <item android:id="@+id/action_delete" android:icon="@drawable/ic_vector_menu_delete" android:title="Delete" app:showAsAction="always" /> <item android:id="@+id/action_forward" android:icon="@drawable/ic_vector_menu_forward" android:title="Forward" app:showAsAction="always" /> </menu> 

Create your own action menu in your activity

 //Global variable in Activity/Fragment to manage close the menu private ActionMode mActionMode; //Action mode callbacks //Contextual Action bar - for showing delete/copy/... on action bar private ActionMode.Callback mActionModeCallback = new ActionMode.Callback() { // Called when the action mode is created; startActionMode() was called @Override public boolean onCreateActionMode(ActionMode mode, Menu menu) { // Inflate a menu resource providing context menu items MenuInflater inflater = mode.getMenuInflater(); inflater.inflate(R.menu.menu_contextual_action, menu); return true; } // Called each time the action mode is shown. // Always called after onCreateActionMode, but // may be called multiple times if the mode is invalidated. @Override public boolean onPrepareActionMode(ActionMode mode, Menu menu) { return false; // Return false if nothing is done } // Called when the user selects a contextual menu item @Override public boolean onActionItemClicked(final ActionMode mode, MenuItem item) { switch (item.getItemId()) { case R.id.action_delete: //Do the delete action //mAdapter.resetSelection(); mode.finish(); // Action picked, so close the TAB //showToast "Deleted successfully" return true; case R.id.action_copy: //mAdapter.resetSelection(); MyClipboardManager.copyToClipboard(ChatDetailActivity.this, mAdapter.getSelectedMessageText()); mode.finish(); // Action picked, so close the TAB //showToast "Text copied to clipboard" return true; default: return false; } } // Called when the user exits the action mode @Override public void onDestroyActionMode(ActionMode mode) { mActionMode = null; //mAdapter.resetSelection(); } }; @Override public void onBackPressed() { //Closing menu first if it visible rather than doing the back press action if (mActionMode != null && mActionMode.getMenu().hasVisibleItems()) { mActionMode.finish(); return; } super.onBackPressed(); } @Override public void onDestroy() { //Closing menu if (mActionMode != null) { mActionMode.finish(); } super.onDestroy(); } 

* Set callback for global action mode variable

 mActionMode = startSupportActionMode(mActionModeCallback); 

* Set menu title

 mActionMode.setTitle("Menu title"); 

* Cancel the menu after the settings value

 mActionMode.invalidate(); 

Style for managing compact context menus

 <!-- Base application theme. --> <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar"> <!-- Customize your theme here. --> <item name="colorPrimary">@color/colorPrimary</item> <item name="colorPrimaryDark">@color/colorPrimaryDark</item> <item name="colorAccent">@color/colorAccent</item> <item name="android:windowDisablePreview">true</item> <!--CONTEXTUAL action MODE--> <item name="android:windowContentOverlay">@null</item> <!--ActionMode background color--> <!-- <item name="android:actionModeBackground">@color/colorPrimary</item>--> <!--To Overlay existing toolbar, NOTE We are not using android: to let it work everywhere--> <item name="windowActionModeOverlay">true</item> <item name="actionModeStyle">@style/AppActionModeStyle</item> <item name="android:actionModeCloseDrawable">@drawable/ic_arrow_back_24dp</item> </style> <style name="AppActionModeStyle" parent="@style/Widget.AppCompat.ActionMode"> <!--ActionMode background color--> <item name="background">@color/colorPrimary</item> <!--ActionMode text title color--> <item name="titleTextStyle">@style/ActionModeTitleTextStyle</item> </style> <style name="ActionModeTitleTextStyle" parent="@style/TextAppearance.AppCompat.Widget.ActionMode.Title"> <item name="android:textColor">@android:color/white</item> </style> 
0
source share

All Articles