How to change the position of opened spinner?

前端 未结 3 1067
既然无缘
既然无缘 2021-01-02 05:01

I would like the spinner dropdown to open right below the spinner itself. E.g.:

\"enter

相关标签:
3条回答
  • 2021-01-02 05:54

    You have to extend Spinner and change the location of AlertDialog (spinner when clicked acts as alertDialog).

    Code (does a bit more than just position, it also sets background for opened spinner):

    public class CustomSpinner extends Spinner {
    
    private AlertDialog mPopup;
    
    public CustomSpinner(Context context) {
        super(context);
    }
    
    public CustomSpinner(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    
    public CustomSpinner(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }
    
    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
    }
    
    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
    
        if (mPopup != null && mPopup.isShowing()) {
            mPopup.dismiss();
            mPopup = null;
        }
    }
    
    
    //when clicked alertDialog is made
    @Override
    public boolean performClick() {
        Context context = getContext();
    
        AlertDialog.Builder builder = new AlertDialog.Builder(context);
        CharSequence prompt = getPrompt();
        if (prompt != null) {
            builder.setTitle(prompt);
        }
    
    
    
        mPopup = builder.setSingleChoiceItems(
                new DropDownAdapter(getAdapter()),
                getSelectedItemPosition(), this).show();
    
        WindowManager.LayoutParams WMLP = mPopup.getWindow().getAttributes();
    
                //width and height must be set to anything other than WRAP_CONTENT!
        WMLP.x = 0; // x position
        WMLP.y = 50; // y position
        WMLP.height =390 ; //LayoutParams.WRAP_CONTEN
        WMLP.width = 315;
        WMLP.horizontalMargin = 0; 
        WMLP.verticalMargin = 0;
    
        mPopup.getWindow().setAttributes(WMLP);
    
    
    
        //ListView.getDefaultSize(size, measureSpec)
        ListView listView = mPopup.getListView();
        //listView.set
        // Remove divider between rows
        listView.setDivider(null);
    
        // Set custom background
        listView.setBackgroundResource(R.drawable.drop);
    
        // Remove background from all (grand)parent's
        ViewParent parent = listView.getParent();
        while (parent != null && parent instanceof View) {
            ((View) parent).setBackgroundDrawable(null);
    
            parent = parent.getParent();
        }
    
        return true;
    }
    
    @Override
    public void onClick(DialogInterface dialog, int which) {
        setSelection(which);
        dialog.dismiss();
        mPopup = null;
    }
    
    
     * <p>Wrapper class for an Adapter. Transforms the embedded Adapter instance
     * into a ListAdapter.</p>
     */
    private static class DropDownAdapter implements ListAdapter, SpinnerAdapter {
        private SpinnerAdapter mAdapter;
    
        /**
         * <p>Creates a new ListAddapter wrapper for the specified adapter.</p>
         *
         * @param adapter the Adapter to transform into a ListAdapter
         */
        public DropDownAdapter(SpinnerAdapter adapter) {
            this.mAdapter = adapter;
        }
    
        public int getCount() {
            return mAdapter == null ? 0 : mAdapter.getCount();
        }
    
        public Object getItem(int position) {
            return mAdapter == null ? null : mAdapter.getItem(position);
        }
    
        public long getItemId(int position) {
            return mAdapter == null ? -1 : mAdapter.getItemId(position);
        }
    
        public View getView(int position, View convertView, ViewGroup parent) {
            return getDropDownView(position, convertView, parent);
        }
    
        public View getDropDownView(int position, View convertView, ViewGroup parent) {
            return mAdapter == null ? null :
                    mAdapter.getDropDownView(position, convertView, parent);
        }
    
        public boolean hasStableIds() {
            return mAdapter != null && mAdapter.hasStableIds();
        }
    
        public void registerDataSetObserver(DataSetObserver observer) {
            if (mAdapter != null) {
                mAdapter.registerDataSetObserver(observer);
            }
        }
    
        public void unregisterDataSetObserver(DataSetObserver observer) {
            if (mAdapter != null) {
                mAdapter.unregisterDataSetObserver(observer);
            }
        }
    
        /**
         * <p>Always returns false.</p>
         *
         * @return false
         */
        public boolean areAllItemsEnabled() {
            return true;
        }
    
        /**
         * <p>Always returns false.</p>
         *
         * @return false
         */
        public boolean isEnabled(int position) {
            return true;
        }
    
        public int getItemViewType(int position) {
            return 0;
        }
    
        public int getViewTypeCount() {
            return 1;
        }
    
        public boolean isEmpty() {
            return getCount() == 0;
        }
    
       }
       }
    

    Then you just gotta insert it to your layout with "yourPackage.CustomSpinner" element like:

    <yourPackage.CustomSpinner 
         android:layout_height="wrap_content"
         android:id="@+id/spinner" 
         android:layout_width="fill_parent">
    </yourPackage.CustomSpinner>
    
    0 讨论(0)
  • 2021-01-02 06:05

    Declare the spinner mode as a dropdown:

    android:spinnerMode="dropdown"
    

    then use the vertical offset to close the gap:

    android:dropDownVerticalOffset="-15dp"
    

    Spinner Android Documentation

    0 讨论(0)
  • 2021-01-02 06:06

    For dropdown Spinner mode you can use this:

    mSortingSpinner.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            mSortingSpinner.setDropDownVerticalOffset(
                    mSortingSpinner.getDropDownVerticalOffset() + mSortingSpinner.getHeight());
            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) {
                mSortingSpinner.getViewTreeObserver().removeOnGlobalLayoutListener(this);
            } else {
                mSortingSpinner.getViewTreeObserver().removeGlobalOnLayoutListener(this);
            }
        }
    });
    

    This set vertical offset of dropdown by spinner height.

    0 讨论(0)
提交回复
热议问题