Android ScrollView пачынаецца не зверху, а ў пачатку GridView

У мяне ёсць праблема з ScrollView, які мае ўнутры яго персаналізаванай GridView і іншай лсом Тыпу ў моры я ўпершыню пачаць актыўнасць, ScrollView пачынае ў сваёй верхняй частцы, але калі я прыязджаю ў іншыя дзеяннях раз ScrollView пачынаецца ў пачатку з GridView.I выкарыстаў клас ExpandableHeightGridView знайсці ў гэтай спасылцы для майго GridView. Код xml для макета дзейнасці гэта адзін:





    

        

        

            

            
        
    

    

        

        

        

        
        

    


Я паспрабаваў з дапамогай кода scrollView.fullScroll (ScrollView.FOCUS_UP); , але гэта не work.And нават з scrollView.scrollTo (0, 0); I не мелі поспеху. Адзіны код, які працаваў было:

    scrollView.post(new Runnable() 
      { 
         public void run() { 
             scrollViewLuogo.fullScroll(ScrollView.FOCUS_UP); 
         } 
      });

але гэта робіць хуткую анімацыю з верхняй частцы GridView ў верхняй частцы экрана, і я не люблю яго.

Любое прапанову ??

47

10 адказы

рашэнне:

Добра шкада, калі гэта позні адказ, але я наткнуўся на тое ж пытанне (толькі што я з дапамогай ListView замест гэтага) і з невялікім колькасцю спроб і памылак <�моцных> Я знайшоў рашэнне гэта:

У асноўным праблема заключаецца ў тым, што GridView/ListView дзіця аўтаматычна запытвае бацькоўскі фокус (Scrollview), калі вы «ўзламаць» і змяніць памер яго ўтрыманне з ExpandableHeightGridView , што адбываецца пасля таго, як макет аказваецца, і, такім чынам, вы бачыце што анімацыя пры спробе пракруціць яго з scrollTo() (адбываецца пасля стварэння макета і пАСЛЯ GridView змяняецца такім чынам любы агульны зваротны выклік бескарысна звяртацца з гэтым праграмным шляхам).

Такім чынам, самае простае рашэнне, якое я знайшоў, было проста адключыць фокусируемых ўласцівасць на ListView/GridView з:

listView.setFocusable(false);

Такім чынам, калі вы спачатку увядзіце актыўнасць, фокус па змаўчанні, а не спадзявацца на Listview/GridView.

І ўсё працуе нармальна =)

147
дададзена
Гэта таксама працуе для RecyclerView
дададзена аўтар ymerdrengene, крыніца
захаваць мой дзень! Танкі вельмі шмат
дададзена аўтар Radesh, крыніца
Працы для WebView занадта
дададзена аўтар sagus_helgy, крыніца
Таксама цікава, чаму ён не працуе ў XML. Паводзіны па змаўчанні даволі дзіўна, навошта каму-небудзь што ??
дададзена аўтар greatergoodguy, крыніца
Дзіўны выправіць, дзякуй. Мне было цікава, чаму ён не працуе, калі я ўсталяваць яго ў XML.
дададзена аўтар Emanuel, крыніца
Гэта варта ўлічваць, што правільны адказ
дададзена аўтар FabioR, крыніца

Самы просты спосаб дадаць на бацьку ScrollView наступныя атрыбуты XML:

android:descendantFocusability="beforeDescendants"
android:focusableInTouchMode="true"

Гэта азначае, што ScrollView ў цэлым будзе толькі адзін здабывае фокус, а не які-небудзь унутраны кантэйнер, калі вы запускаеце дзейнасць. Гэта таксама карысна, напрыклад, калі ў вас ёсць рэдагаваць тэкст у макеце, і вы не хочаце, каб засяродзіцца адразу і ўсплыве клавіятуры пры ўваходзе ў экран (гэта той жа прынцып).

Такім чынам, ваш ScrollView на верхняй частцы макета будзе выглядаць наступным чынам:


19
дададзена
Звярніце ўвагу, што <�б> ScrollView патрэбен тыя атрыбуты, толькі калі ён з'яўляецца прамым продкам іншы пракруткі віджэту. У адваротным выпадку проста атрымаць з бацькоў і паставіць тыя ж атрыбуты. У мяне была <�б> LinearLayout у якасці непасрэднага з бацькоў і гэты твор раствора, як пажадана.
дададзена аўтар mimoralea, крыніца
У мяне ёсць ExpandableListView ўнутры ScrollView і ваш падыход працуе толькі на Android 8 (Sony G8441), але не на Android 5 (Huawei Honor 7), Android 6 (Samsung Galaxy J5), Android 7 (Huawei P9 Lite).
дададзена аўтар soshial, крыніца
не працуе для мяне, у мяне ёсць recyclerview ўнутры Scrollview
дададзена аўтар Kai Wang, крыніца
RecyclerView ўяўляе сабой асаблівы выпадак, гэтак жа як ListView. У агульным выпадку , які змяшчае ад 2 пракручваю кантэйнерах адзін ўнутры адзін аднаго (ListView або RecyclerView ўнутры ScrollView) уяўляе сабой гняздо праблем і пытанняў, якія прыводзяць да не проста. Калі ў вас ёсць EditText, ўнутры RecyclerView, ўнутры ScrollView, усё становіцца вельмі брыдка, і простае рашэнне (Нашчадак фокусируемости) не можа лёгка прымяняцца, у прыватнасці, з-за таго, як скролінг кантэйнеры самі рэалізаваныя.
дададзена аўтар Disruption, крыніца

ScrollView

android:fitsSystemWindows="false"
3
дададзена

Калі вы хочаце, каб пракруціць яго уверх/ніз у праграме, вы можаце гэта зрабіць (гэта з тут ):

Для фокусу ўніз:

((ScrollView) findViewById(R.id.scrollView)).post(new Runnable() { 
    public void run() { 
        ((ScrollView) findViewById(R.id.scrollView)).fullScroll(View.FOCUS_DOWN); 
    } 
});

Для Фокусу да пачатку

((ScrollView) findViewById(R.id.scrollView)).post(new Runnable() { 
    public void run() { 
        ((ScrollView) findViewById(R.id.scrollView)).fullScroll(View.FOCUS_UP); 
    } 
});
3
дададзена

На жаль, прыклад вы вынікалі вельмі бедны. ListViews і GridViews ніколі не павінны быць змешчаны ў ScrollViews.

Мэта Scrollview з'яўляецца даць бясконцую вышыню яго пункт гледжання дзіцяці. Спіс/прызначэнне GridView з'яўляецца прыняць патэнцыйна вельмі вялікі набор дадзеных, і толькі генераваць дастатковую колькасць уяўленняў элементаў, каб запоўніць прастору, прадастаўлены ёй у той час, для павышэння эфектыўнасці. Абодва здольныя пракрутка іх зместу без іншых.

Ўвод спіс/GridView ў ScrollView кажа, «неадольная сіла, сустракаецца нерухомы аб'ект.» Альбо вы перамаглі кропку List/GridView ці вы перамаглі кропку ScrollView, камбінуючы іх.

Палепшаныя спосабы ўключаюць у сябе іншыя матэрыялы ў межах адной і той жа пракруткай вобласці ўключаюць у сябе з дапамогай уяўленняў верхняга/ніжняга калантытула з ListView ці іншым чынам канкатэнацыі змесціва спісу адаптараў ў адзіны адаптар. Стварэнне элементаў ListView, якія ўтрымліваюць некалькі элементаў на радок, каб сфармаваць сетку для часткі кантэнту закрепительного з'яўляецца простым.

2
дададзена
У гэтым практыкаванні карыстальнік можа дадаць колькі TextViews (для інфармацыі, каментароў і г.д.) і imageviews (яго ўласныя фатаграфіі) ён wants.I хоча ўвесь выгляд будзе пракручваць і dinamicity з GridView ідэальна падыходзіць для кіравання малюнкамі, так мне падабаецца гэтае рашэнне.
дададзена аўтар user2328149, крыніца

Проста дадайце гэты радок кода ў Дзіцё ScrollView

android:focusableInTouchMode="true"
2
дададзена

Проста дадайце дзве радкоў у вашым бацькоўскай макеце

АНДРОІД: фокусируемый = "ісціна" АНДРОІД: focusableInTouchMode = "ісціна"

Паспрабуйце гэта, спадзяюся, ён будзе працаваць для вас

2
дададзена

У наступным Поделюсь боль, а таксама. У маім дадатку ў мяне ёсць RecyclerView ўнутры NestedScrollView ўнутры CoordinatorLayout :


  

     .......

     

            

  

Вядома, пры адкрыцці дзейнасці, старонка пракручваецца ўключыць recyclerView ў сярэдзіне. Ні адзін з вышэйпералічаных адказаў працаваў, так што я прыдумаў наступнае рашэнне:

@Override
protected void onCreate( Bundle savedInstanceState ) {
  ....
  content.setOnScrollChangeListener( new NestedScrollView.OnScrollChangeListener() {
    @Override
    public void onScrollChange( NestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY ) {
      Rect scrollBounds = new Rect();
      v.getHitRect( scrollBounds );
      if( header.getLocalVisibleRect( scrollBounds ) ){
        if( View.VISIBLE != recyclerView.getVisibility() ){
          recyclerView.setVisibility( View.VISIBLE );
          fillRecyclerViewSomehow();
        }
      }
    }
  }
}

@Override
protected void onResume() {
  ...
  recyclerView.setVisibility( View.GONE );//this effectively suppresses the focusability
}

НТН

0
дададзена

Просты спосаб для дасягнення гэтай мэты з'яўляецца стварэнне ідэнтыфікатара для вашага ScrollView ў xml ... скажам,

scrollView_main

Пасля гэтага вам проста трэба пайсці ў файл Java і аб'явіць яго як звычайную зменную вышэй працэдуры OnCreate быць глабальным, як гэта

ScrollView scrollView_main;

ОК, цяпер настаў час, каб перайсці да OnCreate працэдуры і заявіць пра гэта, каб атрымаць злучэнне з ID з файла XML

scrollView_main = (ScrollView)findViewById(R.id.scrollView_main);

і, нарэшце, код, які будзе рабіць трук для вашага ScrollView пракручваецца на вяршыні, гэта ваш адказ

scrollView_main.smoothScrollTo(0,0); //set it on top
0
дададзена

Я знайшоў спосаб, каб даць <�моцны> GridView фіксаваны памер <�моцны> ўнутры ScrollView і <�моцны> даюць магчымасць пракруткі гэта. Гэта дазваляе бачыць усю Scrollview без пракруткі ўсіх элементаў GridView, і гэта мае сэнс для мяне, што з дапамогай ExpandableHeightGridView .

Каб зрабіць гэта, вы павінны рэалізаваць новы клас, які пашырае GridView і перавызначыць onTouchEvent() для выкліку requestDisallowInterceptTouchEvent (ісціна) . Такім чынам, бацькоўскі выгляд пакіне сетку перахопліваць падзея дотыку.

GridViewScrollable.java:

package com.example;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.GridView;

public class GridViewScrollable extends GridView {

    public GridViewAdjuntos(Context context) {
        super(context);
    }

    public GridViewAdjuntos(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public GridViewAdjuntos(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev){
       //Called when a child does not want this parent and its ancestors to intercept touch events.
        requestDisallowInterceptTouchEvent(true);
        return super.onTouchEvent(ev);
    }
}

Дадайце яго ў макеце з характарыстыкамі і палёў, якія вы хочаце, ўнутры ScrollView:



    


І проста атрымаць яго ў вашай дзейнасці:

GridViewScrollable myGridView = (GridViewScrollable) findViewById(R.id.myGVS);

Я спадзяюся, што гэта дапамагае =)

0
дададзена