Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
952 views
in Technique[技术] by (71.8m points)

android - PopupWindow not triggering sytem context dialog on EditText long-press

Sorry if the title was a bit vague.

I'm developing an app on Freelancer and I almost have it finished except for a complaint from the customer after some testing.

I use a PopupWindow in place of a dialog to edit contextual settings, if that makes any sense. I don't want to be too specific and risk giving the app concept away, which I'm sure the customer wouldn't be too pleased about.

The PopupWindow is given a Content View of a layout inflated from XML. In that layout are several EditText widgets. The issue is that those EditTexts will not trigger the default contextual dialog on long press that presents options for text/IME selection, and cut/copy/paste.

I saw a similar question trying to get the TouchTrigger or something and it not working without setBackgroundDrawable(), which I've tried with a simple new ColorDrawable(). It still doesn't work.

Is there any easy way to trigger the system-default long-press dialog in an OnLongPressListener, or will I have to move Heaven and Earth to implement it myself? Because if that's the case, I'll just write a Fragment for it and swap it out in a transaction. I know that'll work.

The relevant code: Inside the initiating fragment:

RulesDialog dialog;
PopupWindow window;

public void showAddRuleDialog(){
    dialog = new RulesDialog();

    View view = getView();

    window = new PopupWindow(dialog.initViews(this, null), view.getWidth(), view.getHeight(), true);

    window.setBackgroundDrawable(new ColorDrawable());

    dialog.setRulesDialogListener(new rulesDialogListener(){            

        @Override
        public void onSave(ViewHolder holder) {


            addRule(holder);

            window.dismiss();


        }

        @Override
        public void onCancel() {
            window.dismiss();

        }});

    int[] location = {0,0};
    view.getLocationOnScreen(location);



    window.showAtLocation(view, 0, location[0], location[1]);

In RulesDialog:

public class ViewHolder{
    public ViewHolder(View dialogView){
        name = (TextView) dialogView.findViewById(R.id.name);
        response = (TextView) dialogView.findViewById(R.id.response);

        senders = (TextView) dialogView.findViewById(R.id.senders);
        sendersAdd = (Button) dialogView.findViewById(R.id.sendersAdd);
        sendersEdit = (Button) dialogView.findViewById(R.id.sendersEdit);

        timeFrom = (TextView) dialogView.findViewById(R.id.from);
        timeFromEdit = (Button) dialogView.findViewById(R.id.timeBeforeEdit);
        timeTo = (TextView) dialogView.findViewById(R.id.to);
        timeToEdit = (Button) dialogView.findViewById(R.id.timeAfterEdit);

        keywords = (TextView) dialogView.findViewById(R.id.keywords);

        matchCase = (CheckBox) dialogView.findViewById(R.id.matchCase);
        matchAlone = (CheckBox) dialogView.findViewById(R.id.matchAlone);
        matchPlural = (CheckBox) dialogView.findViewById(R.id.matchPlural);

        cancel = (Button) dialogView.findViewById(R.id.cancel);
        save = (Button) dialogView.findViewById(R.id.save);


    }

    TextView name;
    TextView response;
    TextView senders;
    Button sendersAdd;
    Button sendersEdit;
    TextView timeFrom;
    Button timeFromEdit;
    TextView timeTo;
    Button timeToEdit;
    TextView keywords;

    CheckBox matchCase;
    CheckBox matchAlone;
    CheckBox matchPlural;

    Button cancel;
    Button save;


}

Activity activity;
ViewHolder holder;
Fragment fragment;



public View initViews(Fragment mFragment, Rule rule){
    fragment = mFragment;
    activity = fragment.getActivity();
    View dialogView = LayoutInflater.from(activity).inflate(R.layout.rules_dialog, null);

    holder = new ViewHolder(dialogView);

    final TextView senders = holder.senders;

    holder.sendersAdd.setOnClickListener(new OnClickListener(){

        @Override
        public void onClick(View v) {
            showContacts();
        }});

    holder.sendersEdit.setOnClickListener(new OnClickListener(){

        @Override
        public void onClick(View v) {
            editSenders(senders);

        }

    });

    final TextView timeFrom = holder.timeFrom;
    holder.timeFromEdit.setOnClickListener(new OnClickListener(){

        @Override
        public void onClick(View v) {
            showTimePickerDialog(timeFrom);             

        }

        });

    final TextView timeTo = holder.timeTo;
    holder.timeToEdit.setOnClickListener(new OnClickListener(){

        @Override
        public void onClick(View v) {
            showTimePickerDialog(timeTo);               

        }

        });


    holder.cancel.setOnClickListener(new OnClickListener(){

        @Override
        public void onClick(View v) {
            mListener.onCancel();

        }});        
    holder.save.setOnClickListener(new OnClickListener(){

        @Override
        public void onClick(View v) {
            mListener.onSave(holder);

        }});


    if(rule == null)
        rule = new Rule();


    holder.name.setText(rule.name);
    holder.response.setText(rule.response);

    holder.senders.setText(rule.senders.toString());
    holder.senders.setTag(rule.senders);                

    holder.keywords.setText(rule.keywords);

    holder.matchCase.setChecked(rule.matchCase);
    holder.matchAlone.setChecked(rule.matchAlone);
    holder.matchPlural.setChecked(rule.matchPlural);        

    holder.timeFrom.setTag(rule.timeFrom);                          
    holder.timeFrom.setText(Rules.formatTime(rule.timeFrom));

    holder.timeTo.setTag(rule.timeTo);
    holder.timeTo.setText(Rules.formatTime(rule.timeTo));

    return dialogView;
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

So I tried rewriting RulesDialog as a fragment, and it didn't work out too well. Had issues with making Fragment Transactions work right when called from the Fragments they're operating on.

(I know this isn't the point to fragments. I'm not really aiming to write a completely modular app right now. I just want to come out with a product the customer will be happy with.)

I ended up rewriting RulesDialog as an Activity instead, and using startActivityForResult() from the calling fragment. Then passing the edited data back with setResult(). It all works nicely in concert.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...