如何设置微调器下拉列表的最大长度?

时间:2014-01-29 08:45:24

标签: android height spinner

我有一个微调器,它在打开时会遮挡旋转器下面的一些文本。我需要通过java代码或XML来限制微调器的最大下拉长度,这样它就不会模糊这个文本。

当前设计是左侧示例,而所需设计位于右侧。 explanation

如何限制旋转器在打开时下降到多远?目前,它下降到填满它下面的整个屏幕部分。

4 个答案:

答案 0 :(得分:9)

实现此目的的一种方法是使用ActionBarSherlock的IcsSpinner。我进行了必要的修改以限制微调器的大小,这看起来效果很好。

对IcsListPopupWindow进行以下修改。

添加实例变量:

private int mDropDownVerticalOffsetBottom;

添加一个方法来设置此变量:

public void setVerticalOffsetBottom(int offsetBottom) {
    mDropDownVerticalOffsetBottom = offsetBottom;
}

将对getMaxAvailableHeight的调用更改为(添加了mDropDownVerticalOffsetBottom):

final int maxHeight = /*mPopup.*/getMaxAvailableHeight(
        mDropDownAnchorView, mDropDownVerticalOffset, mDropDownVerticalOffsetBottom, ignoreBottomDecorations);

更改方法的签名以包含该变量:

private int getMaxAvailableHeight(View anchor, int yOffset, int yOffsetBottom, boolean ignoreBottomDecorations) {

在计算到底部的距离时考虑偏移:

final int distanceToBottom = bottomEdge - (anchorPos[1] + anchor.getHeight()) - yOffset - yOffsetBottom;

现在修改IcsSpinner.java以实现偏移的setter方法:

private DropdownPopup mPopup;   // <- needs to be a DropdownPopup instead of a SpinnerPopup

public void setVerticalOffsetBottom(int offsetBottom) {
    mPopup.setVerticalOffsetBottom(offsetBottom);
}

现在,您需要做的就是将偏移设置为正确的值。这是我如何做到的(我测试了它并且它在两个测试设备上工作):

final View root = findViewById(R.id.root_layout);
final View view = findViewById(R.id.view_not_to_be_obscured);
root.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
    public void onGlobalLayout() {
        root.getViewTreeObserver().removeGlobalOnLayoutListener(this);
        int[] locations = new int[2];
        root.getLocationOnScreen(locations);
        int y1 = locations[1];
        int h1 = root.getHeight();
        view.getLocationOnScreen(locations);
        int y2 = locations[1];
        int offset = y1 + h1 - y2;
        // here we initialize the spinner
    }
});

假设root_layout填充整个窗口,不包括所有装饰元素。

最后一步是创建微调器:

    // actionDropDownStyle is an attribute set in the theme to e.g. @style/Widget.Sherlock.Spinner.DropDown.ActionBar or @style/Widget.Sherlock.Light.Spinner.DropDown.ActionBar for light theme
    IcsSpinner spinner = new IcsSpinner(context, null, R.attr.actionDropDownStyle);

    // yes here we set the offset!
    spinner.setVerticalOffsetBottom(offset);

    spinner.setPadding(spinner.getPaddingLeft(), 0, spinner.getPaddingRight(), 0);
    spinner.setId(R.id.some_id);
    spinner.setAdapter(yourAdapter); // you can use a simple ArrayAdapter or whatever you need

    // create ICS LinearLayout
    LayoutInflater inflater = (LayoutInflater) context.getSystemService( Context.LAYOUT_INFLATER_SERVICE );
    IcsLinearLayout linearLayout = (IcsLinearLayout) inflater.inflate(R.layout.abs__action_bar_tab_bar_view, null);
    linearLayout .setPadding(listNavLayout.getPaddingLeft(), 0, listNavLayout.getPaddingRight(), 0);
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
    params.gravity = Gravity.CENTER;
    linearLayout .addView(spinner, params);

现在看起来可能看起来很复杂,但正如其他人提到的那样,如果没有自己的微调器实现,你将无法实现这一点,因为ActionBarSherlock附带一个,为什么不使用它?写作自己的工作肯定少了。如果你不使用ActionBar的库去除你不需要的所有资源文件,并使用Proguard去除所有未使用的类。 您可以使用AppCompat实现相同的目标(请参阅此处:https://github.com/android/platform_frameworks_support/tree/master/v7/appcompat/src/android/support)。

答案 1 :(得分:3)

我已经搜索了很多,似乎无法在任何地方找到解决方案。您可能必须通过重新创建微调器的功能来使用稍微不同的路径,但是使用按钮和对话框。

假设您正在使用ArrayAdapter作为微调器,请尝试以下操作:

使用带有向下箭头图标的按钮替换您的微调器。

创建自定义DialogAlertDialog并使用ListView填充ArrayAdapter。 对于onClick方法,请按下所选选项的值,并使用所选值填充static变量和按钮文本。这样,您可以将对话框的大小设置为您想要的任何大小,并且多余的选项将始终可滚动。

我知道这并不理想,但我还没有找到任何方法来改变&#34;下拉&#34;旋转器的一部分。

对不起,如果这不是你所希望的。

编辑:之前有人问过同样的问题,事实证明他们采用了我刚才描述的确切方法。您可以在此处查看他们使用的示例代码:Check out the question/code

答案 2 :(得分:0)

您可以使用relfection。

 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...
} 

但是,如果您使用的是androidx.appCompat 1.1.0,则必须使用->

I can't use API reflection on androidx.appcompat:appcompat:1.1.0

致谢

答案 3 :(得分:-3)

我认为您必须使用自定义微调器来满足您的需求。没有任何内置方法或xml属性可以提供帮助。

请参阅此示例以获取帮助。

https://github.com/ankitthakkar/DropDownSpinner

希望这会奏效。

注意:这是更改后的答案。