How to allow Spinner elements to appear underneath when pressed and full width, for example, in the G + application

background

Google plus has a spinner-like look that shows a lot of elements, but they all appear below:

enter image description here

I need to imitate this in my own counter (this is what I was told), but recently in Material-Design recommendations it says ( here ) that Spinner should put its elements on top of itself, as well as what the support library supports for it.

Problem

I cannot find a way to return this behavior. I tried to change Spinner's style, and also searched about it on the Internet (and here).

Questions

  • How can I let the counter have its elements lower (or higher, if necessary), as was done before Material Design, but like G +, so that they occupy the entire width?

  • Is G + Spinner a special kind? Does he have a name? Is it mentioned anywhere in the guidelines? Maybe something that I can use instead of the usual counter?

+6
source share
1 answer

OK, Spinner's decision on how to put elements underneath is to simply add this:

<Spinner ... android:overlapAnchor="false" /> 

It seems to work even on Kitkat, and not just Lollipop, so I guess it should work on previous versions as well.

However, I still would like to know how this works on G +, and if there are tutorials / examples for what I see there.

I do not know, for example, how to make a window not look like a window.

I tried this:

 android:dropDownWidth="match_parent" android:popupBackground="#FFffffff" android:popupElevation="0px" 

but this does not help, since the correct area is not covered by the counter elements.

I also tried using a TextView that looks like a spinner, and create PopupMenu for it, but I still have the same problems:

 PopupMenu popupMenu = new PopupMenu(getActivity(), v, Gravity.NO_GRAVITY, R.attr.popupMenuStyle, R.style.PopupMenuFullWidthStyle); <style name="PopupMenuFullWidthStyle" parent="@style/Widget.AppCompat.PopupMenu"> <!--<item name="android:dropDownWidth">match_parent</item>--> <item name="android:popupBackground">#FFFFFFFF</item> </style> 

He does nothing using styles.


Complete solution

Since it’s quite difficult to configure PopupMenu as I was instructed, I made a complete solution for it. Here are some of its parts:

This will cause the spinner to pop up (and actually act as a spinner):

 <com.example.user.myapplication.FullSizeFakeSpinner android:id="@+id/spinner" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@drawable/spinner_selector" android:gravity="start|center_vertical" android:minHeight="44dp" android:paddingLeft="8dp" android:paddingRight="8dp" android:text="Fake Spinner" tools:ignore="UnusedAttribute"/> 

MainActivity.java private static final String [] ITEMS = {"Item 0", "Item 1"};

 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); FullSizeFakeSpinner spinner = (FullSizeFakeSpinner) findViewById(R.id.spinner); spinner.setItems(ITEMS); } 

FullSizeFakeSpinner

 public class FullSizeFakeSpinner extends TextView { private String[] mItems; private int mSelectedItemPosition = -1; private PopupWindow mPopupWindow; private boolean mInitialized = false; private OnItemClickListener mOnItemSelectedListener; public interface OnItemClickListener { void onItemClick(FullSizeFakeSpinner parent, View clickedView, int position, String item); void onNothingSelected(FullSizeFakeSpinner parent); } public FullSizeFakeSpinner(final Context context) { super(context); init(context); } public FullSizeFakeSpinner(final Context context, final AttributeSet attrs) { super(context, attrs); init(context); } public FullSizeFakeSpinner(final Context context, final AttributeSet attrs, final int defStyleAttr) { super(context, attrs, defStyleAttr); init(context); } @Override public Parcelable onSaveInstanceState() { Parcelable superState = super.onSaveInstanceState(); SavedState ss = new SavedState(superState); ss.mSelectedItemPosition = this.mSelectedItemPosition; ss.mItems = mItems; return ss; } @Override public void onRestoreInstanceState(Parcelable state) { if (!(state instanceof SavedState)) { super.onRestoreInstanceState(state); return; } SavedState ss = (SavedState) state; super.onRestoreInstanceState(ss.getSuperState()); setItems(ss.mItems); setSelectedItemPosition(ss.mSelectedItemPosition); } public String[] getItems() { return mItems; } public void setItems(final String[] items) { mItems = items; if (mItems != null && mSelectedItemPosition >= 0 && mSelectedItemPosition < mItems.length) setText(mItems[mSelectedItemPosition]); } public int getSelectedItemPosition() { return mSelectedItemPosition; } public void setSelectedItemPosition(final int selectedItemPosition) { mSelectedItemPosition = selectedItemPosition; if (mItems != null && mSelectedItemPosition >= 0 && mSelectedItemPosition < mItems.length) setText(mItems[mSelectedItemPosition]); } public void setOnItemSelectedListener(OnItemClickListener onItemSelectedListener) { mOnItemSelectedListener = onItemSelectedListener; } @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); if (mPopupWindow != null) mPopupWindow.dismiss(); } protected void init(final Context context) { if (mInitialized) return; mInitialized = true; setSaveEnabled(true); setOnClickListener(new OnClickListener() { @Override public void onClick(final View v) { if (mItems == null) return; LayoutInflater layoutInflater = LayoutInflater.from(context); final View popupView = layoutInflater.inflate(R.layout.spinner_drop_down_popup, null, false); final LinearLayout linearLayout = (LinearLayout) popupView.findViewById(android.R.id.list); linearLayout.setOrientation(LinearLayout.VERTICAL); mPopupWindow = new PopupWindow(popupView, LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); mPopupWindow.setOutsideTouchable(true); mPopupWindow.setTouchable(true); mPopupWindow.setBackgroundDrawable(new ColorDrawable(0)); mPopupWindow.setFocusable(true); final AtomicBoolean isItemSelected = new AtomicBoolean(false); for (int i = 0; i < mItems.length; ++i) { final String item = mItems[i]; final int position = i; View itemView = layoutInflater.inflate(android.R.layout.simple_list_item_1, linearLayout, false); itemView.setBackgroundResource(R.drawable.listview_white_selector); itemView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)); ((TextView) itemView.findViewById(android.R.id.text1)).setText(item); linearLayout.addView(itemView, linearLayout.getChildCount() - 1); itemView.setOnClickListener(new OnClickListener() { @Override public void onClick(final View v) { isItemSelected.set(true); mPopupWindow.dismiss(); mSelectedItemPosition = position; setText(item); if (mOnItemSelectedListener != null) mOnItemSelectedListener.onItemClick(FullSizeFakeSpinner.this, v, position, item); } }); } popupView.findViewById(android.R.id.empty).setOnClickListener(new OnClickListener() { @Override public void onClick(final View v) { mPopupWindow.dismiss(); } }); mPopupWindow.setOnDismissListener(new OnDismissListener() { @Override public void onDismiss() { setViewBackgroundWithoutResettingPadding(FullSizeFakeSpinner.this, R.drawable.spinner_selector); if (!isItemSelected.get() && mOnItemSelectedListener != null) mOnItemSelectedListener.onNothingSelected(FullSizeFakeSpinner.this); } }); // optional: set animation style. look here for more info: http://stackoverflow.com/q/9648797/878126 mPopupWindow.showAsDropDown(v, 0, 0); setViewBackgroundWithoutResettingPadding(FullSizeFakeSpinner.this, R.drawable.spinner_opened_selector); } }); } public static void setViewBackgroundWithoutResettingPadding(final View v, final int backgroundResId) { final int paddingBottom = v.getPaddingBottom(), paddingLeft = v.getPaddingLeft(); final int paddingRight = v.getPaddingRight(), paddingTop = v.getPaddingTop(); v.setBackgroundResource(backgroundResId); v.setPadding(paddingLeft, paddingTop, paddingRight, paddingBottom); } ////////////////////////////////////// //SavedState// ////////////// static class SavedState extends BaseSavedState { private String[] mItems; private int mSelectedItemPosition = -1; SavedState(Parcelable superState) { super(superState); } private SavedState(Parcel in) { super(in); this.mItems = in.createStringArray(); mSelectedItemPosition = in.readInt(); } @Override public void writeToParcel(Parcel out, int flags) { super.writeToParcel(out, flags); out.writeStringArray(mItems); out.writeInt(mSelectedItemPosition); } //required field that makes Parcelables from a Parcel public static final Parcelable.Creator<SavedState> CREATOR = new Parcelable.Creator<SavedState>() { public SavedState createFromParcel(Parcel in) { return new SavedState(in); } public SavedState[] newArray(int size) { return new SavedState[size]; } }; } } 

As for the code, but there are some resources available:

There should be a β€œshaped" image file similar to "abc_spinner_mtrl_am_alpha" in the support library and has the color that you want to use. You don’t know how to use the hue for it on pre-Lollipop, so it’s better to just create a file using the color you use.

colors:

 <color name="listview_pressed">#FFE2E2E2</color> <color name="listview_focused">#FF7dbcd3</color> <color name="listview_checked">#FFededed</color> 

listview_white_selector.xml :

 <?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_pressed="true"><shape> <solid android:color="@color/listview_pressed" /> </shape></item> <item android:state_focused="true"><shape> <solid android:color="@color/listview_focused" /> </shape></item> <item android:state_checked="true"><shape> <solid android:color="@color/listview_checked" /> </shape></item> <item android:state_selected="true"><shape> <solid android:color="@color/listview_checked" /> </shape></item> <item android:drawable="@android:color/white"/> </selector> 

listview_white_selector.xml v21:

 <?xml version="1.0" encoding="utf-8"?> <ripple xmlns:android="http://schemas.android.com/apk/res/android" android:color="@color/listview_pressed"> <item android:id="@android:id/mask"> <color android:id="@android:id/mask" android:color="@color/listview_pressed"/> </item> <item android:drawable="@drawable/listview_ripple_white_background_selector"/> </ripple> 

spinner_selector.xml

 <?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_pressed="true"> <shape> <solid android:color="@color/listview_pressed"/> </shape> </item> <item android:state_focused="true"> <shape> <solid android:color="@color/listview_focused"/> </shape> </item> <item android:state_checked="true"> <shape> <solid android:color="@color/listview_checked"/> </shape> </item> <item android:state_selected="true"> <shape> <solid android:color="@color/listview_checked"/> </shape> </item> <item android:drawable="@android:color/transparent"/> </selector> </item> <item android:drawable="@drawable/spinner"/> </layer-list> 

spinner_selector.xml (v21)

 <?xml version="1.0" encoding="utf-8"?> <ripple xmlns:android="http://schemas.android.com/apk/res/android" android:color="@color/listview_pressed"> <item android:drawable="@drawable/spinner"/> <item android:id="@android:id/mask"> <color android:id="@android:id/mask" android:color="@color/listview_pressed"/> </item> <item android:drawable="@drawable/listview_ripple_background_selector"/> </ripple> 

listview_ripple_white_background_selector

 <?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_checked="true"><shape> <solid android:color="@color/listview_checked" /> </shape></item> <item android:state_selected="true"><shape> <solid android:color="@color/listview_checked" /> </shape></item> <item android:drawable="@android:color/white"/> </selector> 

listview_ripple_background_selector

 <?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_checked="true"><shape> <solid android:color="@color/listview_checked" /> </shape></item> <item android:state_selected="true"><shape> <solid android:color="@color/listview_checked" /> </shape></item> <item android:drawable="@android:color/transparent"/> </selector> 

spinner_drop_down_popup

 <ScrollView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:fillViewport="true"> <LinearLayout android:id="@android:id/list" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:orientation="vertical"> <View android:id="@android:id/empty" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#33000000"/> </LinearLayout> </ScrollView> 
+20
source

All Articles