2012-05-25 1 views
21

Sto lavorando su un'app per Android e ho una sottoclasse di AlertDialog. Vorrei mettere 2 ImageButtons sul lato destro dell'area del titolo della finestra di dialogo (simile a un ActionBar in un'attività). Sto usando setCustomTitle() per fare ciò, che sostituisce l'area del titolo con una vista personalizzata della mia creazione. Funziona bene, ma lo stile della mia area di titolo personalizzata non è lo stesso dello stile del titolo standard (altezza, colore, separatore, ecc.).AlertDialog setCustomTitle styling per abbinare il titolo standard AlertDialog

La mia domanda è: con la consapevolezza che lo stile varia a seconda versione del sistema operativo e produttore, come posso lo stile mio titolo personalizzato nella finestra di dialogo in modo che abbinerà lo stile titolo standard per le altre AlertDialogs?

Ecco un'immagine di anAlertDialog con uno stile standard (questo è da ICS, ma voglio essere in grado di adattarsi a qualsiasi variante - non questo particolare stile) enter image description here

E qui è l'immagine di un AlertDialog con titolo personalizzato e pulsanti (da notare come l'altezza del titolo e il colore non corrispondono il dialogo standard) enter image description here

EDIT: non posso aggiungere i ImageButtons alla visualizzazione titolo standard, perché io non ho accesso ad esso. Se si conosce un metodo (affidabile, non specifico) per aggiungere pulsanti all'area del titolo standard, lo accetterei anch'io.

risposta

10

Dato che c'è un nuovo interesse in questo QUESTI su, lasciatemi approfondire su come ho "risolto" questo.

In primo luogo, io uso ActionBarSherlock nella mia app. Questo non è necessario, suppongo, anche se aiuta molto perché gli stili e i temi definiti nel progetto ABS mi permettono di imitare il tema Holo su dispositivi pre-ICS, che fornisce un'esperienza coerente nell'app.

In secondo luogo, la mia "finestra di dialogo" non è più una finestra di dialogo: è un'attività a tema come una finestra di dialogo. Questo semplifica la manipolazione della gerarchia della vista, perché ho il controllo completo. Quindi aggiungere pulsanti all'area del titolo è ora banale.

Ecco gli screenshot (dispositivo 2.2 e emulatore 4.1). Si noti che l'unica differenza stilistica significativa è il EditText, che ho scelto di non indirizzare.

2.2 device 4.1 emulator

Ecco il mio onCreate nella mia finestra di attività:

public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    requestWindowFeature(Window.FEATURE_NO_TITLE); 

    setContentView(R.layout.activity_tag); 
    setTitle(R.string.tag_dialog_title); 

    View sherlockTitle = findViewById(android.R.id.title); 
    if (sherlockTitle != null) { 
     sherlockTitle.setVisibility(View.GONE); 
    } 
    View sherlockDivider = findViewById(R.id.abs__titleDivider); 
    if (sherlockDivider != null) { 
     sherlockDivider.setVisibility(View.GONE); 
    } 

    // setup custom title area 
    final View titleArea = findViewById(R.id.dialog_custom_title_area); 
    if (titleArea != null) { 
     titleArea.setVisibility(View.VISIBLE); 

     TextView titleView = (TextView) titleArea.findViewById(R.id.custom_title); 
     if (titleView != null) { 
      titleView.setText(R.string.tag_dialog_title); 
     } 

     ImageButton cancelBtn = (ImageButton) titleArea.findViewById(R.id.cancel_btn); 
     cancelBtn.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       finish(); 
      } 
     }); 
     cancelBtn.setVisibility(View.VISIBLE); 

     ImageButton okBtn = (ImageButton) titleArea.findViewById(R.id.ok_btn); 
     okBtn.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       // do stuff here 
       finish(); 
      } 
     }); 
     okBtn.setVisibility(View.VISIBLE); 
    } 
} 

E qui è il layout rilevante per l'attività:

<LinearLayout 
    android:orientation="vertical" 
    android:layout_height="fill_parent" 
    android:layout_width="fill_parent"> 
    <LinearLayout 
     android:id="@+id/dialog_custom_title_area" 
     android:orientation="vertical" 
     android:fitsSystemWindows="true" 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content"> 
     <LinearLayout 
      android:layout_width="fill_parent" 
      android:layout_height="wrap_content" 
      android:orientation="horizontal" 
      android:paddingRight="10dp"> 
      <TextView 
       android:id="@+id/custom_title" style="?android:attr/windowTitleStyle" 
       android:layout_width="0dp" 
       android:layout_height="wrap_content" 
       android:layout_weight="1" 
       android:minHeight="@dimen/abs__alert_dialog_title_height" 
       android:paddingLeft="16dip" 
       android:paddingRight="16dip" 
       android:textColor="#ffffff" 
       android:gravity="center_vertical|left" /> 

      <ImageButton 
       android:id="@+id/ok_btn" 
       android:layout_height="wrap_content" 
       android:layout_width="wrap_content" 
       android:minWidth="@dimen/abs__action_button_min_width" 
       android:minHeight="@dimen/abs__alert_dialog_title_height" 
       android:scaleType="center" 
       android:src="@drawable/ic_action_accept" 
       android:background="@drawable/abs__item_background_holo_dark" 
       android:visibility="visible" 
       android:layout_gravity="center_vertical" 
       android:contentDescription="@string/acc_done"/> 

      <ImageButton 
       android:id="@+id/cancel_btn" 
       android:layout_height="wrap_content" 
       android:layout_width="wrap_content" 
       android:minWidth="@dimen/abs__action_button_min_width" 
       android:minHeight="@dimen/abs__alert_dialog_title_height" 
       android:scaleType="center" 
       android:src="@drawable/ic_action_cancel" 
       android:background="@drawable/abs__item_background_holo_dark" 
       android:visibility="visible" 
       android:layout_gravity="center_vertical" 
       android:contentDescription="@string/acc_cancel" 
       /> 
     </LinearLayout> 
     <View 
      android:id="@+id/dialog_title_divider" 
      android:layout_width="fill_parent" 
      android:layout_height="2dip" 
      android:background="@color/abs__holo_blue_light" /> 
    </LinearLayout> 

    <RelativeLayout 
     android:id="@+id/list_suggestions_layout" 
     android:layout_height="wrap_content" 
     android:layout_width="fill_parent"> 

     <!-- this is where the main dialog area is laid out --> 

    </RelativeLayout> 

</LinearLayout> 

E, infine, nel mio AndroidManifext .xml, ecco come definisco la mia TagActivity:

<activity 
    android:icon="@drawable/ic_home" 
    android:name=".activity.TagActivity" 
    android:theme="@style/Theme.Sherlock.Dialog"/> 
-2

Va bene se si tratta solo di immagini, quindi è sufficiente assicurarsi che tutto ciò che si crea in xml sia ridimensionato per densità pixel o DP in breve. La maggior parte delle semplici codifiche che impostano la pittura sono generalmente impostate anche da pixel e potrebbe richiedere una versione di codifica manuale per i pixel di densità.

+0

Penso che tu abbia frainteso quello che sto cercando. Ho aggiunto alcuni collegamenti immagine per chiarezza. – mikejonesguy

+0

Spero che questa sia la risposta alla tua domanda. – sdfwer

+1

No, penso che tu stia ancora fraintendendo il problema. (Vedi la mia ultima modifica.) L'area del titolo della finestra di dialogo non mi è accessibile per ID, quindi non posso semplicemente aggiungere i miei pulsanti ad essa. Devo usare setCustomTitle (vista vista), che ** sostituisce ** l'area del titolo esistente. – mikejonesguy

0

OK, forse non è la soluzione super perfetta e forse è una cattiva soluzione, ma ho provato questo su Android 2.3.7 e Android 4.1.2:

2.3.7 (real device)

2.3.7 (real device)

4.1.2 (emulator)

4.1.2 (emulator)


Iniziamo creando uno stile Titolo finestra di dialogo per essere sicuri di avere un po 'di spazio per le nostre icone:

res/values/dialogstyles.xml

<?xml version="1.0" encoding="utf-8"?> 
<resources xmlns:android="http://schemas.android.com/apk/res/android"> 

    <style name="Dialog" parent="@android:style/Theme.Dialog"> 
     <item name="android:windowTitleStyle">@style/MyOwnDialogTitle</item> 
    </style> 

    <style name="MyOwnDialogTitle"> 
     <!-- we need to make sure our images fit --> 
     <item name="android:layout_marginRight">100dp</item> 
    </style> 

</resources> 

res/values-v11/dialogstyles.xml

<?xml version="1.0" encoding="utf-8"?> 
<resources xmlns:android="http://schemas.android.com/apk/res/android"> 

    <style name="Dialog" parent="@android:style/Theme.Holo.Dialog"> 
     <item name="android:windowTitleStyle">@style/MyOwnDialogTitle</item> 
    </style> 

</resources> 

Allora noi creiamo la nostra DialogFragment con due trucchi:

  • impostare lo stile nel onCreate:

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        setStyle(DialogFragment.STYLE_NORMAL, R.style.Dialog); 
    } 
    
  • esclusione onCreateView e aggiungere il nostro layout (di pulsanti) per la finestra di dialogo (vedi commenti)

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
        //we need the view to remove the tree observer (that's why it is final) 
        final View view = inflater.inflate(R.layout.dialog_custom, container); 
        getDialog().setTitle("Shush Dialog"); 
        //register a layout listener to add our buttons 
        view.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() { 
    
         @SuppressWarnings("deprecation") 
         @SuppressLint("NewApi") 
         @Override 
         public void onGlobalLayout() { 
          //inflate our buttons 
          View menu = LayoutInflater.from(getActivity()).inflate(R.layout.layout_mymenu, null); 
          //get the root view of the Dialog (I am pretty sure this is the weakest link) 
          FrameLayout fl = ((FrameLayout) getDialog().getWindow().getDecorView()); 
          //get the height of the root view (to estimate the height of the title) 
          int height = fl.getHeight() - fl.getPaddingTop() - fl.getPaddingBottom(); 
          //to estimate the height of the title, we subtract our view's height 
          //we are sure we have the heights btw because layout is done 
          height = height - view.getHeight(); 
          //prepare the layout params for our view (this includes setting its width) 
          //setting the height is not necessary if we ensure it is small 
          //we could even add some padding but anyway! 
          FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, height); 
          params.gravity = Gravity.RIGHT | Gravity.TOP; 
          //add the view and we are done 
          fl.addView(menu, params); 
          if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) 
           view.getViewTreeObserver().removeOnGlobalLayoutListener(this); 
          else 
           view.getViewTreeObserver().removeGlobalOnLayoutListener(this); 
         } 
        }); 
        return view; 
    }