在DialogFragment上处理后退行为的最佳方法是什么?

时间:2013-12-17 09:02:47

标签: android android-dialogfragment

所以我有一个DialogFragment显示区域选择列表。用户单击该区域后,列表将重新获取数据以显示街道选择列表。此时,我想让用户按下硬件返回按钮返回区域选择。这可能吗?我试图覆盖下面的一些方法,但我只能点击事件,但不能阻止它发生。

@Override
public void onCancel(DialogInterface dialog) {
    if(isDismissable()){
        super.onCancel(dialog);
    }else {
        Log.d(TAG, "Don't dismiss cancel this dialog!");
    }
}

@Override
public void dismissAllowingStateLoss() {
    if(isDismissable()){
        super.dismissAllowingStateLoss();
    }else {
        Log.d(TAG, "Don't dismiss this dialog!");
    }
}

@Override
public void dismiss() {
    if(isDismissable()){
        super.dismiss();
    }else {
        Log.d(TAG, "Don't dismiss this dialog!");
    }
}
当用户按下后退按钮时,

dismiss()被调用,但即使我不调用super.dismiss(),对话也会被解雇。

有办法做到这一点吗?我还会调查 Google + 应用如何在DialogFragment中显示ActionBar以提供HomeAsUp,但我找不到任何相关信息。

3 个答案:

答案 0 :(得分:5)

我看到两个解决方案:

最简单:将区域选择和街道选择列表作为单独的通常片段,并将它们都放在单独的活动中,并将此活动作为通过简单主题的对话框进行: <activity android:theme="@android:style/Theme.Dialog" /> excludeFromRecents="true"并且addToBackStack(null)在最近使用的应用中没有此功能。 首先加载区域选择,然后通过AreaSelection添加街道选择,这样您下方就会有AreaFragment个片段。

如果您不希望因任何原因为此创建单独的活动,则可以从对话框片段添加对话框侦听器,其实现者(活动)将打开import com.example.adip.fragments.AreaSelectionFragment; import com.example.adip.fragments.StreetSelectionFragment; import com.example.adip.fragments.AreaSelectionFragment.AreaSelectionListener; import com.example.adip.fragments.StreetSelectionFragment.StreetSelectionListener; import android.os.Bundle; import android.support.v4.app.DialogFragment; import android.support.v4.app.FragmentActivity; import android.view.View; import android.view.View.OnClickListener; public class DialogsActivity extends FragmentActivity implements OnClickListener, AreaSelectionListener, StreetSelectionListener { private static final String AREA_TAG = "AREA_TAG"; private static final String STREETS_TAG = "STREETS_TAG"; @Override protected void onCreate(Bundle savedInstance) { super.onCreate(savedInstance); setContentView(R.layout.area_selections); findViewById(R.id.btnStuff).setOnClickListener(this); } @Override public void onClick(View v) { showArea(); } private void showArea() { DialogFragment df = new AreaSelectionFragment(); df.show(getSupportFragmentManager(), AREA_TAG); } @Override public void onStreetsUserCanceled() { showArea(); } @Override public void showStreets() { DialogFragment df = new StreetSelectionFragment(); df.show(getSupportFragmentManager(), STREETS_TAG); } } 。基本了解您的代码,这个简单的项目应该这样做:

所有者活动:

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;

public class AreaSelectionFragment extends DialogFragment {
    public static interface AreaSelectionListener {
        void showStreets();
    }

    private AreaSelectionListener areaSelectionListener;

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        if (activity instanceof AreaSelectionListener) {
            areaSelectionListener = (AreaSelectionListener) activity;
        } else {
            throw new ClassCastException("Parent Activity must implement AreaSelectionListener");
        }
    }

    @Override
    public void onDetach() {
        super.onDetach();
        areaSelectionListener = null;
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        return new AlertDialog.Builder(getActivity()).setTitle("Area Selection")
                .setPositiveButton("OK", new OnClickListener() {

                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        areaSelectionListener.showStreets();
                    }
                }).setNegativeButton("Cancel", null).create();
    }
}

AreaSelectionFragment(根据您的需要扩展):

StreetSelectionFragment

import android.app.Activity; import android.app.AlertDialog; import android.app.Dialog; import android.content.DialogInterface; import android.content.DialogInterface.OnClickListener; import android.os.Bundle; import android.support.v4.app.DialogFragment; public class StreetSelectionFragment extends DialogFragment { public static interface StreetSelectionListener { void onStreetsUserCanceled(); } private StreetSelectionListener selectionListener; @Override public void onAttach(Activity activity) { super.onAttach(activity); if (activity instanceof StreetSelectionListener) { selectionListener = (StreetSelectionListener) activity; } else { throw new ClassCastException("Parent activity must implement StreetSelectionListener"); } } @Override public void onDetach() { selectionListener = null; super.onDetach(); } @Override public Dialog onCreateDialog(Bundle savedInstanceState) { Dialog dialog = new AlertDialog.Builder(getActivity()).setTitle("Street Selection") .setPositiveButton("OK", null).setNegativeButton("Cancel", new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { selectionListener.onStreetsUserCanceled(); } }).create(); return dialog; } @Override public void onCancel(DialogInterface dialog) { super.onCancel(dialog); selectionListener.onStreetsUserCanceled(); } } (再次:根据您的需要扩展):

{{1}}

答案 1 :(得分:3)

  

在DialogFragment上处理反向行为的最佳方法是什么?

处理DialogFragment上的后退行为的最佳方法是不要弄乱它并保持原样,在此过程中重新思考当前的方法。如果我在应用程序中看到一个对话框并且我正在回击我希望将对话框弹出屏幕并且不能在对话框的页面之间导航(我希望我没有误读你的问题。)

  

有办法做到这一点吗?

在您的DialogFragment中,您可以使用自定义Dialog(我假设您只是使用onCreateDialog()回调来返回带有列表的Dialog)你覆盖onKeyDown()回调来处理后面被按下的东西:

public class CustomDialog extends Dialog {

    protected CustomDialog(Context context) {
        super(context);
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {
            // the back key was pressed so do something?
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }

}
  

我还会了解Google+应用如何显示ActionBar   DialogFragment提供HomeAsUp,但我找不到任何信息。

您始终可以使Activity看起来像Dialog

答案 2 :(得分:2)

The best way is to override onBackPressed() in the dialog , you created in onCreateDialog().
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    return new Dialog(getActivity(), getTheme()){
        @Override
        public void onBackPressed() {
            //do your stuff
        }
    };
}