Android Lollipop, AppCompat ActionBar 사용자 정의보기가 전체 화면 너비를 차지하지 않음


97

그래서 방금 코드베이스를 Lollipop으로 업데이트했는데 Action Bar에 문제가 있습니다. AppCompat 및 ActionBarActivity를 사용하고 있으며 사용자 지정보기를 확장하고 있습니다. 사용자 지정보기가 더 이상 화면의 전체 너비를 차지하지 않고 왼쪽에 얇은 띠가 남는 것 같습니다.

19로 건물 예전 모습

21로 건물 지금 모습

이것은 액션 바를 설정하는 데 사용하는 코드입니다. 누구나 아이디어가 있습니까?

final ActionBar actionBar = getSupportActionBar();
if(actionBar != null) {
    actionBar.setDisplayHomeAsUpEnabled(false);
    actionBar.setDisplayShowHomeEnabled(false);
    actionBar.setDisplayShowTitleEnabled(false);
    actionBar.setDisplayShowCustomEnabled(true);
    actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
    actionBar.setCustomView(R.layout.action_bar_content_search_custom_view);
    actionBar.setBackgroundDrawable(null);
    // actionBar.setStackedBackgroundDrawable(null);
    TextView title = (TextView) actionBar.getCustomView().findViewById(R.id.action_bar_title);
    title.setText(R.string.youtube);
    ImageView back = (ImageView) actionBar.getCustomView().findViewById(R.id.action_bar_back);
    back.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            finish();
        }
    });
}

편집하다

사용자 정의보기를 꺼내고 배경을 변경하면 이제 전체 너비를 차지합니다. 그래서 문제는 CustomView가 ActionBar의 전체 너비를 차지하도록 어떻게 만들 수 있습니까?


사용자 정의보기 부분을 일시적으로 주석 처리하면 더 잘 작동합니까? 그렇지 않다면 나는 아마도 당신의 주제에서 오는 이것에 의지 할 것입니다.
CommonsWare

사용자 정의보기를 제거하고 배경을 ActionBar의 배경 드로어
블로 설정

사용자 지정보기가있는 경우와없는 경우 모두 계층보기에서 활동을 살펴보고 사용자 지정보기의 결과로 어떤 레이아웃 규칙이 변경되는지 확인할 수 있습니다. 새로운 .NET의 버그 일 가능성이 appcompat-v7있습니다.
CommonsWare

나를 위해 예약 된 장소 인 것 같습니다 ImageView. 우선 비활성화하십시오.
Nikola Despotoski

1
안녕하세요, 커스텀 뷰가 전체 너비를 차지하도록하는 것이 좋은 솔루션 인 것 같습니다. 레이아웃 가중치가 설정되어 있어도 확장되지 않는 것을 경험했습니다. 여기를 참조하십시오 : stackoverflow.com/a/20794736/581574
ratana

답변:


111

ActionBar최근 appcompat-v7업데이트 의 에 대한 최신 변경 사항으로 인해 발생한 것 같습니다 . 작업 표시 줄을 처리하는 방법이 크게 변경된 것 같습니다.

나는 같은 문제에 직면했고 ActionBar문서를 읽은 후 특히 다음 인용문 을 읽고 해결책을 찾았습니다.

Android L (API 레벨 21)부터 작업 표시 줄은 애플리케이션 레이아웃 내의 툴바 위젯으로 표시 될 수 있습니다. 애플리케이션은 툴바를 활동의 작업 표시 줄로 처리해야하는 활동에 신호를 보낼 수 있습니다. 이 기능을 사용하는 활동은 제공된 .NoActionBar 테마 중 하나를 사용하고 windowActionBar 속성을 false로 설정하거나 그렇지 않으면 창 기능을 요청하지 않아야합니다.

내가 보는 방식으로 AppCompat테마가 변경되었고 한편으로는 몇 가지를 깨뜨리는 것처럼 보였지만 다른 한편으로는 훨씬 더 많은 유연성을 제공합니다. 다음 단계를 따르는 것이 좋습니다.

  1. .NoActionBar위 인용문에 설명 된대로 활동에 스타일을 사용하십시오.
  2. android.support.v7.widget.Toolbar활동 레이아웃에 추가
  3. app:contentInsetStart="0dp"속성을 설정 합니다. 이것은 귀하의 질문에서 설명하는 여백의 주요 문제입니다.
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/actionBar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:contentInsetEnd="0dp"
    app:contentInsetStart="0dp" >
</android.support.v7.widget.Toolbar>

일반적으로 별도의 레이아웃 파일에서 수행하고 include활동 레이아웃에서 사용하는 것이 좋습니다. 따라서 여러 활동에서 사용하는 경우 한 곳에서 도구 모음을 사용자 정의하면됩니다.

<include layout="@layout/view_action_bar" />
  1. 사용 findViewByIdsetSupportActionBar활동 onCreate에서signal to the Activity which Toolbar should be treated as the Activity's action bar
Toolbar actionBar = (Toolbar) findViewById(R.id.actionBar);
setSupportActionBar(actionBar);
  1. 이렇게하면 추가 된 모든 작업 onCreateOptionsMenu이 도구 모음에 추가되고 활동 작업 표시 줄로 처리됩니다.
  2. 원하는대로 도구 모음을 추가로 사용자 지정합니다 (하위보기 추가 등).

1
탐색 창과 함께 툴바를 사용하려고하는데 오류가 발생합니다Error inflating class fragment
Ahmed Nawaz

모든 관련 코드가 답변에 공유됩니다. 케이스가 다른 문제인 것 같으므로 새 질문을 시작해야하는 것 같습니다.
Muzikant

감사. 액션 바를 툴바로 대체하여 문제를 해결했습니다.
Ahmed Nawaz 2014 년

9
네임 스페이스 선언에 명시적인 패키지 이름을 사용해서는 안됩니다. 사용xmlns:app="http://schemas.android.com/apk/res-auto"
Liminal

1
에 대한 필요가 없습니다 setCustomView. 툴바에 포함하려는 위젯으로 레이아웃 파일을 빌드하기 만하면됩니다 (예 : 답변의 섹션 3에 설명 된 레이아웃 파일에 하위 뷰 추가)
Muzikant

51

Muzikant가 언급 하고이 답변 처럼 많은 일을하는 대신

    getSupportActionBar().setDisplayShowHomeEnabled(false);
    getSupportActionBar().setDisplayShowTitleEnabled(false);
    getSupportActionBar().setBackgroundDrawable(new ColorDrawable(Color.WHITE));
    LayoutInflater mInflater = LayoutInflater.from(this);

    View mCustomView = mInflater.inflate(R.layout.action_bar_home, null);
    getSupportActionBar().setCustomView(mCustomView);
    getSupportActionBar().setDisplayShowCustomEnabled(true);
    Toolbar parent =(Toolbar) mCustomView.getParent();//first get parent toolbar of current action bar 
    parent.setContentInsetsAbsolute(0,0);// set padding programmatically to 0dp

문제를 해결하려면 마지막 두 줄의 코드 만 추가하면됩니다.

이것이 당신과 다른 사람에게 도움이되기를 바랍니다.

업데이트 : 그것에 대해 조사한 후이 솔루션이 어떤 경우에는 작동하지 않는다는 것을 알았습니다. 이렇게하면 왼쪽 간격 (HOME 또는 BACK)이 제거되지만 오른쪽 간격 (MENU)은 그대로 유지됩니다. 다음은 이러한 경우에 대한 해결책입니다.

View v = getSupportActionBar().getCustomView();
LayoutParams lp = v.getLayoutParams();
lp.width = LayoutParams.MATCH_PARENT;
v.setLayoutParams(lp);

이 네 줄을 위의 코드에 추가하여 오른쪽 간격도 지원 작업 표시 줄에서 제거합니다.


감사! 감사! 마지막 두 줄은 ive가 찾고 있던 것입니다!
digitalmidges

이 줄을 어디에 추가합니까? 툴바 부분 이후?
Zen

1
@summers yes 도구 모음 코드 바로 뒤에 추가합니다.
Amrut Bidri

31

스타일에서도 할 수 있다고 생각합니다. 이 시도. kitkat에서 테스트했습니다.

<style name="AppTheme" parent="Theme.AppCompat">
  <item name="toolbarStyle">@style/AppThemeToolbar</item>
</style>

<style name="AppThemeToolbar" parent="Widget.AppCompat.Toolbar" >
  <item name="contentInsetStart">0dp</item>
</style>

1
이 대답은 잘못되었습니다. android : contentInsetStart는 API 레벨 21이 필요합니다 (현재 최소값은 14 임)
mr.boyfox 2014

그러나 관용구는 아주 좋습니다! API 21 및 이전 버전의 경우 별도의 쓰기 스타일이 필요합니다.
mr.boyfox 2014

여전히 기본 작업 표시 줄을 사용하는 경우 왼쪽 여백을 제거하는 정답입니다.
Tooroop 2014

이것은 실제로 작동합니다! 최신 버전의 지원 라이브러리를 사용하면 속성을 두 번 선언 할 필요가 없다고 생각합니다 (안드로이드는 필요하지 않음).
BoD

나는이 문제를 찾고 있었고 당신의 대답을 찾았을 때 나는 이미 그것을 찬성했다는 것을 알았습니다! 두 번 감사합니다.
user1732313

8

다른 답변 중 어느 것도 나를 위해 일하지 않았으므로 여기 에있는 실제 AppCompat v7 스타일을 살펴 보았습니다 .

Base.Widget.AppCompat.ActionBar 스타일을 보면 다음과 같습니다.

<item name="contentInsetStart">@dimen/abc_action_bar_content_inset_material</item>
<item name="contentInsetEnd">@dimen/abc_action_bar_content_inset_material</item>

그래서 분명히 우리는 우리의 액션 바 스타일로 그 속성들을 덮어 쓰기 만하면됩니다 :

<style name="ActionBar" parent="@style/Base.Widget.AppCompat.ActionBar">
        <item name="contentInsetStart">0dp</item>
        <item name="contentInsetEnd">0dp</item>
</style>

이것은 나를 위해 잘 작동했으며 다른 사람들에게도 도움이되기를 바랍니다.


네, 선택한 답변에서 알 수 있듯이 핵심은 ActionBar / Toolbar의 contentInsetStart 및 contentInsetEnd 속성입니다. 그것은 자신 만의 스타일을 정의하는 것이 유효하지만 당신은 또한 그들이 당신 XML의 도구 모음의 속성에 0dp 설정할 수 있습니다
스티비 Kideckel

1

내 머리를 모니터에 대고 많이 치고 난 후, 이것은 나를 위해 일했습니다.

 Toolbar toolbar = (Toolbar) actionBar.getCustomView().getParent();
        toolbar.setContentInsetStartWithNavigation(0);
        toolbar.setContentInsetEndWithActions(0);
        toolbar.setContentInsetsAbsolute(0, 0);
        toolbar.setPadding(0, 0, 0, 0);

getCustomView (). getParent ()가 트릭을 한 것입니다.


0

오늘도이 문제 res/values-v21/styles.xml가 발생했고 Android Studio에서 자동으로 생성 된 프로젝트 내부에있는 것이 원인이라는 것을 알게되었습니다.

왜?

res/values-v21/styles.xml콘텐츠가 다음과 같았 기 때문입니다.

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style name="BaseAppTheme" parent="android:Theme.Material.Light">
    </style>
</resources>

그리고 내 res/values/styles.xml포함 된 내용은 다음과 같습니다.

<style name="BaseAppTheme" parent="android:Theme.Holo.Light">
    <!-- Customize your theme here. -->
    <item name="android:windowContentOverlay">@null</item>
    <item name="android:soundEffectsEnabled">false</item>
</style>

그런 다음 Lollipop에서 내 앱을 실행했을 때 res/values-v21/styles.xml를 사용했고 OP가 가진 정확한 문제를 일으켰습니다. 그래서 간단한 수정은 그냥 삭제하는 것입니다.

    <style name="BaseAppTheme" parent="android:Theme.Material.Light">
    </style>

res/values-v21/styles.xml


0

요점 :

 ActionBar actionBar = getSupportActionBar();
                actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
                actionBar.setCustomView(R.layout.actionbar_layout);
                Toolbar toolbar = (Toolbar) actionBar.getCustomView().getParent();
                    toolbar.setContentInsetsAbsolute(0, 0);
                    toolbar.setPadding(0, 0, 0, 0);

올바른 도구 모음을 가져와야합니다. android.support.v7.widget.Toolbar;


0

코드와 함께이 두 줄을 작성하십시오.

Toolbar toolbar=(Toolbar)viewActionBar.getParent();
toolbar.setContentInsetsAbsolute(0,0);
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.