Как установить максимальную длину для раскрывающегося списка прядильщика?

У меня есть прядильщик, который в настоящее время закрывает какой-то текст под вращателем при открытии. Мне нужно ограничить максимальную выпадающую длину счетчика, либо через java-код, либо через XML, чтобы он не скрывал этот текст.

Текущий дизайн - это левый пример, а желаемый дизайн - справа. explanation

Как я могу ограничить, как далеко падает счетчик при открытии? В настоящее время он падает, чтобы заполнить всю часть экрана ниже.

Ответы

Ответ 1

Один из способов добиться этого - использовать 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);

Теперь это может выглядеть сложным, но, как упоминалось выше, вы не сможете достичь этого без своей собственной реализации spinner, и поскольку ActionBarSherlock поставляется с одним, почему бы не использовать его? Это, безусловно, меньше, чем написание собственного. Если вы не используете библиотеку для панели ActionBar для удаления всех файлов ресурсов, которые вам не нужны, и используйте Proguard для удаления всех неиспользуемых классов. Вероятно, вы могли бы достичь того же, используя AppCompat (см. Здесь https://github.com/android/platform_frameworks_support/tree/master/v7/appcompat/src/android/support).

Ответ 2

Я искал совсем немного, и кажется, что я нигде не могу найти решение. Возможно, вам придется пойти немного иначе, воссоздав функциональность счетчика, но используя кнопки и диалоги.

Предполагая, что вы используете ArrayAdapter для счетчика, попробуйте следующее:

Замените Spinner клавишей со стрелкой вниз.

Создайте пользовательский Dialog или AlertDialog и заполните ListView с помощью ArrayAdapter. Для метода onClick нажмите значение выбранного параметра и заполните переменную static и текст кнопки с выбранным значением. Таким образом, вы можете сделать размер диалогового окна любым размером, который вы хотите, и избыточный выбор всегда будет прокручиваться.

Я знаю, что это не идеально, но я не нашел способа изменить высоту "выпадающего" фрагмента счетчика.

Извините, если это не то, на что вы надеялись.

РЕДАКТИРОВАТЬ: кто-то еще задал один и тот же вопрос здесь раньше, и выясняется, что они пошли с точным методом, который я только что описал. Вы можете увидеть пример кода, который они использовали здесь: Проверить вопрос/код

Ответ 3

Размер набора Spinner имеет android: layout_width = "wrap_content" определяется его содержимым. Если вы хотите, чтобы все вещи были эллипсированными, это зависит от вас в вашем SpinnerAdapter, когда вы создаете свою строку Views.

Или, жестко проведите андроид: layout_width, размер которого ограничен.

Или вместо использования LinearLayout используйте RelativeLayout и структурируйте свои правила таким образом, чтобы Spinner занимал оставшееся место в строке, привязывая его к левой стороне экрана и к левой стороне первого EditText. Хотя я не на 100% уверен, что происходит, если контент слишком велик - он, вероятно, просто усечен.

Ответ 4

Я думаю, вам нужно использовать собственный счетчик для вашего требования. Нет встроенного метода или свойства xml, которые могут вам помочь.

См. этот пример для справки.

https://github.com/ankitthakkar/DropDownSpinner

Надеюсь, что это сработает.

Примечание: Это измененный ответ.