Uzun ScrollView düzeninin en üstüne nasıl geçilir?


162

Uygulamamın bir kısmı için kullanıcıya bir ad listesi sunulur ve uygun gördükleri şekilde gruplandırmaları istenir.

(Not, ListView kodu Android Views öğreticisinden kelimesi kelimesine kopyalandı. Henüz ihtiyaçlarıma göre özelleştirmedim, sadece bu işi nasıl yapacağımı anlamaya çalışıyorum.)

Temel düzen, RelativeLayout içeren bir ScrollView (aşağıdaki kodda "groupsScrollView" olarak adlandırılır) içeren bir LinearLayout'tur. Bazı düğmeler ve metin ve sonra adları listesini görüntüleyen bunun altında benim ListView var. Tüm bunlar görünür ekran alanından daha uzundur, bu nedenle kullanıcının hepsini görmek için dikey olarak kaydırılmasına izin verilir.

Sayfa yüklendiğinde her zaman sayfanın ortasındaki ListView sayfamın üstüne önceden kaydırılmış olduğu sürece, bunların hepsi güzel çalışır. Oluşturduğum metin ve düğmeler kullanıcıya ne yapacağını söyleyemez.

Ekranı alıp yukarı kaydırabilirim, bu iyi çalışır, ancak ekranın zaten yukarı kaydırılmış olarak yüklenmesini istiyorum. Kullanıcının yeni yüklenen bir sayfanın üst kısmını görmek için YUKARI kaydırması gerekmez. Ancak programlı olarak ekranın üst kısmına kaydırmaya çalıştığım her şey başarısız oldu.

İşte benim onCreate yöntemi:

protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    setContentView(R.layout.groups);

    mainScrollView = (ScrollView)findViewById(R.id.groupsScrollView);

    //get the Bundle out of the Intent...
    Bundle extras = getIntent().getExtras();
    mNames = extras.getStringArray("mNames");

    setListAdapter(new ArrayAdapter<String>(this, R.layout.list_item, mNames));

    ListView lv = getListView();
    lv.setTextFilterEnabled(true);

    //This is the line I'm having issues with
    mainScrollView.pageScroll(View.FOCUS_UP);

    lv.setOnItemClickListener(new OnItemClickListener() {
        public void onItemClick(AdapterView<?> parent, View view,
            int position, long id) {
          // When clicked, show a toast with the TextView text
          Toast.makeText(getApplicationContext(), ((TextView) view).getText(),
              Toast.LENGTH_SHORT).show();
        }
      });
}

"MainScrollView.pageScroll (View.FOCUS_UP) satırı; sorun. Hataya neden olmaz, ancak hiçbir şey yapmıyor gibi görünüyor. ScrollTo (0,0), scrollDirection (View.FOCUS_UP) ) ve aklıma gelen her şeyi.

Bir hata alamadım çünkü bu kaydırma komutlarının gerçekten çalıştığını, ancak bunları içeren ScrollView veya RelativeLayout'un yerine, ListView'in en üstüne kaydırdıklarını varsaymak zorundayım. Bu, Google'ın kendi "scrollTo (int x, int y)) yöntemi ile" Bu sürüm aynı zamanda kaydırmayı çocuğumuzun sınırlarına kenetliyor "derler.

Daha uzun bir soru daha da uzun yapmak için, bir ScrollView içinde bulunan ekrana bir grup görünümü nasıl yükleyebilirim ve daha sonra kullanıcının etkileşime girebilmesi için programın tamamını sayfanın üstüne kaydırırım?

Teşekkürler!

Yanıtlar:


264

Deneyin

mainScrollView.fullScroll(ScrollView.FOCUS_UP);

İşe yaramalı.


Benim için de çalışıyor. : D
Muntasir Aonik

1
ScrollView # fullScroll () geçerli odağı değiştirdiğini buldum. EditText ile test ettim.
illusionJJ

175

Aynı sorun, muhtemelen bir tür hata vardı.

Hatta fullScroll(ScrollView.FOCUS_UP)diğer cevabını çalışmadı. Diyalog gösterildikten hemen sonra
benim için işe yarayan şey çağırıyordu scroll_view.smoothScrollTo(0,0).


Bu başlangıçta işe yaradı, ancak daha sonra tekrar tekrar yapmaya çalıştığımda, bu yaklaşım tatmin edici bir sonuç vermedi.
JaydeepW

16
i scroll_view.smoothScrollTo (0,0) 'dan çözersek, listview yanımızda fullScroll (ScrollView.FOCUS_UP) çalışmaz.
Kirtikumar A.

1
scroll_view.smoothScrollTo (0,0) benim için mainScrollView.fullScroll (ScrollView.FOCUS_UP) 'dan daha iyi çalıştı; TEŞEKKÜRLER!
marienke

2
Çoğu cihazda fullScroll (ScrollView.FOCUS_UP) çalıştı, ancak Nexus 5 ve metin boyutunu açtığım cihazlarda - fullSscroll eylem çubuğunun altına taşındı, smoothScrollTo (0,0) tüm cihazlarda daha iyi çalıştı.
jt-gilkeson

Bunun fullScroll(), seçilen öğeyi taşıma işleminden sonra hala seçili tutması avantajına da sahiptir . İle fullScroll(), kaydırma görünümündeki ilk öğe, her defasında, kaydırma yukarı gitmeden önce seçilen öğeden bağımsız olarak, her seferinde yeniden seçildi.
GeertVc

97

aynı sorunu vardı ve bu düzeltildi. Umarım size yardımcı olur.

listView.setFocusable(false);

3
Bu, ızgara görünümleri için de doğru çözümdür. Aynı görünüm grubunda birden fazla görünüm öğeniz varsa, özellikle listenin veya ızgara görünümünün üstünde başka bir liste görünümü olduğunda olur. Bağdaştırıcı UI iş parçacığını bildirdiği için görünüm yeniden oluşturulur ve ilk öğeye kadar yukarı kaydırılır. ListView.setFocusable (false) / gridView.setFocusable (false) öğesini çağırmanız yeterlidir. Eğer xml dosyasından yaparsanız, yine de çalışmaz.
omersem

Bu çözüm benim durumumda da işe yaradı, NestedScrollView içinde RecyclerView vardı, bu yüzden otomatik aşağı kaydırıyordu. Teşekkürler dostum!
Nilesh Rathore

Adaptör ayarlamadan önce bunu eklemek zorunda kaldı ama bundan sonra bir cazibe gibi çalışıyor. Thanks
Topluluk

mükemmel bir açıklama !!
Borja López

Hem Miguel'e hem de özellikle açıklama için omersem'e, özellikle XML'de ayarlandığında nasıl çalışmayacağına dair bölüme teşekkür ederim, bu bana biraz baş ağrısı kurtardı
buradd

53

scrollViewObject.fullScroll(ScrollView.FOCUS_UP)bu iyi çalışıyor, ancak yalnızca bu satırdaki sorun, scrollViewObject'te veri doldurulduğunda hemen çağrılmasıdır. Veri doldurulana kadar bir kaç milisaniye beklemeniz gerekir. Bu kodu deneyin:

scrollViewObject.postDelayed(new Runnable() {
    @Override
    public void run() {
        scroll.fullScroll(ScrollView.FOCUS_UP);
    }
}, 600);

VEYA

 scrollViewObject.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
        scrollViewObject.getViewTreeObserver().removeOnGlobalLayoutListener(this);
        scrollViewObject.fullScroll(View.FOCUS_UP);
    }
});

Kaydırma görüntüsünün sayfanın altına doğru kaydırılması gerekiyordu, aynı sorunu çözüyordum!
Makine Kabilesi

1
"Sihirli" x sayısını beklemek zorunda kalacağınız milisaniye sayısını tahmin etmek yerine, Görünüm nesneleri, widget kullanıcı arayüzünde oluşturulduktan sonra çalıştırılabilir olanı gönderecek bir yazı (Runnable) yöntemi sunar.
Ryan

@Ryan: post (Runnable) Nexus 5'de (Genymotion) benim için her zaman işe yaramıyor
Dika

post (Runnable) işlevi, görüntüleme ihlali adımından sonra verileri alırsanız, önce yukarı kaydırma ve ardından da görünümde veriler dolduğundan işe yaramayabilir. Bu yüzden ya veri doldurma işlemlerinden sonra postDelayed (Runnable, dummyMillis) veya scroll.fullScroll (ScrollView.FOCUS_UP) kullanmalısınız.
oguzhan

Statik milis verdiğiniz ilk çözümünüz kötü bir yaklaşımdır.
Malwinder Singh

35

Tüm bu geçerli çözümlerin ana problemi, henüz ekranda çizilmediğinde ekranı yukarı kaydırmaya çalışmanızdır.

Kaydırma görünümü ekranda görünene kadar beklemeniz ve ardından bu çözümlerden herhangi biriyle yukarı taşımanız gerekir. Bu, bir gecikme süresinden daha iyi bir çözümdür, çünkü gecikmeyi önemsemezsiniz.

    // Wait until my scrollView is ready
    scrollView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            // Ready, move up
            scrollView.fullScroll(View.FOCUS_UP);
        }
    });

7
Güzel çözüm - onGlobalLayoutÇağrı yönteminin sonunda Global Listener'ı kaldırmayı unutmayınscrollView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
Nilhcem

30

Çok kolay

    ScrollView scroll = (ScrollView) findViewById(R.id.addresses_scroll);
    scroll.setFocusableInTouchMode(true);
    scroll.setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS);

3
benim için işe yaramadı (3. satır), çözüm şuydu: scroll.fullScroll (View.FOCUS_UP); (ilk 2 satırınız dahil)
medskill

@medskill, Merhaba, bunları xml dosyanıza yazdınız mı? Bunun sadece işe yaradığını düşünüyorum onCreate().
tanınmayan

@ imknownJ.Kimu Benim için xml dosyasında çalışıyor
Paglian

Bu benim için çalıştı. Hem ikinci hem de üçüncü satıra ihtiyacınız var. Benim için XML'de işe yaramaz.
ET

2
Eğer yapabilseydim seni öpebilirdim Bunun için 1-2 saat geçirdim. En iyisi, iki liste görünümünün yüklenmesini beklerken onlara odaklanmak istemedi. OnResume () öğesine ekledi.
John T

24

İ vaka olduğunu gör Flipper veya Dialog içindeki scrollview kullanıyorum zaman aynı sorunu karşılaştığı scrollViewObject.fullScroll(ScrollView.FOCUS_UP)bu durumda bu nedenle döner sahte scrollViewObject.smoothScrollTo(0, 0)benim için çalıştı edilir

Scroll Focus Üst


19
 final ScrollView scrollview = (ScrollView)findViewById(R.id.selected_place_layout_scrollview);

         scrollview.post(new Runnable() { 
                public void run() { 
                    scrollview.scrollTo(0, 0); 
                } 
            }); 

9
runOnUiThread( new Runnable(){
   @Override
   public void run(){
      mainScrollView.fullScroll(ScrollView.FOCUS_UP);
   }
}

9

Bu benim için çalıştı

scroll_view.smoothScrollTo(0,0); // scroll to top of screen

6

Bu için kuvvet kaydırma olduğunu Scrollview :

            scrollView.post(new Runnable() {
                @Override
                public void run() {
                    scrollView.scrollTo(0, 0);
                    scrollView.pageScroll(View.FOCUS_UP);
                    scrollView.smoothScrollTo(0,0);
                }
            });

4
scrollView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
        // Ready, move up
        scrollView.fullScroll(View.FOCUS_UP);
    }
});

1

Kotlin'deki sorunumu şöyle düzelttim:

scrollview.isFocusableInTouchMode = true
scrollview.fullScroll(View.FOCUS_UP)
scrollview.smoothScrollTo(0,0)

0
@SuppressWarnings({ "deprecation", "unchecked" })
public void swipeTopToBottom(AppiumDriver<MobileElement> driver) 
                    throws InterruptedException {
       Dimension dimensions = driver.manage().window().getSize();
        Double screenHeightStart = dimensions.getHeight() * 0.30;
        int scrollStart = screenHeightStart.intValue();
        System.out.println("s="+scrollStart);
        Double screenHeightEnd = dimensions.getHeight()*0.90;
        int scrollEnd = screenHeightEnd.intValue();
        driver.swipe(0,scrollStart,0,scrollEnd,2000);
        CommonUtils.threadWait(driver, 3000);
    }

Bu kesin çalışacak,
Ajeet Gour

Lütfen bu cevabın sorunu nasıl çözdüğüne dair kısa bir açıklama yapın.
Ayberk Özgür
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.