Как установить размер и расположение в 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? Что я пропустил?
Ответы
Ответ 1
Добавление следующего в конце onSizeChanged()
решит его:
Handler handler = new Handler();
handler.post(new Runnable() {
@Override
public void run() {
requestLayout();
}
});
См. ответ на этот вопрос: Представления внутри пользовательской ViewGroup без рендеринга после изменения размера
Ответ 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);
}
});
.....
}
.....
}
Я приведу рабочий пример позже, но теперь должен бежать.