2012-06-11 12 views
6

Mam ViewPager i GridView, aby wyświetlić kalendarz miesięczny. Model GridView ma około 30 elementów, a przesunięcie w lewo i prawo jest bardzo wolne. Zrobiłem przykładowy projekt do przetestowania bez dostępu do bazy danych i jest on powolny. Może ktoś widzi problem lub muszę wykonać asynchroniczne ładowanie stron? Jest to układ dla jednego elementu w GridView. Chcę pokazać 9 małych ikon 5x5 pikseli w dowolnym elemencie, ale bez nich też jest wolny.Dlaczego ViewPager i GridLayout z 30 elementami są bardzo wolne?

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/Layout1" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" android:padding="1dp"> 
    <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content"> 
    <TextView android:id="@+id/date" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_marginLeft="5dp" android:gravity="center_vertical" android:textSize="14sp" android:textStyle="bold"/> 
    </LinearLayout> 
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#ffffff"> 
    <ImageView android:id="@+id/dot1" android:layout_width="wrap_content" android:drawingCacheQuality="auto" android:layout_height="wrap_content" android:layout_marginLeft="5dp" android:background="#ffffff" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:paddingBottom="1dp" android:paddingLeft="1dp" android:paddingTop="5dp"/> 
    </RelativeLayout> 
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#ffffff"> 
    <ImageView android:id="@+id/dot2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="5dp" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:background="#ffffff" android:paddingBottom="1dp" android:paddingLeft="1dp"/> 
    </RelativeLayout> 
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#ffffff"> 
    <ImageView android:id="@+id/dot3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="5dp" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:layout_gravity="right" android:background="#ffffff" android:paddingBottom="1dp" android:paddingLeft="1dp"/> 
    </RelativeLayout> 
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#ffffff"> 
    <ImageView android:id="@+id/dot4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="5dp" android:layout_gravity="center_horizontal" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:background="#ffffff" android:paddingBottom="1dp" android:paddingLeft="1dp"/> 
    </RelativeLayout> 
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#ffffff"> 
    <ImageView android:id="@+id/dot5" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="5dp" android:layout_gravity="left" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:background="#ffffff" android:paddingBottom="1dp" android:paddingLeft="1dp"/> 
    </RelativeLayout> 
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#ffffff"> 
    <ImageView android:id="@+id/dot6" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="5dp" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:layout_gravity="left" android:background="#ffffff" android:paddingBottom="1dp" android:paddingLeft="1dp"/> 
    </RelativeLayout> 
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#ffffff"> 
    <ImageView android:id="@+id/dot7" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="5dp" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:layout_gravity="left" android:background="#ffffff" android:paddingBottom="1dp" android:paddingLeft="1dp"/> 
    </RelativeLayout> 
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#ffffff"> 
    <ImageView android:id="@+id/dot8" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="5dp" android:layout_gravity="left" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:background="#ffffff" android:paddingBottom="1dp" android:paddingLeft="1dp"/> 
    </RelativeLayout> 
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#ffffff"> 
    <ImageView android:id="@+id/dot9" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="5dp" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:layout_gravity="left" android:background="#ffffff" android:paddingBottom="5dp" android:paddingLeft="1dp"/> 
    </RelativeLayout> 
</LinearLayout> 

To instantiateItem z GridView adaptera:

public Object instantiateItem(ViewGroup container, int position) { 
    GridView gv = new GridView(m_context); 
    gv.setAdapter(new BaseAdapter() { 
     @Override 
     public View getView(int pos, View convertView, ViewGroup parent) { 
      View v; 
      if (convertView == null) { 
       // if it's not recycled, initialize some attributes 
       v = mInflater.inflate(R.layout.calendar_month_item, null); 
      } else { 
       v = convertView; 
      } 
      TextView dayView = (TextView) v.findViewById(R.id.date); 
      dayView.setText(pos + ""); 
      return v; 
     } 

     @Override 
     public long getItemId(int p) { 
      return 0; 
     } 

     @Override 
     public Object getItem(int p) { 
      return null; 
     } 

     @Override 
     public int getCount() { 
      return 30; 
     } 
    }); 
    gv.setNumColumns(5); 
    ((ViewPager) container).addView(gv); 
    return gv; 
} 
+4

Użyj funkcji Traceview, aby określić, gdzie znajdują się wąskie gardła. – CommonsWare

+0

Zajrzałem do TraceView, ale nie mogę zobaczyć, gdzie jest problem, jego jedyną reprezentację UI. – MOST2K2

+2

Zawijacie Państwo ImageViews wewnątrz RelativeLayouts i TextView wewnątrz LinearLayout: To zupełnie niepotrzebne. Po drugie, masz wiele widoków GridView ... Czy masz wiele Adaptery? nie potrzebujesz wszystkich adapterów. Możesz zarządzać wszystkim w jednym adapterze! Wreszcie, po prostu kontemplując, nie potrzebujesz ViewPagera. Dzięki prostym animacjom możesz to zrobić za pomocą pojedynczego GridView (i za każdym razem jeden reset adaptera). Powodzenia –

Odpowiedz

5

Rozejrzałem się trochę i myślę, że znalazłem dokładnie to, czego szukasz:

+0

Tak, znam ten projekt. ale potrzebuję 9 ikon (i mają włączony/wyłączony stan) w jednym elemencie gridview, więc dodam je programowo w tej chwili. może umieściłem je w układzie i pokazałem potrzebne i ukryłem pozostałe. opublikuję ponownie, jeśli przyspieszy to przeglądanie z gridview. – MOST2K2

+0

Spojrzałem na to jeszcze raz i myślę, że powinieneś trzymać się tego, co powiedziałem wcześniej. Chociaż zamiast wyświetlać wszystkie te ikony w "widoku miesiąca" kalendarza, należy wyświetlić tylko jedną ikonę, jeśli ten dzień zawiera jakiekolwiek ikony. Następnie, po wybraniu dnia w "widoku miesiąca", pojawi się okno dialogowe z tego dnia zawierające wszystkie ikony dodane przez użytkownika do tego dnia. Jest łatwiejszy w czyszczeniu i działa o wiele szybciej. Możesz także użyć SQLite DB do przechowywania wszystkich dni z ikonami i ikonami, które zawierają. Będziesz wtedy miał wiele opcji, takich jak "lista zadań" lub cokolwiek innego. – CommonKnowledge

+0

@ MOST2K2 W tym, co opisałem powyżej, możesz użyć niestandardowego okna dialogowego i będzie on miał swój własny plik xml. – CommonKnowledge

2

Która wersja Androida używacie? Jest to ważne, ponieważ istnieje kalendarz w Androidzie 3.0, ma błędy, ale nie jest tak krytyczny.

O twoim pytaniu, jeśli dobrze to zrozumiałem. Spójrz na swój XML, zawiera 11 układów, a to tylko dla jednego elementu. Jeśli masz ich wiele, wyobraź sobie, ile pracy musi wykonać system Android, aby nadmuchać wszystkie twoje elementy. Następnie, po przesunięciu, możesz ponownie użyć elementów, a Android musi odświeżyć te, które nie są prawidłowe. To dużo pracy. (11 układów * 30 = 330 układów do odświeżenia lub nadmuchania). Jak głosi dokumentacja dla programistów Androida, musisz zawsze używać mniej układów do zawijania swoich elementów, jak to tylko możliwe!

W każdym razie Twoje podejście nie jest poprawne. Mogę zasugerować, aby przyjrzeć się kodowi źródłowemu CalendarView w systemie Android 3+, ale aby dać wskazówkę:

Utwórz układ na tydzień, nie na każdy dzień (jak w widoku kalendarza). W ten sposób Android będzie musiał odświeżyć tylko n elementów (wybierzesz, ile tygodni chcesz wyświetlić w danym momencie), a nie 30. Ten układ musi zawierać 7 widoków każdego dnia.

Mam nadzieję, że masz z tego jakiś pomysł.

+0

Używam Androida 4.0.4 w moim samsung galaxy nexus. ale chcę uruchomić moją aplikację na poziomie aplikacji> 8 (2.2.x), nie używam kalendarza wewnętrznego, jego własnej implementacji. Tak, to prawda, że ​​330 układów to dużo pracy, i to na każdy miesiąc. Mam też perspektywę tygodniową i dzienną. są one bardzo szybkie podczas przesuwania w lewo lub w prawo. Próbuję zmniejszyć układy i mam nadzieję, że uda mi się je uruchomić. może zmieniam się na fragmenty i wykonuję ansynchroniczne ładowanie stron. – MOST2K2

+0

Po co wymyślać, jeśli istnieje już kalendarz? Na przykład musiałem narysować kilka kółek w każdym rzędzie kalendarza na Androida. Pobrałem kod źródłowy tego kalendarza i zmieniłem niektóre linie, i to działa. Nie testowałem go jednak na 2.2, tylko 3+. – XMight

+0

Używam mojego kalendarza do książki klasowej dla nauczycieli, która jest bardzo specyficzna i trwa tylko 1-10 godzin. – MOST2K2

0

Przede wszystkim, układ jest trochę dziwne, jak inni stwierdzili.

  • Naprawdę nie potrzebujesz schematu dla żadnych elementów podrzędnych układu.
  • Posiadanie wielu zagnieżdżonych układów względnych lub liniowych, gdy nie są potrzebne, będzie dość kosztowne, szczególnie gdy są zapakowane w GridView owinięte w ViewPager.

Po drugie, ViewPager i PagerAdapter są trochę trudne.

  • Gdy masz domyślną liczbę stron poza ekranem, wszystkie trzy zostaną ułożone w tym samym czasie. Jeśli ustawisz go wyżej, będziesz układał jeszcze więcej widoków.
  • Upewnij się, że poprawnie usuwasz widoki w destroyItem.
  • Wykonaj poprawną metodę isViewFromObject, ponieważ w przeciwnym razie twoje poglądy zostaną odrzucone na stronie, powodując większy koszt ponownego ich utworzenia.

Korzystanie z porad @ CommonsWare jest prawdopodobnie dobrym pomysłem. TraceView jest nieco trudny w użyciu, ale mimo to prawdopodobnie da pewne wskazówki.

+0

tak to prawda, że ​​nie potrzebuję takich elementów podrzędnych. Nie zmieniam domyślnych stron poza ekranem 3. usunąć i isViewFromObject jest poprawnie zaimplementowany. – MOST2K2

Powiązane problemy