Подтвердить что ты не робот

Как установить размер и расположение в onSizeChanged?

Я не могу получить мои элементы, например ListView, чтобы правильно изменить размер.

У меня есть ListActivity для поиска, с панели мониторинга, редактирования и списка. Идея состоит в том, чтобы скрыть панель действий, пока отображается клавиатура.

Я расширил LinearLayout, чтобы прослушать изменения размера вида (как рекомендовано здесь):

public class SizeChangingLinearLayout extends LinearLayout {
    //...
    @Override
    protected void onSizeChanged(int xNew, int yNew, int xOld, int yOld)
    {        
        View actionbar = mainView.findViewById(R.id.actionbar);

        if (yNew > yOld) 
            actionbar.setVisibility(View.VISIBLE);
        else if (yNew < yOld) 
            actionbar.setVisibility(View.GONE);

        super.onSizeChanged(xNew, yNew, xOld, yOld);

    }
}

Скрытие/показ панели действий работает как ожидалось, но есть пробел ниже ListView той же высоты, что и скрытая панель действий. Как только любое изменение графики (например, запись в поле редактирования), ListView заполняет пробел. Аналогичное поведение появляется в обратном порядке, скрывая клавиатуру.

enter image description here

[изменить]

Аналогичная проблема возникает и при изменении другого макета. Изменение Visibility объектов в onSizeChanged отображается напрямую, но изменение размеров и полей не показывается, пока какое-либо другое действие пользователя не перерисовывает эти представления. Недействительность не работает из onSizeChanged.

[/Edit]

Я попытался обновить графику:

  • invalidate - как пользовательский LinearLayout и ListView (as рекомендуется здесь)
  • notifyDataSetChanged в списке адаптер
  • forceLayout

... и многое другое, без успеха. Почему ListView не изменяет размер вначале? Должен ли я переопределить onLayout в моем расширенном LinearLayout? Что я пропустил?

4b9b3361

Ответ 2

Это может быть длинный снимок...

Вы пытались играть с настройкой android:layout_height="" для ListView?

Возможно использование match_parent или wrap_content может заставить его работать...

Как я уже сказал... длинный выстрел!

Ответ 3

Вы можете принудительно перерисовать ListView, изменив его высоту на 1px и вызывая

requestLayout()

Ответ 4

Возможно сделать то, что вы хотите, зарегистрировав setOnFocusChangeListener и setOnClickListener на EditText.

Существует множество различных сценариев, которые следует учитывать, когда речь заходит о навигации, и что-то может потребоваться изменить для работы с определенным макетом.

В любом случае, начните с переопределения onSizeChanged, чтобы показать скрытый элемент, когда нажата кнопка "Назад".

public class MyLinearLayout extends LinearLayout {

    private MyListActivity mMyListActivity;

    public MyLinearLayout(Context context) {
        super(context);
    }

    public MyLinearLayout(Context context, AttributeSet attrs) {
        super(context, attrs);      
    }

    public void setMyListActivity(MyListActivity mla) {
        mMyListActivity = mla;
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        // show the element when we get more room       
        if (h > oldh) {
            if (mMyListActivity != null) {
                mMyListActivity.showBar();
            }
        }
        super.onSizeChanged(w, h, oldw, oldh);
    }
}

В ListActivity мы захватываем MyLinearLayout и передаем ему this. Затем устанавливается setOnFocusChangeListener, чтобы обрабатывать вещи, когда изменяется фокус EditText. SetOnClickListener используется, чтобы скрыть элемент, когда EditText уже имеет фокус.

public class MyListActivity extends ListActivity {

    private ArrayList<MyData> mDataList = new ArrayList<MyData>();

    private MyLinearLayout mMyLinearLayout; 
    private LinearLayout mHideMeLinearLayout;
    private EditText mEditText;

    public void showBar() {
        if (mHideMeLinearLayout != null) {
            mHideMeLinearLayout.setVisibility(View.VISIBLE);
        }
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        // Get MyLinearLayout and pass this to it.
        mMyLinearLayout = (MyLinearLayout) findViewById(R.id.myLinearLayout);
        mMyLinearLayout.setMyListActivity(this);

        // the LinearLayout to be hidden
        mHideMeLinearLayout = (LinearLayout) findViewById(R.id.LinearLayoutToHide);

        mEditText = (EditText) findViewById(R.id.editText);     
        mEditText.setOnFocusChangeListener(new OnFocusChangeListener() {
            @Override
            public void onFocusChange(View v, boolean hasFocus) {
                InputMethodManager imm = (InputMethodManager) getSystemService(Service.INPUT_METHOD_SERVICE);
                if (hasFocus) {
                    imm.showSoftInput(mEditText, 0);
                    mHideMeLinearLayout.setVisibility(View.GONE);
                } else {
                    imm.hideSoftInputFromWindow(mMyLinearLayout.getWindowToken(), 0);
                    mHideMeLinearLayout.setVisibility(View.VISIBLE);
                }
            }
        });
        mEditText.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                mHideMeLinearLayout.setVisibility(View.GONE);
            }
        });

        .....
    }

    .....
}

Я приведу рабочий пример позже, но теперь должен бежать.