web-dev-qa-db-fra.com

Android ListView emplacement de défilement actuel Y pixels

J'essaie de détecter le défilement d'un affichage de liste au-delà d'un certain seuil en pixels (au milieu du premier élément) Malheureusement, getScrollY () de listview semble toujours renvoyer 0 instad de la position de défilement. Existe-t-il un moyen d'obtenir l'emplacement de défilement réel par pixel?

Voici le code que j'ai essayé d'utiliser mais comme dit, il ne retourne que 0.

getListView().setOnScrollListener(new AbsListView.OnScrollListener() {
    public void onScroll(AbsListView view, int firstVisibleItem,
                         int visibleItemCount, int totalItemCount) {
        Log.d("scroll", "scroll: " + getListView().getScrollY());
    }

    public void onScrollStateChanged(AbsListView view, int scrollState) {
        if (scrollState == 0)
        Log.d("scroll", "scrolling stopped");
    }
});
29
Juhani

Il n'y a aucune notion de défilement Y pour un ListView dans Android simplement parce que la hauteur totale du contenu est inconnue. Seule la hauteur du contenu affiché est connue.

Cependant, il est possible d'obtenir la position actuelle/défilement Y d'un élément visible en utilisant le hack suivant:

getListView().getChildAt(0).getTop();
51
Cyril Mottier

Peut-être que ce sera utile pour quelqu'un. Le code des réponses précédentes ne fonctionnera pas si la liste défile rapidement. Parce que dans ce cas, firstVisiblePosition peut être modifié irrégulièrement. Dans mon code, je n'utilise pas de tableau pour stocker des positions

fun setOnTouchScrollListener(lv: AbsListView, onTouchScrollListener: (isDown: Boolean, offset: Int?, isScrollWorking: Boolean) -> Unit) {

    var lastItemPosition: Int = -1
    var lastItemTop: Int? = null
    var lastItemHeight: Int? = null
    var lastScrollState: Int? = AbsListView.OnScrollListener.SCROLL_STATE_IDLE

    lv.setOnScrollListener(object : AbsListView.OnScrollListener {

        override fun onScroll(view: AbsListView, firstVisibleItem: Int, visibleItemCount: Int, totalItemCount: Int) {
            val child = lv.getChildAt(0)
            var offset: Int? = null
            var isDown: Boolean? = if (firstVisibleItem == lastItemPosition || lastItemPosition == -1) null else firstVisibleItem > lastItemPosition
            val dividerHeight = if (lv is ListView) lv.dividerHeight else 0
            val columnCount = if (lv is GridView) lv.numColumns else 1

            if (child != null) {
                if (lastItemPosition != -1) {
                    when (firstVisibleItem - lastItemPosition) {
                        0 -> {
                            isDown = if (lastItemTop == child.top) null else lastItemTop!! > child.top
                            offset = Math.abs(lastItemTop!! - child.top)
                        }
                        columnCount -> offset = lastItemHeight!! + lastItemTop!! - child.top + dividerHeight
                        -columnCount -> offset = child.height + child.top - lastItemTop!! + dividerHeight
                    }
                }

                lastItemPosition = firstVisibleItem
                lastItemHeight = child.height
                lastItemTop = child.top

                if (isDown != null && (offset == null || offset != 0)
                        && lastScrollState != AbsListView.OnScrollListener.SCROLL_STATE_IDLE) {
                    onTouchScrollListener(isDown, offset, true)
                }
            }
        }

        override fun onScrollStateChanged(view: AbsListView, scrollState: Int) {
            lastScrollState = scrollState
            if (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_IDLE) {
                onTouchScrollListener(true, 0, false)
                lastItemPosition = -1
                lastItemHeight = null
                lastItemTop = null
            }
        }
    })
}

Ensuite, nous pouvons utiliser quand une liste est défilée au-delà du seuil

private var lastThresholdOffset = 0
private var thresholdHeight = some value

setOnTouchScrollListener(listView) { isDown: Boolean, offset: Int?, isScrollWorking: Boolean ->
    val offset = offset ?: if (isDown) 0 else thresholdHeight
    lastThresholdOffset = if (isDown) Math.min(thresholdHeight, lastThresholdOffset + offset)
    else Math.max(0, lastThresholdOffset - offset)

    val result = lastThresholdOffset > thresholdHeight
}

isScrollWorking - peut être utilisé pour une animation

0
Andrey Tuzov

Un code de refactor de la réponse de Malachiasz. Cette fonction est utilisée pour la hauteur de ligne dynamique.

Appeler l'auditeur onScroll

mListView.setOnScrollListener(new AbsListView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(AbsListView view, int scrollState) {

            }

            @Override
            public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
                if (mCardsListView.getChildCount() > 0) {
                    int scrollY = getScrollY();
                }
            }
        });

fonction getScrollY

private Dictionary<Integer, Integer> mListViewItemHeights = new Hashtable<Integer, Integer>(); 
private int getScrollY() {
        View child = mCardsListView.getChildAt(0); //this is the first visible row
        if (child == null) return 0;

        int scrollY = -child.getTop();

        mListViewItemHeights.put(mCardsListView.getFirstVisiblePosition(), child.getHeight());

        for (int i = 0; i < mCardsListView.getFirstVisiblePosition(); ++i) {
            Integer hei = mListViewItemHeights.get(i);

            //Manual add hei each row into scrollY
            if (hei != null)
                scrollY += hei;
        }

        return scrollY;
    }
0
Tai Le Anh

Vous pouvez essayer d'implémenter OnTouchListener et remplacer sa onTouch(View v, MotionEvent event) et obtenir x et y en utilisant event.getX() et event.getY(). Je venais de créer une démo à balayer sur la ligne ListView qui activera un bouton de suppression permettant de supprimer un élément particulier de ListView. Vous pouvez vérifier le code source de mon github en tant que ListItemSwipe .

0
Lalit Poptani