如何在 Android 中限制 Spinner 下拉视图的高度

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20597584/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 03:07:42  来源:igfitidea点击:

How to limit the height of Spinner drop down view in Android

androidandroid-layoutandroid-spinner

提问by Tushar Pandey

Please suggest any approach which i use to create it .

请建议我用来创建它的任何方法。

Query: I am creating 2-Spinner view , where i have to add Country/Cities list , So like if i am selecting india then i am getting 50 items inside the drop down view , problem with this is that it is taking the whole page in height .

查询:我正在创建 2-Spinner 视图,我必须在其中添加国家/城市列表,所以如果我选择印度然后我在下拉视图中得到 50 个项目,问题在于它占用了整个页面在高度。

What i want: I want to create a drop down view , where user can see only 10 items in the drop down view , other items will be shown whenever user will scrollthe drop down view .

我想要什么:我想创建一个下拉视图,用户只能在下拉视图中看到 10 个项目,只要用户滚动下拉视图,就会显示其他项目。



My problem

我的问题

回答by shlee1

You can use Reflection.

您可以使用反射。

    Spinner spinner = (Spinner) findViewById(R.id.spinner);
    try {
        Field popup = Spinner.class.getDeclaredField("mPopup");
        popup.setAccessible(true);

        // Get private mPopup member variable and try cast to ListPopupWindow
        android.widget.ListPopupWindow popupWindow = (android.widget.ListPopupWindow) popup.get(spinner);

        // Set popupWindow height to 500px
        popupWindow.setHeight(500);
    }
    catch (NoClassDefFoundError | ClassCastException | NoSuchFieldException | IllegalAccessException e) {
        // silently fail...
    }

回答by Almighty

You can also affect drop down view location and size by subclassing Spinnerand overriding its getWindowVisibleDisplayFrame(Rect outRect)which is used by android.widget.PopupWindowfor calculations. Just set outRectto limit the area where drop down view can be displayed.

您也可以通过影响继承下拉视图的位置和大小Spinner,并覆盖其getWindowVisibleDisplayFrame(Rect outRect)被使用android.widget.PopupWindow的计算。只需设置outRect限制可以显示下拉视图的区域。

This approach is of course not suitable for all scenarios since sometimes you want to place drop down view so it doesn't obscure another view or by some other condition known only "outside the instance".

这种方法当然不适用于所有场景,因为有时您想要放置下拉视图,这样它就不会遮挡另一个视图或其他一些仅在“实例之外”已知的条件。

In my case, I needed to apply FLAG_LAYOUT_NO_LIMITSflag to my activity window which caused the outRectto be huge and therefore part of the drop down view got sometimes hidden behind navigation bar. In order to restore original behavior I used the following override:

就我而言,我需要将FLAG_LAYOUT_NO_LIMITS标志应用到我的活动窗口,这导致它outRect变得很大,因此下拉视图的一部分有时隐藏在导航栏后面。为了恢复原始行为,我使用了以下覆盖:

@Override
public void getWindowVisibleDisplayFrame(Rect outRect) {
    WindowManager wm = (WindowManager) getContext.getSystemService(Context.WINDOW_SERVICE);
    Display d = wm.getDefaultDisplay();
    d.getRectSize(outRect);
    outRect.set(outRect.left, <STATUS BAR HEIGHT>, outRect.right, outRect.bottom);
}

回答by Tushar Pandey

for that i have created my own , PopUpWindow as suggested by @theLittleNaruto , in the comment section .

为此,我在评论部分按照@theLittleNaruto 的建议创建了自己的 PopUpWindow。

main.xml

主文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:orientation="vertical" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content"> 

    <Button 
        android:layout_marginTop="80dp"
        android:id="@+id/btn"
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content"
        android:text="Country"
        android:layout_gravity="center_vertical|center_horizontal"/>
</LinearLayout>

popup_example.xml

popup_example.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:padding="10dip" >

    <ListView 
        android:id="@+id/lstview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        />

</LinearLayout>

showpopup_1.java

showpopup_1.java

package com.example.spinnerworking;

import android.app.Activity;
import android.content.Context;
import android.graphics.Color;
import android.os.Bundle;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.ListView;
import android.widget.PopupWindow;
import android.widget.TextView;
import android.widget.PopupWindow.OnDismissListener;
import android.widget.Toast;

public class showpopup_1 extends Activity {

    boolean click = true ;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);

        setContentView(R.layout.main);
        final LayoutInflater inflater = (LayoutInflater) this
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        final Button b = (Button) findViewById(R.id.btn);
        final View pview = inflater.inflate(R.layout.popup_example,
                (ViewGroup) findViewById(R.layout.main));
        final PopupWindow pw = new PopupWindow(pview);
        Log.i("hello", "hello") ;

        b.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                if (click) {
                    // if onclick written here, it gives null pointer exception.
                    // if onclick is written here it gives runtime exception.
                    pw.showAtLocation(v, Gravity.CENTER_HORIZONTAL, 0, 0);
                    pw.update(8, 0, 150, 200);
                    String[] array = new String[] { "tushar", "pandey",
                            "almora" };

                    ListView lst = (ListView) pview.findViewById(R.id.lstview);
                    adapterHello adapter = new adapterHello(showpopup_1.this);
                    lst.setAdapter(adapter);
                    lst.setOnItemClickListener(new OnItemClickListener() {
                        @Override
                        public void onItemClick(AdapterView<?> arg0, View arg1,
                                int arg2, long arg3) {
                            Toast.makeText(showpopup_1.this, "pandey",
                                    Toast.LENGTH_SHORT).show();
                        }

                    });
                    click = false ;
                }
                else
                {
                    pw.dismiss();
                    click = true;
                }

            }
        });
    }
}

class adapterHello extends BaseAdapter {
    String array[] = new String[] { "tushar", "pandey", "almora", "hello",
            "tushar", "pandey", "almora", "hello", "tushar", "pandey",
            "almora", "hello" };

    showpopup_1 context;

    public adapterHello(showpopup_1 context) {
        this.context = context;
    }

    public int getCount() {
        // TODO Auto-generated method stub
        return array.length;
    }

    @Override
    public Object getItem(int arg0) {
        // TODO Auto-generated method stub
        return arg0;
    }

    @Override
    public long getItemId(int position) {
        // TODO Auto-generated method stub
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        // TODO Auto-generated method stub
        TextView text = new TextView(context);
        text.setHeight(30);
        text.setPadding(10, 8, 0, 0);
        text.setTextColor(Color.BLACK);
        text.setText(array[position]);
        text.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                Log.i("clicked", "tushar");
            }
        });
        return text;
    }

}

回答by Shimi Uhlman

  1. add android:popupBackground="#00000000"to the Spinner
  2. in the Adapter
  1. 添加 android:popupBackground="#00000000"到微调器
  2. 在适配器中

getDropDownView();
parentParams = new FrameLayout.LayoutParams(LayoutParams.WRAP_CONTENT, (int) Utils.convertDpToPx(350));
parentParams.gravity = Gravity.BOTTOM;
parent.setLayoutParams(parentParams);
  1. you can move the popup by adding android:dropDownVerticalOffset="60dp"
  1. 您可以通过添加移动弹出窗口 android:dropDownVerticalOffset="60dp"

回答by Mahmoud Ayman

You can use this awesome library MaterialSpinnerthat will do all the hard work for you.

您可以使用这个很棒的库MaterialSpinner,它将为您完成所有艰苦的工作。

Download:implementation 'com.jaredrummler:material-spinner:1.3.1'

下载:implementation 'com.jaredrummler:material-spinner:1.3.1'

fileName.xml:

文件名.xml:

<com.jaredrummler.materialspinner.MaterialSpinner
android:id="@+id/spinner"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:ms_dropdown_max_height="400dp"/>

set height using app:ms_dropdown_max_height="400dp"

使用设置高度 app:ms_dropdown_max_height="400dp"

回答by F.Mysir

As of 2020 I would go with: Exposed Dropdown Menusand use under AutoCompleteTextView

截至 2020 年,我将采用:Exposed Dropdown Menus并在以下情况下使用AutoCompleteTextView

android:dropDownHeight="300dp"

If you don't know what is this all about start exploring: Menu-Display& Menu-Documentation

如果您不知道这是什么,请开始探索:菜单-显示菜单-文档