Skip to content

Commit

Permalink
Popups now have a custom epicenter
Browse files Browse the repository at this point in the history
Tweaked spinner caret padding
  • Loading branch information
consp1racy committed Jan 19, 2017
1 parent 53c52e8 commit 503641d
Show file tree
Hide file tree
Showing 12 changed files with 244 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,16 @@
import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Rect;
import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.ArrayRes;
import android.support.annotation.IntDef;
import android.support.annotation.LayoutRes;
import android.support.annotation.NonNull;
import android.support.v7.preference.*;
import android.support.v4.view.ViewCompat;
import android.support.v7.preference.PreferenceViewHolder;
import android.support.v7.view.ContextThemeWrapper;
import android.text.TextUtils;
import android.util.AttributeSet;
Expand Down Expand Up @@ -82,6 +84,7 @@ private static boolean isSimpleMenuEnabled() {

private Context mPopupContext;

@SuppressWarnings("RestrictedApi")
public ListPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ListPreference, defStyleAttr, defStyleRes);
Expand Down Expand Up @@ -116,6 +119,7 @@ public ListPreference(Context context) {
this(context, null);
}

@SuppressWarnings("RestrictedApi")
@Override
protected void performClick(View view) {
switch (mMenuMode) {
Expand Down Expand Up @@ -192,6 +196,14 @@ private boolean showAsPopup(final View anchor, final boolean force) {
int preferredVerticalOffset = popup.getPreferredVerticalOffset(position);
popup.setVerticalOffset(preferredVerticalOffset);

final int unit = anchor.getHeight();
if (ViewCompat.getLayoutDirection(anchor) == ViewCompat.LAYOUT_DIRECTION_RTL) {
int width = anchor.getWidth();
popup.setEpicenterBounds(new Rect(width - unit, 0, width - unit * 2, unit));
} else {
popup.setEpicenterBounds(new Rect(unit, 0, unit * 2, unit));
}

// Testing.
// popup.setDropDownGravity(Gravity.LEFT);
// popup.setMaxWidth(XpListPopupWindow.MATCH_PARENT);
Expand Down Expand Up @@ -270,10 +282,12 @@ public SpinnerAdapter buildSimpleMenuAdapter(final Context context) {
* If you want to supply your own {@link SpinnerAdapter}
* override {@link #buildSimpleMenuAdapter(Context)}
* and {@link #buildSimpleDialogAdapter(Context)} instead.
*
* @param context
* @return
*/
@NonNull @Deprecated
@NonNull
@Deprecated
public SpinnerAdapter buildAdapter(final Context context) {
return buildAdapter(context, R.layout.asp_simple_spinner_dropdown_item);
}
Expand Down Expand Up @@ -342,8 +356,8 @@ public void setEntries(CharSequence[] entries) {
}

/**
* @see #setEntries(CharSequence[])
* @param entriesResId The entries array as a resource.
* @see #setEntries(CharSequence[])
*/
public void setEntries(@ArrayRes int entriesResId) {
this.setEntries(this.getContext().getResources().getTextArray(entriesResId));
Expand Down Expand Up @@ -374,8 +388,8 @@ public void setEntryValues(CharSequence[] entryValues) {
}

/**
* @see #setEntryValues(CharSequence[])
* @param entryValuesResId The entry values array as a resource.
* @see #setEntryValues(CharSequence[])
*/
public void setEntryValues(@ArrayRes int entryValuesResId) {
this.setEntryValues(this.getContext().getResources().getTextArray(entryValuesResId));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package android.support.v7.widget;

import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.ColorStateList;
Expand Down Expand Up @@ -54,6 +55,7 @@
*
* @hide
*/
@SuppressLint("AppCompatCustomView")
@TargetApi(23)
public abstract class AbstractXpAppCompatSpinner extends Spinner implements TintableBackgroundView {

Expand Down Expand Up @@ -196,6 +198,7 @@ public AbstractXpAppCompatSpinner(Context context, AttributeSet attrs, int defSt
* @see #MODE_DIALOG
* @see #MODE_DROPDOWN
*/
@SuppressWarnings("RestrictedApi")
public AbstractXpAppCompatSpinner(Context context, AttributeSet attrs, int defStyleAttr, int mode,
Resources.Theme popupTheme) {
super(context, attrs, defStyleAttr);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import android.os.Build;
import android.os.Handler;
import android.support.annotation.NonNull;
import android.support.annotation.RestrictTo;
import android.support.annotation.Size;
import android.support.v4.text.TextUtilsCompat;
import android.support.v4.view.GravityCompat;
Expand Down Expand Up @@ -53,6 +54,8 @@
import java.lang.reflect.Method;
import java.util.Locale;

import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;

/**
* Static library support version of the framework's {@link android.widget.ListPopupWindow}.
* Used to write apps that run on platforms prior to Android L. When running
Expand All @@ -78,6 +81,7 @@ public abstract class AbstractXpListPopupWindow {
private static Method sClipToWindowEnabledMethod;
private static Method sGetMaxAvailableHeightMethod;
private static Method sSetAllowScrollingAnchorParentMethod;
private static Method sSetEpicenterBoundsMethod;

static {
try {
Expand All @@ -103,6 +107,12 @@ public abstract class AbstractXpListPopupWindow {
Log.i(TAG, "Could not find method setAllowScrollingAnchorParent(boolean)"
+ " on PopupWindow. Oh well.");
}
try {
sSetEpicenterBoundsMethod = PopupWindow.class.getDeclaredMethod(
"setEpicenterBounds", Rect.class);
} catch (NoSuchMethodException e) {
Log.i(TAG, "Could not find method setEpicenterBounds(Rect) on PopupWindow. Oh well.");
}
}

private Context mContext;
Expand Down Expand Up @@ -151,6 +161,12 @@ public abstract class AbstractXpListPopupWindow {
private final Rect mTempRect = new Rect();
private final int[] mTempLocation = new int[2];

/**
* Optional anchor-relative bounds to be used as the transition epicenter.
* When {@code null}, the anchor bounds are used as the epicenter.
*/
private Rect mEpicenterBounds;

private boolean mModal;

private int mLayoutDirection;
Expand Down Expand Up @@ -679,6 +695,20 @@ public void setVerticalOffset(int offset) {
mDropDownVerticalOffsetSet = true;
}

/**
* Specifies the anchor-relative bounds of the popup's transition
* epicenter.
*
* @param bounds anchor-relative bounds
*/
public void setEpicenterBounds(Rect bounds) {
mEpicenterBounds = bounds;
}

public Rect getEpicenterBounds() {
return mEpicenterBounds;
}

/**
* Set the gravity of the dropdown list. This is commonly used to
* set gravity to START or END for alignment with the anchor.
Expand Down Expand Up @@ -999,6 +1029,13 @@ public void show() {
// only set this if the dropdown is not always visible
mPopup.setOutsideTouchable(!mForceIgnoreOutsideTouch && !mDropDownAlwaysVisible);
mPopup.setTouchInterceptor(mTouchInterceptor);
if (sSetEpicenterBoundsMethod != null) {
try {
sSetEpicenterBoundsMethod.invoke(mPopup, mEpicenterBounds);
} catch (Exception e) {
Log.e(TAG, "Could not invoke setEpicenterBounds on PopupWindow", e);
}
}
// We handle gravity manually. Just as everything else.
PopupWindowCompat.showAsDropDown(mPopup, getAnchorView(), horizontalOffset, verticalOffset, Gravity.NO_GRAVITY);
mDropDownList.setSelection(ListView.INVALID_POSITION);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import android.content.Context;
import android.content.DialogInterface;
import android.content.res.TypedArray;
import android.graphics.Rect;
import android.support.annotation.IntDef;
import android.support.annotation.Nullable;
import android.support.v4.view.GravityCompat;
Expand Down Expand Up @@ -215,6 +216,14 @@ private boolean showAsPopup(final boolean force) {
popup.setHorizontalOffset(preferredHorizontalOffset);
}

final int unit = anchor.getHeight();
if (ViewCompat.getLayoutDirection(this) == ViewCompat.LAYOUT_DIRECTION_RTL) {
int width = anchor.getWidth();
popup.setEpicenterBounds(new Rect(width - unit, 0, width - unit * 2, unit));
} else {
popup.setEpicenterBounds(new Rect(unit, 0, unit * 2, unit));
}

// Testing.
// popup.setDropDownGravity(Gravity.LEFT);
// popup.setMaxWidth(XpListPopupWindow.MATCH_PARENT);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2014 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.
-->

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:gravity="left|center_vertical"
android:left="2dp">
<selector>
<item android:state_enabled="false">
<nine-patch
android:alpha="?android:disabledAlpha"
android:src="@drawable/abc_spinner_mtrl_am_alpha"
android:tint="?colorControlNormal"/>
</item>
<item
android:state_focused="false"
android:state_pressed="false">
<nine-patch
android:src="@drawable/abc_spinner_mtrl_am_alpha"
android:tint="?colorControlNormal"/>
</item>
<item>
<nine-patch
android:src="@drawable/abc_spinner_mtrl_am_alpha"
android:tint="?colorControlActivated"/>
</item>
</selector>
</item>
</layer-list>
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2014 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.
-->

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:gravity="right|center_vertical"
android:right="2dp">
<selector>
<item android:state_enabled="false">
<nine-patch
android:alpha="?android:disabledAlpha"
android:src="@drawable/abc_spinner_mtrl_am_alpha"
android:tint="?colorControlNormal"/>
</item>
<item
android:state_focused="false"
android:state_pressed="false">
<nine-patch
android:src="@drawable/abc_spinner_mtrl_am_alpha"
android:tint="?colorControlNormal"/>
</item>
<item>
<nine-patch
android:src="@drawable/abc_spinner_mtrl_am_alpha"
android:tint="?colorControlActivated"/>
</item>
</selector>
</item>
</layer-list>
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2015 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.
-->

<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="?colorControlHighlight"
android:radius="20dp" />
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2014 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.
-->

<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
android:paddingEnd="32dp"
android:paddingLeft="0dp"
android:paddingMode="stack"
android:paddingRight="0dp"
android:paddingStart="0dp">
<item
android:width="24dp"
android:drawable="@drawable/asp_control_background_40dp_material"
android:gravity="end|fill_vertical"/>

<item
android:end="2dp"
android:gravity="end|center_vertical">
<nine-patch
android:src="@drawable/abc_spinner_mtrl_am_alpha"
android:tint="?colorControlNormal"/>
</item>
</layer-list>
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2014 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.
-->

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/abc_edit_text_material" />
<item android:drawable="@drawable/asp_spinner_background_material" />
</layer-list>
5 changes: 5 additions & 0 deletions support-spinner/src/main/res/values-v21/styles.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,9 @@
<resources>
<style name="Animation.Asp.Popup" parent="Animation.Material.Popup"/>

<style name="Base.Widget.Material.Spinner.Underlined" parent="@style/Widget.AppCompat.Spinner.Underlined">
<item name="android:background">@drawable/asp_spinner_textfield_background_material</item>
<item name="android:paddingEnd">36dp</item>
</style>

</resources>
6 changes: 6 additions & 0 deletions support-spinner/src/main/res/values-v23/styles.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Base.Widget.Material.Spinner.Underlined" parent="@style/Widget.AppCompat.Spinner.Underlined">
<item name="android:background">@drawable/asp_spinner_textfield_background_material</item>
</style>
</resources>
Loading

0 comments on commit 503641d

Please sign in to comment.