2010-12-29 6 views
3

私はListActivityを使用してアイテムのリストを表示します。ユーザは、リスト内の項目を長押ししてコンテキストメニューを表示することができる。このメニューには、長押しアイテムを削除するオプションがあります。ユーザーがこのオプションを選択すると、削除の確認を求めるダイアログが表示されます。確認後、その項目はリストから削除されます。AlertDialogsを再利用してActivityListのアイテムのコンテキストメニューのアクションを確認する方法を提案する

可能な限りAlertDialogを再利用したいと思います。 onPrepareDialog(int, View, Bundle)を使用しようとした私の試みは、BundleDialogInterface.OnClickListenerに渡されないという事実によって打ち負かされました。私はすべての呼び出しでリスナーを再作成する必要があります。

私はこれを解決するために、いくつかの方法を参照してください。

  • ListActivity上のフィールドでDialogInterface.OnClickListenerを維持したい項目を保つ

    1. は(::シンプル、短所無駄な長所は)あらゆる機会にダイアログを再作成リスナーのフィールドとして削除されます。 (賛否:メモリの無駄、短所:状態の管理が必要)。 Q:これは安全ですか?
    2. onPrepareDialogがあり、AlertDialogのボタンに新しいView.OnClickListenerをバインドします。 (プロ:制限無し、短所:すべての呼び出しで新しいView.OnClickListener)。

    DialogInterface.OnClickListenerBundleを受け入れた場合、私は、削除されている項目を追跡するためにフープを介してジャンプする必要はありません。

    これはブロッカーではありませんが、私は洗練されたソリューションを見たいと思います。私はあなたの提案を聞くのが大好きだ:)ここ

    は、あなたがこれをプレイしたい場合は、オプション#1のコードです:

    public class Example extends ListActivity { 
        private static final int CONFIRM_DELETE_DIALOG = 1; 
        private static final String POSITION_KEY = "position"; 
    
        private ArrayAdapter<String> mAdapter; 
    
        @Override 
        public void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        mAdapter = new ArrayAdapter<String>(
         this, android.R.layout.simple_list_item_1, 
         new String[] { "one", "two" }); 
        setListAdapter(mAdapter); 
        registerForContextMenu(getListView()); 
        } 
    
        @Override 
        public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { 
        super.onCreateContextMenu(menu, v, menuInfo); 
        getMenuInflater().inflate(R.menu.my_lovely_menu, menu); 
        } 
    
        @Override 
        public boolean onContextItemSelected(MenuItem item) { 
        AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo(); 
        switch (item.getItemId()) { 
        case R.id.delete_item: 
         Bundle bundle = new Bundle(); 
         bundle.putInt(POSITION_KEY, info.position); 
         showDialog(CONFIRM_DELETE_DIALOG, bundle); 
         return true; 
        default: 
         return super.onContextItemSelected(item); 
        } 
        } 
    
        @Override 
        protected Dialog onCreateDialog(int id, Bundle args) { 
        switch (id) { 
        case CONFIRM_DELETE_DIALOG: 
         final int position = args.getInt(POSITION_KEY); 
         AlertDialog.Builder builder = new AlertDialog.Builder(); 
         builder.setCancelable(false); 
         builder.setTitle(String.format(
          getString(R.string.confirm_delete), mAdapter.getItem(position))); 
         DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() { 
         public void onClick(DialogInterface dialog, int which) { 
          switch (which) { 
          case DialogInterface.BUTTON_POSITIVE: 
          mAdapter.remove(mAdapter.getItem(position)); 
          // Dismiss the dialog to ensure OnDismissListeners are notified. 
          dialog.dismiss(); 
          break; 
          case DialogInterface.BUTTON_NEGATIVE: 
          // Cancel the dialog to ensure OnCancelListeners are notified. 
          dialog.cancel(); 
          break; 
          } 
          // Remove the dialog so it is re-created next time it is required. 
          removeDialog(CONFIRM_DELETE_DIALOG); 
         } 
         }; 
         builder.setPositiveButton(android.R.string.yes, listener); 
         builder.setNegativeButton(android.R.string.no, listener); 
         return builder.create(); 
        default: 
         return super.onCreateDialog(id, args); 
        } 
        } 
    } 
    
  • +0

    私はあなたがユーザーLO新しいダイアログを毎回作成を検討理由をお聞きしたいのですが無駄なアイテムを押す。一般的に、ダイアログとは、ダイアログが破壊されメモリから消去された時点で結果が得られるまでユーザーが対話することを強制されます。したがって、常に1つしか存在しません。この場合、あなたは何を無駄にしていますか? – user432209

    +0

    ハンドヘルドデバイスではメモリが貴重なので、スピードは重要です。ダイアログは、再利用されることを意図しています。つまり、onPrepareDialogの目的です。新しいダイアログを作成するたびに、オブジェクトの大部分を再利用するのではなく、オブジェクトの束を割り当てます。これらのオブジェクトは後でガベージコレクションされる必要があります。私はこれらのダイアログに必要な作業を最小限に抑えようとしています。私が言ったように、これはブロッカーではありませんが、より洗練されたソリューションを探したいと思います。 – Ozone

    答えて

    0

    私はオプション1、またはそれに非常に近い何かが、だと思います利用可能な最も洗練されたソリューションである可能性があります。

    オプション1とサンプルコードは有効ですが、ダイアログボックスをsetCancelable(true)に変更してパターンを誤って使用する可能性があります。その場合は、[戻る]ボタンを使用してダイアログを閉じることができるので、removeDialog(CONFIRM_DELETE_DIALOG)をスキップします。そうすると次回はダイアログが開き、誤った位置に表示される可能性があります。 、

    protected void onPrepareDialog(int id, Dialog dialog, Bundle args) { 
        switch (id) { 
        case CONFIRM_DELETE_DIALOG: 
         dialog.setOnDismissListener(new DialogInterface.OnDismissListener() { 
          public void onDismiss(DialogInterface dialog) { 
           removeDialog(CONFIRM_DELETE_DIALOG); 
          } 
         }); 
         break; 
        default: 
         super.onPrepareDialog(id, dialog, args); 
        } 
    } 
    

    代替onPrepareDialogの使用を避ける:

    はそのために、私はオプション1のアプローチはonPrepareDialogに設定し、DialogInterface.OnDismissListeneronCreateDialogDialogInterface.onClickListenerからremoveDialog(CONFIRM_DELETE_DIALOG)を再配置するように調整されるべきだと思います、onCreateDialogDialogInterface.OnDismissListenerをバインドすることです:

    Dialog dialog = builder.create(); 
        dialog.setOnDismissListener(new DialogInterface.OnDismissListener() { 
         public void onDismiss(DialogInterface dialog) { 
          removeDialog(CONFIRM_DELETE_DIALOG); 
         } 
        }); 
        return dialog; 
    
    関連する問題