Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4e8b78a2 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Remove divider lines from all PreferenceFragments."

parents 6d7e2ed0 4addb592
Loading
Loading
Loading
Loading
+24 −0
Original line number Diff line number Diff line
@@ -17,13 +17,20 @@
package com.android.settings.core;

import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.android.settings.core.instrumentation.Instrumentable;
import com.android.settings.core.instrumentation.MetricsFeatureProvider;
import com.android.settings.core.instrumentation.VisibilityLoggerMixin;
import com.android.settings.core.lifecycle.ObservablePreferenceFragment;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.widget.PreferenceDividerDecoration;

/**
 * Instrumented fragment that logs visibility state.
@@ -48,6 +55,9 @@ public abstract class InstrumentedPreferenceFragment extends ObservablePreferenc
    protected final int GESTURE_DOUBLE_TAP_SCREEN = PLACEHOLDER_METRIC + 11;
    protected final int GESTURE_DOUBLE_TWIST = PLACEHOLDER_METRIC + 12;

    private final PreferenceDividerDecoration mDividerDecoration =
            new PreferenceDividerDecoration();

    public InstrumentedPreferenceFragment() {
        // Mixin that logs visibility change for activity.
        getLifecycle().addObserver(new VisibilityLoggerMixin(getMetricsCategory()));
@@ -59,7 +69,21 @@ public abstract class InstrumentedPreferenceFragment extends ObservablePreferenc
        mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        final View view = super.onCreateView(inflater, container, savedInstanceState);
        getListView().addItemDecoration(mDividerDecoration);
        return view;
    }

    @Override
    public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
    }

    @Override
    public void setDivider(Drawable divider) {
        mDividerDecoration.setDivider(divider);
        super.setDivider(new ColorDrawable(Color.TRANSPARENT));
    }
}
+0 −13
Original line number Diff line number Diff line
@@ -17,9 +17,6 @@ package com.android.settings.dashboard;

import android.app.Activity;
import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.annotation.VisibleForTesting;
import android.support.v7.preference.Preference;
@@ -117,16 +114,6 @@ public abstract class DashboardFragment extends SettingsPreferenceFragment
        refreshAllPreferences(getLogTag());
    }

    @Override
    public void setDivider(Drawable divider) {
        if (mDashboardFeatureProvider.isEnabled()) {
            // Intercept divider and set it transparent so system divider decoration is disabled.
            super.setDivider(new ColorDrawable(Color.TRANSPARENT));
        } else {
            super.setDivider(divider);
        }
    }

    @Override
    public void onStart() {
        super.onStart();
+79 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.settings.widget;

import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.support.v4.view.ViewCompat;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceCategory;
import android.support.v7.preference.PreferenceGroupAdapter;
import android.support.v7.widget.RecyclerView;
import android.view.View;

public class PreferenceDividerDecoration extends RecyclerView.ItemDecoration {

    private Drawable mDivider;
    private int mDividerHeight;

    public void setDivider(Drawable divider) {
        if (divider != null) {
            mDividerHeight = divider.getIntrinsicHeight();
        } else {
            mDividerHeight = 0;
        }
        mDivider = divider;
    }

    public void setDividerHeight(int dividerHeight) {
        mDividerHeight = dividerHeight;
    }

    @Override
    public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
        if (mDivider == null) {
            return;
        }
        final int childCount = parent.getChildCount();
        final int width = parent.getWidth();
        for (int childViewIndex = 0; childViewIndex < childCount; childViewIndex++) {
            final View view = parent.getChildAt(childViewIndex);
            if (shouldDrawDividerAbove(view, parent)) {
                int top = (int) ViewCompat.getY(view);
                mDivider.setBounds(0, top, width, top + mDividerHeight);
                mDivider.draw(c);
            }
        }
    }

    private boolean shouldDrawDividerAbove(View view, RecyclerView parent) {
        final RecyclerView.Adapter adapter = parent.getAdapter();
        if (adapter == null || !(adapter instanceof PreferenceGroupAdapter)) {
            return false;
        }
        final PreferenceGroupAdapter prefAdapter = (PreferenceGroupAdapter) adapter;
        final int adapterPosition = parent.getChildAdapterPosition(view);
        if (adapterPosition == RecyclerView.NO_POSITION) {
            return false;
        }
        final Preference pref = prefAdapter.getItem(adapterPosition);
        if (pref instanceof PreferenceCategory) {
            return adapterPosition != 0;
        }
        return pref instanceof FooterPreference;
    }
}
+113 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.settings.widget;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceCategory;
import android.support.v7.preference.PreferenceGroupAdapter;
import android.support.v7.widget.RecyclerView;
import android.view.View;

import com.android.settings.SettingsRobolectricTestRunner;
import com.android.settings.TestConfig;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Answers;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.annotation.Config;

import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

@RunWith(SettingsRobolectricTestRunner.class)
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
public class PreferenceDividerDecorationTest {

    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
    private Context mContext;
    @Mock
    private Drawable mDrawable;
    @Mock
    private Canvas mCanvas;
    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
    private RecyclerView mRecyclerView;
    @Mock
    private PreferenceGroupAdapter mAdapter;
    @Mock
    private PreferenceCategory mPrefCategory;
    @Mock
    private Preference mNormalPref;
    @Mock
    private FooterPreference mFooterPref;
    private PreferenceDividerDecoration mDecoration;

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
        mDecoration = new PreferenceDividerDecoration();
        mDecoration.setDivider(mDrawable);
        mDecoration.setDividerHeight(3);
    }

    @Test
    public void drawOver_footerPreference_shouldDrawDivider() {
        when(mRecyclerView.getAdapter()).thenReturn(mAdapter);
        when(mRecyclerView.getChildCount()).thenReturn(1);
        when(mAdapter.getItem(anyInt())).thenReturn(mFooterPref);

        mDecoration.onDrawOver(mCanvas, mRecyclerView, null /* state */);

        verify(mDrawable).draw(mCanvas);
    }

    @Test
    public void drawOver_preferenceCategory_shouldSkipFirst() {
        when(mRecyclerView.getAdapter()).thenReturn(mAdapter);
        when(mRecyclerView.getChildCount()).thenReturn(3);
        when(mAdapter.getItem(anyInt())).thenReturn(mPrefCategory);
        when(mRecyclerView.getChildAdapterPosition(any(View.class)))
                .thenReturn(0)
                .thenReturn(1)
                .thenReturn(2);

        mDecoration.onDrawOver(mCanvas, mRecyclerView, null /* state */);

        // 3 prefCategory, should skip first draw
        verify(mDrawable, times(2)).draw(mCanvas);
    }

    @Test
    public void drawOver_preference_doNotDrawDivider() {
        when(mRecyclerView.getAdapter()).thenReturn(mAdapter);
        when(mRecyclerView.getChildCount()).thenReturn(1);
        when(mAdapter.getItem(anyInt())).thenReturn(mNormalPref);

        mDecoration.onDrawOver(mCanvas, mRecyclerView, null /* state */);

        verify(mDrawable, never()).draw(mCanvas);
    }
}