studio programacion móviles libro fillviewport desarrollo curso aplicaciones android android-scrollview

programacion - scrollview android fillviewport



Creando un ScrollView bloqueado en Android (4)

Estoy intentando implementar un ScrollView en Android que no se desplaza cuando se agrega un elemento por encima de la posición de desplazamiento actual.

La implementación predeterminada de ScrollView comporta de la siguiente manera:

Adición de un elemento por encima de la posición de desplazamiento actual:

Agregar un elemento debajo de la posición de desplazamiento actual:

¿Cómo puedo "bloquear" el ScrollView antes de agregar un elemento por encima de la posición de desplazamiento actual?

Este es mi archivo de diseño, actualmente he anulado tanto ScrollView como LinearLayout , pero todavía no he realizado ninguna modificación.

<LinearLayout android:layout_height="fill_parent" android:orientation="vertical" android:layout_width="fill_parent"> <LinearLayout android:id="@+id/LinearLayout02" android:layout_height="wrap_content" android:layout_width="fill_parent" android:layout_alignParentBottom="true"> <Button android:id="@+id/Button02" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:text="Add To Top" android:onClick="addToStart"> </Button> <Button android:id="@+id/Button03" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:text="Add to End" android:onClick="addToEnd"> </Button> </LinearLayout> <com.poc.scroller.locable.lockablescrollerpoc.LockedScrollView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:fillViewport="true" android:scrollbarAlwaysDrawVerticalTrack="true" android:verticalScrollbarPosition="right" android:fadeScrollbars="false" android:background="@color/scrollColor"> <com.poc.scroller.locable.lockablescrollerpoc.LockedLinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:id="@+id/Container"> </com.poc.scroller.locable.lockablescrollerpoc.LockedLinearLayout> </com.poc.scroller.locable.lockablescrollerpoc.LockedScrollView> </LinearLayout> </android.support.constraint.ConstraintLayout>

Código fuente de ejemplo: https://github.com/Amaros90/android-lockable-scroller-poc

¡Gracias!


Implementar esto funcionó para mí. Puedes ver la aplicación de ejemplo que agregué en la pregunta original.

public class LockableScrollView extends ScrollView { private boolean _enabled = true; public LockableScrollView(Context context, AttributeSet attrs) { super(context, attrs); super.setFillViewport(true); } @Override public void addView(View layout, ViewGroup.LayoutParams params) { super.addView(layout, params); ((ViewGroup)layout).setOnHierarchyChangeListener(new OnHierarchyChangeListener() { @Override public void onChildViewAdded(View layout, View item) { if (_enabled) { item.addOnLayoutChangeListener(new View.OnLayoutChangeListener() { @Override public void onLayoutChange(View item, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { item.removeOnLayoutChangeListener(this); int scrollViewY = ((LockableScrollView)item.getParent().getParent()).getScrollY(); int layoutPosition = ((View)item.getParent()).getTop(); boolean shouldScroll = item.getTop() + layoutPosition <= scrollViewY || item.getBottom() + getTop() <= scrollViewY; if (shouldScroll) { final int childViewHeight = item.getHeight(); ((View)item.getParent()).addOnLayoutChangeListener(new View.OnLayoutChangeListener() { @Override public void onLayoutChange(View layout, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { layout.removeOnLayoutChangeListener(this); LockableScrollView scrollView = ((LockableScrollView)layout.getParent()); scrollView.scrollTo(scrollView.getScrollX(), scrollView.getScrollY() + childViewHeight); } }); } } }); } } @Override public void onChildViewRemoved(View layout, View item) { if (_enabled) { int scrollViewY = ((LockableScrollView)layout.getParent()).getScrollY(); int layoutPosition = layout.getTop(); boolean shouldScroll = item.getTop() + layoutPosition <= scrollViewY || item.getBottom() + getTop() <= scrollViewY; if (shouldScroll) { final int childViewHeight = item.getHeight(); layout.addOnLayoutChangeListener(new View.OnLayoutChangeListener() { @Override public void onLayoutChange(View layout, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { layout.removeOnLayoutChangeListener(this); LockableScrollView scrollView = ((LockableScrollView)layout.getParent()); scrollView.scrollTo(scrollView.getScrollX(), scrollView.getScrollY() - childViewHeight); } }); } } } }); } }


Puede intentar usar RecyclerView e implementar onDataSetChanged() . A continuación, detecte si se presionó add to TOP o add to END botón. Luego use scrollToPositionWithOffset(int, int) para administrar el scroll.

Por ejemplo:

//Scroll item 3 to 20 pixels from the top linearLayoutManager.scrollToPositionWithOffset(3, 20);

Para restaurar la posición de desplazamiento de un RecyclerView , esta es la forma de guardar las posiciones de desplazamiento (los dos argumentos para el método scrollToPositionWithOffset(int, int) ):

int index = linearLayoutManager.findFirstVisibleItemPosition(); View v = linearLayoutManager.getChildAt(0); int top = (v == null) ? 0 : (v.getTop() - linearLayoutManager.getPaddingTop())


Puede obtener fácilmente el comportamiento opuesto utilizando addOnLayoutChangeListener de su LinearLayout y reinicie LinearLayout ScrollView . Aquí está la implementación en su ScrollViewActivity.onCreate

protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.scrollview); _linearLayout = (LockedLinearLayout)findViewById(R.id.Container); _scrollView = (LockedScrollView)findViewById(R.id.ScrollView); _layoutInflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE); _linearLayout.addOnLayoutChangeListener(new View.OnLayoutChangeListener() { @Override public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { _scrollView.scrollTo(0, _scrollView.getScrollY() + (bottom - oldBottom )); } }); addExampleImage(10, _linearLayout); }

Luego, puede marcar fácilmente la función addToEnd o verificar dónde se agregó el niño para evitar cambiar de desplazamiento cuando se agrega algún niño en la parte inferior.


Puedes hacerlo fácilmente solo tienes que conseguirlo ..

En primer lugar, en el evento onclick, almacene el valor int utilizando getFirstVisiblePosition ()

ejemplo.

en un clic en el botón Agregar elemento haga esto ---

int currentpos = recycleview.getFirstVisiblePosition ();

ahora después de insertar elment a list / recyclerview ---

recyclerview.scrolltoposition (currentpos);

eso es intentarlo si quieres hacerlo sin error ...

Buena suerte :)