El diseño personalizado con ActionBar en appcompat hace que el contenido se superponga con la barra de acción

He implementado un diseño de barra de acción personalizada con AppCompat :

 public class DoneBarActivity { public interface OnSaveActionListener { public void onSave(); } public static void setupActionBar(final ActionBarActivity activity, final OnSaveActionListener listener) { // Inflate a "Done/Cancel" custom action bar view. final LayoutInflater inflater = (LayoutInflater) activity .getSupportActionBar().getThemedContext() .getSystemService(Context.LAYOUT_INFLATER_SERVICE); final View customActionBarView = inflater.inflate( R.layout.actionbar_custom_view_done_cancel, null); customActionBarView.findViewById(R.id.actionbar_done) .setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // "Done" (or "Save") if (listener != null) { listener.onSave(); } activity.finish(); } }); customActionBarView.findViewById(R.id.actionbar_cancel) .setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // "Cancel" activity.finish(); } }); // Show the custom action bar view and // hide the normal Home icon and title. final ActionBar actionBar = activity.getSupportActionBar(); actionBar.setDisplayOptions( ActionBar.DISPLAY_SHOW_CUSTOM, ActionBar.DISPLAY_SHOW_CUSTOM | ActionBar.DISPLAY_SHOW_HOME | ActionBar.DISPLAY_SHOW_TITLE); actionBar.setCustomView(customActionBarView, new ActionBar.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT ) ); } } 

Mi actividad es sólo una ActionBarActivity muda que carga un fragmento en un FrameLayout . Aquí está el código del fragmento:

 @Override public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) { // ... DoneBarActivity.setupActionBar((ActionBarActivity) getActivity(), new DoneBarActivity.OnSaveActionListener() { @Override public void onSave() { saveIssueChangesAndClose(); } }); return v; } 

Aquí está el diseño de la barra de acción:

 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" android:divider="?attr/dividerVertical" android:showDividers="middle" android:dividerPadding="12dp"> <include layout="@layout/include_cancel_button"/> <include layout="@layout/include_done_button"/> </LinearLayout> 

Aquí están los dos botones:

 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" style="?actionButtonStyle" android:id="@+id/actionbar_cancel" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1"> <TextView style="?actionBarTabTextStyle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:paddingRight="20dp" android:drawableLeft="@drawable/ic_action_cancel" android:drawablePadding="8dp" android:gravity="center_vertical" android:text="@android:string/cancel"/> </FrameLayout> 

y

 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" style="?actionButtonStyle" android:id="@+id/actionbar_done" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1"> <TextView style="?actionBarTabTextStyle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:paddingRight="20dp" android:drawableLeft="@drawable/ic_action_done" android:drawablePadding="8dp" android:gravity="center_vertical" android:text="@string/save"/> </FrameLayout> 

Aquí está el resultado en Jelly Bean vs Gingerbread (Galaxy Nexus para el primero, el emulador de este último):

ActionBar compat con el error de superposición de pan de jengibre

Lo siento por la calidad, el PNG animado no funcionó correctamente así que cambié a GIF animado.

Como se puede ver, el diseño del contenido va sobre el diseño personalizado de la barra de acciones (observe el desbordamiento azul en JB y la posición de la barra de desplazamiento).

El uso de un diseño de barra de acción no personalizada funciona correctamente en JB y GB.

La superposición se debe a la identificación de recursos utilizada para hacer referencia a la vista de contenido en diferentes versiones de Android. Consulte la publicación de Shellom para obtener información detallada . Mientras tanto, el fragmento siguiente le ayudará a identificar la parte relevante de su código.

 // http://code.google.com/p/android/issues/detail?id=58108 private static int getContentViewCompat() { return Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH ? android.R.id.content : R.id.action_bar_activity_content; } 

Actualización: el switch ya no es necesario. Puede actualizar appcompat-v7 a la revisión 19.0.0. O más reciente y luego referencia android.R.id.content en todas las versiones de Android.

  • AppCompat 23.2 utiliza VectorDrawableCompat con RemoteViews (AppWidget) en la API <21
  • Excepción de puntero nulo al utilizar SearchView con AppCompat
  • ¿Cómo escuchar el cambio de estado en el widget SwitchCompat?
  • Android.graphics.drawable.ColorDrawable no se puede convertir en android.support.v7.widget.RoundRectDrawableWithShadow
  • No puede resolver AppCompatActivity
  • NullPointerException en ActionBarImplICS (utilizando app compat) en una larga pulsación
  • No se pudo encontrar la clase 'android.widget.ThemedSpinnerAdapter'
  • Fragmento pila trasera no funciona cuando se extiende AppCompatActivity
  • No se pudo mostrar elementos con la biblioteca AppCompat
  • DialogFragment con AppCompatDialog se bloquea si se establece STYLE_NO_TITLE
  • La altura de ProgressBar de AppCompat
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.