Android:自定义视图中的Handle Back按钮

时间:2014-04-01 12:35:28

标签: android view android-custom-view back-button

我通过扩展RelativeLayout为我的应用创建了自定义视图。它通过拖动dialog打开为ImageView。它有EditTextsButtons。我在我的视图中覆盖了onKeyDown,因为我需要拦截此视图中的后退按钮。如果自定义视图可见,则edittext未获得焦点,如果按下后退按钮,则视图将被取消,这是所需的。

出现问题,当edittext获得焦点,键盘可见时,按下后退按钮,软键盘被解除,但如果我再次按下后退按钮,则调用super.onKeyDown()而不是解除自定义视图我从我的应用程序退出,其中所需功能是在解除软键盘后关闭视图。我做错了什么?

以下是我的自定义视图代码:

public class AddTransactionView extends RelativeLayout implements View.OnClickListener {
    private final String TAG = "AddTransactionView";

    private Context context;

    private ViewGroup parentView;

    private FriendsDAO mFriendsDAO;

    private AppPreference mAppPreference;

    private ImageLoader imageLoader;

    private DisplayImageOptions options;

    private CircularImageView friendsImage;

    private Button btnIOwe, btnTheyOwe;

    private EditText edtTransactionDesc, edtTransactionAmt;

    private RelativeLayout relAddTransaction;

    private int status;

    public AddTransactionView(Context context, View anchorView, int marginTop,
        ViewGroup parentView, FriendsDAO mFriendsDAO) {
        super(context);
        Log.e(TAG, "AddTransactionView constructor");
        this.context = context;
        this.parentView = parentView;
        this.mFriendsDAO = mFriendsDAO;
        doInitialization();
        LayoutInflater inflater = (LayoutInflater) context
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View view = inflater.inflate(R.layout.add_transaction_popup, this);

        RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
            RelativeLayout.LayoutParams.MATCH_PARENT,
            RelativeLayout.LayoutParams.MATCH_PARENT);

        params.addRule(RelativeLayout.ABOVE, anchorView.getId());
        params.setMargins(0, marginTop, 0, 0);
        view.setLayoutParams(params);
        this.setFocusableInTouchMode(true);
        this.requestFocus();
        parentView.addView(this);
        initializeView(view, mFriendsDAO);
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        Log.e(TAG, "onKeyCodeDown");
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            Log.e(TAG, "onKeyCodeDown if");
            Log.e(TAG, "onKeyCodeDown else");
            dismiss();
            return true;
        } else {
            Log.e(TAG, "onKeyCodeDown default");
            return super.onKeyDown(keyCode, event);
        }
    }

    private void dismiss() {
        parentView.removeView(this);
    }
}

PS:由于我的应用程序设计限制,我没有使用对话框或弹出窗口。

更新1

键盘关闭时,焦点不会切换回我的自定义视图。我尝试了下面的建议答案,但我发现,当键盘被解除时,android不会发送IME事件。在键盘解雇后,还有其他方法可以将焦点恢复到我的视野吗?

更新2 刚才,我发现edittext的onKeyListener只是在我第二次按回按钮之后才启动,那是在解雇键盘之后。这就是为什么下面的解决方案无效。

2 个答案:

答案 0 :(得分:13)

我终于解决了我的问题,解决方法是使用dispatchKeyEventPreIme。以下是我的实际代码片段:

@Override
public boolean dispatchKeyEventPreIme(KeyEvent event) {
    Log.e(TAG, "dispatchKeyEventPreIme(" + event + ")");
    if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
        KeyEvent.DispatcherState state = getKeyDispatcherState();
        if (state != null) {
            Log.e(TAG, "dispatchKeyEventPreIme state != null");
            if (event.getAction() == KeyEvent.ACTION_DOWN
                    && event.getRepeatCount() == 0) {
                Log.e(TAG, "dispatchKeyEventPreIme ACTION_DOWN");
                state.startTracking(event, this);
                return true;
            } else if (event.getAction() == KeyEvent.ACTION_UP
                    && !event.isCanceled() && state.isTracking(event)) {
                Log.e(TAG, "dispatchKeyEventPreIme ACTION_UP");
                if (edtTransactionAmt.hasFocus()
                        || edtTransactionDesc.hasFocus()) {
                    Log.e(TAG, "dispatchKeyEventPreIme edittext has focus");
                    AppUtils.hideSoftKeyboard(context, edtTransactionAmt);
                    edtTransactionAmt.clearFocus();
                    edtTransactionDesc.clearFocus();
                } else {
                    Log.e(TAG, "dispatchKeyEventPreIme dismiss view");
                    dismiss();
                }
                return true;
            }
        }
    }

    return super.dispatchKeyEventPreIme(event);
}

但实际的功劳归于this post

答案 1 :(得分:-1)

您是否可以使用

在主要活动中进行反击
if (myAddTransactionView.getVisibility == LinearLayout.VISIBLE) {
     myAddTransactionView.dismiss();
} else {
   Super.....

或编辑文字

edtTransactionDesc.setOnKeyListener(new OnKeyListener()
{
    public boolean onKey(View v, int keyCode, KeyEvent event)
    {
        if (event.getAction() == KeyEvent.ACTION_DOWN)
        {
            //check if the right key was pressed
            if (keyCode == KeyEvent.KEYCODE_BACK)
            {
                InputMethodManager imm = (InputMethodManager)getSystemService(
                 Context.INPUT_METHOD_SERVICE);
                imm.hideSoftInputFromWindow(edtTransactionDesc.getWindowToken(), 0);
                AddTransactionView.this.requestFocus(); 
                return false;
            }
        }
        return true;
    }
});