Textfield copy action on long hold (copy popup)

守給你的承諾、 提交于 2019-11-29 15:07:40
José Pereda

The push and hold event can be easily simulated in JavaFX, as in this question.

Once you get the initial event, all you need to do is call the ContextMenu from the TextField. Since TextField.getContextMenu() won't return the default one, you can either provide your own or try to get the default one.

Getting the default one is a little bit more tricky, since it is part of the TextFieldBehavior class. It contains this method public void contextMenuRequested(ContextMenuEvent e);, so all you need to do is provide a ContextMenuEvent, and fire the event from the TextField.

This is a quick implementation:

public class BasicView extends View {

    public BasicView(String name) {
        super(name);

        TextField textField = new TextField();

        addPressAndHoldHandler(textField, Duration.seconds(1), event -> {
            Bounds bounds = textField.localToScreen(textField.getBoundsInLocal());
            textField.fireEvent(new ContextMenuEvent(ContextMenuEvent.CONTEXT_MENU_REQUESTED, 
                    0, 0, bounds.getMinX() + 10, bounds.getMaxY() + 10, false, null));
        });

        setCenter(new VBox(15.0, new Label("Push and hold for ContextMenu"), textField));
    }

    private void addPressAndHoldHandler(Node node, Duration holdTime, EventHandler<MouseEvent> handler) {
        class Wrapper<T> { 
            T content; 
        }

        Wrapper<MouseEvent> eventWrapper = new Wrapper<>();

        PauseTransition holdTimer = new PauseTransition(holdTime);
        holdTimer.setOnFinished(event -> handler.handle(eventWrapper.content));

        node.addEventHandler(MouseEvent.MOUSE_PRESSED, event -> {
            eventWrapper.content = event;
            holdTimer.playFromStart();
        });
        node.addEventHandler(MouseEvent.MOUSE_RELEASED, event -> holdTimer.stop());
        node.addEventHandler(MouseEvent.DRAG_DETECTED, event -> holdTimer.stop());
    }

    @Override
    protected void updateAppBar(AppBar appBar) {
        appBar.setTitleText("Push and Hold");
    }

}

On Desktop this is what you'll get:

The good news is you don't need to modify the ContextMenu for Android, JavaFX has a custom one:

Note the different menu items will change automatically based on the context, as in the Desktop popup.

A quick search would show you something called "Context Menu". Here is small implementation :

TextView tv;

    @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            tv = (TextView) findViewById(R.id.tv1);
            registerForContextMenu(tv);
    }

    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo)
    {
        super.onCreateContextMenu(menu, v, menuInfo);
        menu.setHeaderTitle("Select The Action");
        menu.add(0, v.getId(), 0, "Copy");//groupId, itemId, order, title
    }
    @Override
    public boolean onContextItemSelected(MenuItem item){
        if(item.getTitle()=="Copy"){
            String text = tv.getText().toString();
            Log.e("onContextItemSelected",text);
        }

        return true;
    }

When you click on textView it shows a popup with given title and options from "onCreateContextMenu". Once you select an option "OnContextItemSelected" is called. Then you can use variable "text" as you wish. Don't forget to register the view for context menu using registerForContextMenu(tv).

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!