5

我已经实现了一个自定义操作栏布局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
                              )
                             );
  }
}

我的活动只是一个ActionBarActivity将片段加载到FrameLayout. 这是片段代码:

@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;
}

这是操作栏布局:

<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>

这是两个按钮:

<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>

<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>

这是 Jelly Bean vs. Gingerbread 的结果(第一个是 Galaxy Nexus,后者是模拟器):

ActionBar 与 Gingerbread 重叠错误兼容

对不起质量,动画 PNG 不能正常工作,所以我切换到动画 GIF。

如您所见,内容布局超出了操作栏自定义布局(注意 JB 中的蓝色溢出和滚动条位置)。

使用非自定义操作栏布局在 JB 和 GB 上都可以正常工作。

4

1 回答 1

1

覆盖是由于在不同版本的 Android 中用于引用内容视图的不同资源 id 引起的。有关详细信息,请参阅Shellom 的帖子。同时,以下代码段应该可以帮助您识别代码的相关部分。

// 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;
}

更新:不再需要交换机。您可以将appcompat-v7 更新到修订版 19.0.0。或更新,然后android.R.id.content在所有 Android 版本上引用。

于 2013-11-09T23:24:59.150 回答