2013-02-07 14 views
7

Voglio creare una classe che estende AlertDialog.Builder:Estende AlertDialog.Builder in Android

public class AlertBuilder extends AlertDialog.Builder { 

    private MultiAdapter mAdapter; 
    private ListView lv; 
    private Activity mActivity; 
    private Context mContext; 
    private CheckedTxtView checkedItem; 

    public AlertBuilder(Context context, Activity activity, final List<CheckedTxtView> mList) { 
     super(context); 
     this.mActivity = activity; 
     this.mContext = context; 

     this.setTitle("Test"); 
     LayoutInflater inflater = activity.getLayoutInflater(); 
     View dialoglayout = inflater.inflate(R.layout.main_filter, null); 
     this.setView(dialoglayout); 

     mAdapter = new MultiAdapter(context, mList); 
     lv = (ListView) dialoglayout.findViewById(R.id.list); 
     lv.setAdapter(mAdapter); 
     lv.setOnItemClickListener(new ItemClick()); 
    } 

    class ItemClick implements OnItemClickListener { 
     public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 
      checkedItem = mAdapter.mItems.get(position);; 
      mAdapter.notifyDataSetChanged(); 
     } 
    } 

    private class MultiAdapter extends ArrayAdapter<CheckedTxtView> { 

     private List<CheckedTxtView> mItems; 

     public MultiAdapter(Context context, List<CheckedTxtView> mList) { 
      super(context, R.layout.list2, mList); 
      this.mItems = mList; 
     } 

     @Override 
     public View getView(int position, View convertView, ViewGroup parent) { 

      View row; 

      if (convertView == null) { 
       LayoutInflater inflater = mActivity.getLayoutInflater(); 
       row = inflater.inflate(R.layout.list2, parent, false); 
      } else 
       row = convertView; 

      CheckedTextView txt = (CheckedTextView) row.findViewById(R.id.label); 

      CheckedTxtView c = mItems.get(position); 

      System.out.println(c.item); 

      txt.setText(c.item); 
      if(checkedItem != null && checkedItem.item != null) 
       txt.setChecked(c.item.equals(checkedItem.item)); 

      return row; 
     } 
    } 

Poi lo uso nella mia attività:

public class MainActivity extends Activity { 

    private List<CheckedTxtView> mList; 
    private AlertDialog mAlert; 
    private AlertDialog.Builder mAlertBuilder; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     mList = new ArrayList<CheckedTxtView>(); 
     for(int i=0; i<30; i++) { 
      CheckedTxtView c = new CheckedTxtView(); 
      c.item = "item " + i; 
      mList.add(c); 
     } 

     mAlertBuilder = new AlertBuilder(getApplicationContext(), this, mList); 
     mAlert = mAlertBuilder.create(); 

     Button mButton = (Button) this.findViewById(R.id.mButton); 
     mButton.setOnClickListener(new View.OnClickListener() { 
      public void onClick(View v) { 
       mAlert.show(); 
      } 
     }); 
    } 
} 

ottengo questo errore nella console:

02-07 13:33:05.641: E/AndroidRuntime(12557): FATAL EXCEPTION: main 
02-07 13:33:05.641: E/AndroidRuntime(12557): android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application 
02-07 13:33:05.641: E/AndroidRuntime(12557): at android.view.ViewRoot.setView(ViewRoot.java:566) 
02-07 13:33:05.641: E/AndroidRuntime(12557): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:179) 
02-07 13:33:05.641: E/AndroidRuntime(12557): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91) 
02-07 13:33:05.641: E/AndroidRuntime(12557): at android.app.Dialog.show(Dialog.java:265) 
02-07 13:33:05.641: E/AndroidRuntime(12557): at com.example.testdialog.MainActivity$1.onClick(MainActivity.java:35) 
02-07 13:33:05.641: E/AndroidRuntime(12557): at android.view.View.performClick(View.java:2533) 
02-07 13:33:05.641: E/AndroidRuntime(12557): at android.view.View$PerformClick.run(View.java:9320) 
02-07 13:33:05.641: E/AndroidRuntime(12557): at android.os.Handler.handleCallback(Handler.java:587) 
02-07 13:33:05.641: E/AndroidRuntime(12557): at android.os.Handler.dispatchMessage(Handler.java:92) 
02-07 13:33:05.641: E/AndroidRuntime(12557): at android.os.Looper.loop(Looper.java:150) 
02-07 13:33:05.641: E/AndroidRuntime(12557): at android.app.ActivityThread.main(ActivityThread.java:4385) 
02-07 13:33:05.641: E/AndroidRuntime(12557): at java.lang.reflect.Method.invokeNative(Native Method) 
02-07 13:33:05.641: E/AndroidRuntime(12557): at java.lang.reflect.Method.invoke(Method.java:507) 
02-07 13:33:05.641: E/AndroidRuntime(12557): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:849) 
02-07 13:33:05.641: E/AndroidRuntime(12557): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:607) 
02-07 13:33:05.641: E/AndroidRuntime(12557): at dalvik.system.NativeStart.main(Native Method) 

Mi può mancare qualcosa qui. Mi potete aiutare?

+1

o semplicemente prova dopo il cambiamento 'super (contesto);' a 'super (attività);' perché stai già inviando il contesto attività alla classe AlertBuilder –

risposta

2

Invece di getApplicationContext() utilizzare questo o MainActivity.this.

mAlertBuilder = new AlertBuilder(this, this, mList); 
2

Non si dovrebbe passare contesto dell'applicazione qui:

mAlertBuilder = new AlertBuilder(getApplicationContext(), this, mList); 

Poiché l'attività è contesto stesso, si dovrebbe cambiare il vostro costruttore di prendere una sola paramater - Attività, che può essere usato come un oggetto Context dopo.

+0

Hai ragione. +1 punto. – Ali