android - studio - ¿Cómo establecer el tamaño y el diseño en onSizeChanged?
hacer responsive una app en android studio (4)
No puedo hacer que mis elementos, por ejemplo, ListView
, ListView
de tamaño correctamente.
ListActivity
una ListActivity
para buscar, con un panel, una caja de edición y una vista de lista. La idea es ocultar la barra de acciones mientras se muestra el teclado.
LinearLayout
, para escuchar los cambios de tamaño de vista (como se recomienda here ):
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);
}
}
La ocultación / visualización de la barra de acciones funciona como se esperaba, pero hay un espacio debajo del ListView
de la misma altura que la barra de acciones oculta. Tan pronto como los gráficos cambian (por ejemplo, escribir en la caja de edición) el ListView
llena el espacio. Un comportamiento similar aparece al revés, cuando se oculta el teclado.
[Editar]
El mismo problema también aparece al cambiar otro diseño. Cambiar la Visibility
de las cosas en onSizeChanged
muestra directamente, pero cambiar los tamaños y los márgenes no se muestra hasta que otras acciones del usuario vuelvan a dibujar esas vistas. La invalidación no funciona desde onSizeChanged
.
[/Editar]
Intenté actualizar los gráficos de la siguiente manera:
-
invalidate
-tanto el LinearLayout personalizado como elListView
(como se recomienda here ) -
notifyDataSetChanged
en el adaptador de la lista -
forceLayout
... y más, sin éxito. ¿Por qué el ListView
no ListView
tamaño al principio? ¿Debo anular onLayout
en mi LinearLayout extendido? ¿Qué me he perdido?
Agregar lo siguiente al final de onSizeChanged()
lo resolverá:
Handler handler = new Handler();
handler.post(new Runnable() {
@Override
public void run() {
requestLayout();
}
});
Consulte la respuesta a esta pregunta: Vistas dentro de un grupo de visualización personalizado que no se procesa después de un cambio de tamaño
Es posible hacer lo que quiera registrando setOnFocusChangeListener
y setOnClickListener
en EditText
.
Hay muchos escenarios diferentes para considerar cuando se trata de navegación y es posible que sea necesario cambiar las cosas para que funcionen con un diseño determinado.
De todos modos, comience anulando onSizeChanged para mostrar el elemento oculto cuando se toca el botón Atrás.
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);
}
}
En ListActivity tomamos MyLinearLayout y le pasamos this
. Luego, se establece un setOnFocusChangeListener para manejar cosas cuando el foco de EditText cambia. El setOnClickListener se usa para ocultar el elemento cuando EditText ya tiene foco.
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);
}
});
.....
}
.....
}
Proporcionaré un ejemplo de trabajo más adelante, pero tengo que ejecutar ahora.
Esto podría ser una posibilidad remota ...
¿Has intentado jugar con la android:layout_height=""
para ListView
?
Quizás usar match_parent
o wrap_content
podría forzarlo a funcionar ...
Como dije ... ¡un tiro largo!
Puede obligar a ListView a volver a dibujar cambiando su altura en 1px y llamando
requestLayout()